static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)

{

    struct VirtIOSerialPort *port;

    struct virtio_console_control cpkt, *gcpkt;

    uint8_t *buffer;

    size_t buffer_len;



    gcpkt = buf;



    if (len < sizeof(cpkt)) {

        /* The guest sent an invalid control packet */

        return;

    }



    cpkt.event = lduw_p(&gcpkt->event);

    cpkt.value = lduw_p(&gcpkt->value);



    port = find_port_by_id(vser, ldl_p(&gcpkt->id));

    if (!port && cpkt.event != VIRTIO_CONSOLE_DEVICE_READY)

        return;



    switch(cpkt.event) {

    case VIRTIO_CONSOLE_DEVICE_READY:

        if (!cpkt.value) {

            error_report("virtio-serial-bus: Guest failure in adding device %s\n",

                         vser->bus->qbus.name);

            break;

        }

        /*

         * The device is up, we can now tell the device about all the

         * ports we have here.

         */

        QTAILQ_FOREACH(port, &vser->ports, next) {

            send_control_event(port, VIRTIO_CONSOLE_PORT_ADD, 1);

        }

        break;



    case VIRTIO_CONSOLE_PORT_READY:

        if (!cpkt.value) {

            error_report("virtio-serial-bus: Guest failure in adding port %u for device %s\n",

                         port->id, vser->bus->qbus.name);

            break;

        }

        /*

         * Now that we know the guest asked for the port name, we're

         * sure the guest has initialised whatever state is necessary

         * for this port. Now's a good time to let the guest know if

         * this port is a console port so that the guest can hook it

         * up to hvc.

         */

        if (port->is_console) {

            send_control_event(port, VIRTIO_CONSOLE_CONSOLE_PORT, 1);

        }



        if (port->name) {

            stw_p(&cpkt.event, VIRTIO_CONSOLE_PORT_NAME);

            stw_p(&cpkt.value, 1);



            buffer_len = sizeof(cpkt) + strlen(port->name) + 1;

            buffer = qemu_malloc(buffer_len);



            memcpy(buffer, &cpkt, sizeof(cpkt));

            memcpy(buffer + sizeof(cpkt), port->name, strlen(port->name));

            buffer[buffer_len - 1] = 0;



            send_control_msg(port, buffer, buffer_len);

            qemu_free(buffer);

        }



        if (port->host_connected) {

            send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1);

        }



        /*

         * When the guest has asked us for this information it means

         * the guest is all setup and has its virtqueues

         * initialised. If some app is interested in knowing about

         * this event, let it know.

         */

        if (port->info->guest_ready) {

            port->info->guest_ready(port);

        }

        break;



    case VIRTIO_CONSOLE_PORT_OPEN:

        port->guest_connected = cpkt.value;

        if (cpkt.value && port->info->guest_open) {

            /* Send the guest opened notification if an app is interested */

            port->info->guest_open(port);

        }



        if (!cpkt.value && port->info->guest_close) {

            /* Send the guest closed notification if an app is interested */

            port->info->guest_close(port);

        }

        break;

    }

}

static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)

{

    struct VirtIOSerialPort *port;

    struct virtio_console_control cpkt, *gcpkt;

    uint8_t *buffer;

    size_t buffer_len;



    gcpkt = buf;



    if (len < sizeof(cpkt)) {

        

        return;

    }



    cpkt.event = lduw_p(&gcpkt->event);

    cpkt.value = lduw_p(&gcpkt->value);



    port = find_port_by_id(vser, ldl_p(&gcpkt->id));

    if (!port && cpkt.event != VIRTIO_CONSOLE_DEVICE_READY)

        return;



    switch(cpkt.event) {

    case VIRTIO_CONSOLE_DEVICE_READY:

        if (!cpkt.value) {

            error_report("virtio-serial-bus: Guest failure in adding device %s\n",

                         vser->bus->qbus.name);

            break;

        }

        







        QTAILQ_FOREACH(port, &vser->ports, next) {

            send_control_event(port, VIRTIO_CONSOLE_PORT_ADD, 1);

        }

        break;



    case VIRTIO_CONSOLE_PORT_READY:

        if (!cpkt.value) {

            error_report("virtio-serial-bus: Guest failure in adding port %u for device %s\n",

                         port->id, vser->bus->qbus.name);

            break;

        }

        













        if (port->is_console) {

            send_control_event(port, VIRTIO_CONSOLE_CONSOLE_PORT, 1);

        }



        if (port->name) {

            stw_p(&cpkt.event, VIRTIO_CONSOLE_PORT_NAME);

            stw_p(&cpkt.value, 1);



            buffer_len = sizeof(cpkt) + strlen(port->name) + 1;

            buffer = qemu_malloc(buffer_len);



            memcpy(buffer, &cpkt, sizeof(cpkt));

            memcpy(buffer + sizeof(cpkt), port->name, strlen(port->name));

            buffer[buffer_len - 1] = 0;



            send_control_msg(port, buffer, buffer_len);

            qemu_free(buffer);

        }



        if (port->host_connected) {

            send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1);

        }



        











        if (port->info->guest_ready) {

            port->info->guest_ready(port);

        }

        break;



    case VIRTIO_CONSOLE_PORT_OPEN:

        port->guest_connected = cpkt.value;

        if (cpkt.value && port->info->guest_open) {

            

            port->info->guest_open(port);

        }



        if (!cpkt.value && port->info->guest_close) {

            

            port->info->guest_close(port);

        }

        break;

    }

}

                         vser->bus->qbus.name);                          port->id, vser->bus->qbus.name);
static void FUNC_0(VirtIOSerial *VAR_0, void *VAR_1, size_t VAR_2)

{

    struct VirtIOSerialPort *VAR_3;

    struct virtio_console_control VAR_4, *VAR_5;

    uint8_t *buffer;

    size_t buffer_len;



    VAR_5 = VAR_1;



    if (VAR_2 < sizeof(VAR_4)) {

        

        return;

    }



    VAR_4.event = lduw_p(&VAR_5->event);

    VAR_4.value = lduw_p(&VAR_5->value);



    VAR_3 = find_port_by_id(VAR_0, ldl_p(&VAR_5->id));

    if (!VAR_3 && VAR_4.event != VIRTIO_CONSOLE_DEVICE_READY)

        return;



    switch(VAR_4.event) {

    case VIRTIO_CONSOLE_DEVICE_READY:

        if (!VAR_4.value) {

            error_report("virtio-serial-bus: Guest failure in adding device %s\n",

                         VAR_0->bus->qbus.name);

            break;

        }

        







        QTAILQ_FOREACH(VAR_3, &VAR_0->ports, next) {

            send_control_event(VAR_3, VIRTIO_CONSOLE_PORT_ADD, 1);

        }

        break;



    case VIRTIO_CONSOLE_PORT_READY:

        if (!VAR_4.value) {

            error_report("virtio-serial-bus: Guest failure in adding VAR_3 %u for device %s\n",

                         VAR_3->id, VAR_0->bus->qbus.name);

            break;

        }

        













        if (VAR_3->is_console) {

            send_control_event(VAR_3, VIRTIO_CONSOLE_CONSOLE_PORT, 1);

        }



        if (VAR_3->name) {

            stw_p(&VAR_4.event, VIRTIO_CONSOLE_PORT_NAME);

            stw_p(&VAR_4.value, 1);



            buffer_len = sizeof(VAR_4) + strlen(VAR_3->name) + 1;

            buffer = qemu_malloc(buffer_len);



            memcpy(buffer, &VAR_4, sizeof(VAR_4));

            memcpy(buffer + sizeof(VAR_4), VAR_3->name, strlen(VAR_3->name));

            buffer[buffer_len - 1] = 0;



            send_control_msg(VAR_3, buffer, buffer_len);

            qemu_free(buffer);

        }



        if (VAR_3->host_connected) {

            send_control_event(VAR_3, VIRTIO_CONSOLE_PORT_OPEN, 1);

        }



        











        if (VAR_3->info->guest_ready) {

            VAR_3->info->guest_ready(VAR_3);

        }

        break;



    case VIRTIO_CONSOLE_PORT_OPEN:

        VAR_3->guest_connected = VAR_4.value;

        if (VAR_4.value && VAR_3->info->guest_open) {

            

            VAR_3->info->guest_open(VAR_3);

        }



        if (!VAR_4.value && VAR_3->info->guest_close) {

            

            VAR_3->info->guest_close(VAR_3);

        }

        break;

    }

}

static void FUNC_0(VirtIOSerial *VAR_0, void *VAR_1, size_t VAR_2)
{ struct VirtIOSerialPort *VAR_3; struct virtio_console_control VAR_4, *VAR_5; uint8_t *buffer; size_t buffer_len; VAR_5 = VAR_1; if (VAR_2 < sizeof(VAR_4)) { return; } VAR_4.event = lduw_p(&VAR_5->event); VAR_4.value = lduw_p(&VAR_5->value); VAR_3 = find_port_by_id(VAR_0, ldl_p(&VAR_5->id)); if (!VAR_3 && VAR_4.event != VIRTIO_CONSOLE_DEVICE_READY)
return; switch(VAR_4.event) { case VIRTIO_CONSOLE_DEVICE_READY:
if (!VAR_4.value) { error_report("virtio-serial-bus: Guest failure in adding device %s\n",
VAR_0->bus->qbus.name); break; } QTAILQ_FOREACH(VAR_3, &VAR_0->ports, next) { send_control_event(VAR_3, VIRTIO_CONSOLE_PORT_ADD, 1); } break; case VIRTIO_CONSOLE_PORT_READY:
if (!VAR_4.value) { error_report("virtio-serial-bus: Guest failure in adding VAR_3 %u for device %s\n",
VAR_3->id, VAR_0->bus->qbus.name); break; } if (VAR_3->is_console) { send_control_event(VAR_3, VIRTIO_CONSOLE_CONSOLE_PORT, 1); } if (VAR_3->name) { stw_p(&VAR_4.event, VIRTIO_CONSOLE_PORT_NAME); stw_p(&VAR_4.value, 1); buffer_len = sizeof(VAR_4) + strlen(VAR_3->name) + 1; buffer = qemu_malloc(buffer_len); memcpy(buffer, &VAR_4, sizeof(VAR_4)); memcpy(buffer + sizeof(VAR_4), VAR_3->name, strlen(VAR_3->name)); buffer[buffer_len - 1] = 0; send_control_msg(VAR_3, buffer, buffer_len); qemu_free(buffer); } if (VAR_3->host_connected) { send_control_event(VAR_3, VIRTIO_CONSOLE_PORT_OPEN, 1); } if (VAR_3->info->guest_ready) { VAR_3->info->guest_ready(VAR_3); } break; case VIRTIO_CONSOLE_PORT_OPEN:
VAR_3->guest_connected = VAR_4.value; if (VAR_4.value && VAR_3->info->guest_open) { VAR_3->info->guest_open(VAR_3); } if (!VAR_4.value && VAR_3->info->guest_close) { VAR_3->info->guest_close(VAR_3); } break; } }