/*
 * CAN generic CAN host connection support
 *
 * Copyright (c) 2013-2014 Jin Yang
 * Copyright (c) 2014-2018 Pavel Pisa
 *
 * Initial development supported by Google GSoC 2013 from RTEMS project slot
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "qemu/osdep.h"
#include "chardev/char.h"
#include "qemu/sockets.h"
#include "qapi/error.h"
#include "qom/object_interfaces.h"
#include "net/can_emu.h"
#include "net/can_host.h"

struct CanBusState {
    Object object;

    QTAILQ_HEAD(, CanBusClientState) clients;
};

static void can_host_disconnect(CanHostState *ch)
{
    CanHostClass *chc = CAN_HOST_GET_CLASS(ch);

    can_bus_remove_client(&ch->bus_client);
    chc->disconnect(ch);
}

static void can_host_connect(CanHostState *ch, Error **errp)
{
    CanHostClass *chc = CAN_HOST_GET_CLASS(ch);
    Error *local_err = NULL;

    chc->connect(ch, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    can_bus_insert_client(ch->bus, &ch->bus_client);
}

static void can_host_unparent(Object *obj)
{
    can_host_disconnect(CAN_HOST(obj));
}

static void can_host_complete(UserCreatable *uc, Error **errp)
{
    can_host_connect(CAN_HOST(uc), errp);
}

static void can_host_instance_init(Object *obj)
{
    CanHostState *ch = CAN_HOST(obj);

    object_property_add_link(obj, "canbus", TYPE_CAN_BUS,
                             (Object **)&ch->bus,
                             object_property_allow_set_link,
                             OBJ_PROP_LINK_STRONG,
                             &error_abort);
}

static void can_host_class_init(ObjectClass *klass,
                                void *class_data G_GNUC_UNUSED)
{
    UserCreatableClass *uc_klass = USER_CREATABLE_CLASS(klass);

    klass->unparent = can_host_unparent;
    uc_klass->complete = can_host_complete;
}

static const TypeInfo can_host_info = {
    .parent = TYPE_OBJECT,
    .name = TYPE_CAN_HOST,
    .instance_size = sizeof(CanHostState),
    .class_size = sizeof(CanHostClass),
    .abstract = true,
    .instance_init = can_host_instance_init,
    .class_init = can_host_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_USER_CREATABLE },
        { }
    }
};

static void can_host_register_types(void)
{
    type_register_static(&can_host_info);
}

type_init(can_host_register_types);
