Пример #1
0
static void gpio_handle_event(struct aura_node *node, enum node_event evt, const struct aura_pollfds *fd)
{
	struct aura_buffer *buf;
	struct aura_object *o;

	while (1) {
		buf = aura_dequeue_buffer(&node->outbound_buffers);
		if (!buf)
			break;
		o = buf->object;
		handle_outbound(node, o, buf);
		aura_buffer_release(buf);
	}
}
Пример #2
0
static void usb_loop(struct aura_node *node, const struct aura_pollfds *fd)
{
	struct aura_buffer *buf;
	struct usb_dev_info *inf = aura_get_transportdata(node);
	struct timeval tv = { 
		.tv_sec  = 0,
		.tv_usec = 0
	};

	libusb_handle_events_timeout(inf->ctx, &tv);

	if (inf->cbusy)
		return; 

	if (inf->state == AUSB_DEVICE_RESTART) { 
		slog(4, SLOG_DEBUG, "usb: transport offlined, starting to look for a device");
		aura_set_status(node, AURA_STATUS_OFFLINE);
		libusb_close(inf->handle);
		inf->handle = NULL;
		inf->state = AUSB_DEVICE_SEARCHING;
		ncusb_watch_for_device(inf->ctx, &inf->dev_descr);
		return;
	}

	if (inf->state == AUSB_DEVICE_OPERATIONAL) {
		if (inf->pending) 
			submit_event_readout(node);
		else if ( (buf = aura_dequeue_buffer(&node->outbound_buffers)) ) { 
			submit_call_write(node, buf);
		}
	}
}

static struct aura_transport usb = { 
	.name = "usb",
	.open = usb_open,
	.close = usb_close,
	.loop  = usb_loop,
	.buffer_overhead = LIBUSB_CONTROL_SETUP_SIZE, /* Offset for usb SETUP structure */  
	.buffer_offset = LIBUSB_CONTROL_SETUP_SIZE
};

AURA_TRANSPORT(usb);
Пример #3
0
/* This one is small, but tricky */
static void aura_handle_inbound(struct aura_node *node)
{
    while(1) {
        struct aura_buffer *buf;
        struct aura_object *o;

        buf = aura_dequeue_buffer(&node->inbound_buffers);
        if (!buf)
            break;

        o = buf->object;
        node->current_object = o;
        aura_buffer_rewind(buf);

        slog(4, SLOG_DEBUG, "Handling %s id %d (%s) sync_call_running=%d",
             object_is_method(o) ? "response" : "event",
             o->id, o->name, node->sync_call_running);

        if (object_is_method(o) && !o->pending) {
            slog(0, SLOG_WARN, "Dropping orphan call result %d (%s)",
                 o->id, o->name);
            aura_buffer_release(node, buf);
        } else if (o->calldonecb) {
            slog(4, SLOG_DEBUG, "Callback for method/event %d (%s)",
                 o->id, o->name);
            o->calldonecb(node, AURA_CALL_COMPLETED, buf, o->arg);
            aura_buffer_release(node, buf);
        } else if (object_is_method(o) && (node->sync_call_running)) {
            slog(4, SLOG_DEBUG, "Completing call for method %d (%s)",
                 o->id, o->name);
            node->sync_call_result = AURA_CALL_COMPLETED;
            node->sync_ret_buf = buf;
            o->pending--;
            if (o->pending < 0)
                BUG(node, "Internal BUG: pending evt count lesser than zero");
        } else {
            /* This one is tricky. We have an event with no callback */
            if (node->sync_event_max > 0) { /* Queue it up into event_queue if it's enabled */
                /* If we have an overrun - drop the oldest event to free up space first*/
                if (node->sync_event_max <= node->sync_event_count) {
                    struct aura_buffer *todrop;
                    const struct aura_object *dummy;
                    int ret = aura_get_next_event(node, &dummy, &todrop);
                    if (ret != 0)
                        BUG(node, "Internal bug, no next event");
                    aura_buffer_release(node, todrop);
                }

                /* Now just queue the next one */
                aura_queue_buffer(&node->event_buffers, buf);
                node->sync_event_count++;
                slog(4, SLOG_DEBUG, "Queued event %d (%s) for sync readout",
                     o->id, o->name);
            } else {
                /* Last resort - try the catch-all event callback */
                if (node->unhandled_evt_cb)
                    node->unhandled_evt_cb(node, buf, node->unhandled_evt_arg);
                else /* Or just drop it with a warning */
                    slog(0, SLOG_WARN, "Dropping event %d (%s)",
                         o->id, o->name);
                aura_buffer_release(node, buf);
            }
        }
    }

    node->current_object = NULL;
}