/*
 * 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/module.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);
