コード例 #1
0
static void usb_monitor_check_timeouts(struct usb_monitor_ctx *ctx)
{
    struct usb_port *timeout_itr = NULL, *old_timeout = NULL;
    struct timeval tv;
    uint64_t cur_time;

    gettimeofday(&tv, NULL);
    cur_time = (tv.tv_sec * 1e6) + tv.tv_usec;

    timeout_itr = ctx->timeout_list.lh_first;

    while (timeout_itr != NULL) {
        if (cur_time >= timeout_itr->timeout_expire) {
            //Detatch from list, then run timeout
            old_timeout = timeout_itr;
            timeout_itr = timeout_itr->timeout_next.le_next;

            usb_monitor_lists_del_timeout(old_timeout);

            //Due to async requests, this guard is needed to prevent us
            //accidentaly sending PING on disabled port for example
            if (old_timeout->enabled)
                old_timeout->timeout(old_timeout);
        } else {
            timeout_itr = timeout_itr->timeout_next.le_next;
        }
    }
}
コード例 #2
0
ファイル: gpio_handler.c プロジェクト: relet/usb-monitor
static void gpio_update_port(struct usb_port *port)
{
    struct gpio_port *gport = (struct gpio_port*) port;
    uint8_t gpio_val = 0;
    //We will just write to /sys/class/gpio/gpioX/value, so no need for the full
    //4096 (upper limit according to getconf)
    char file_path[64];
    int32_t bytes_written = 0, fd = 0;

    gport->msg_mode = RESET;

    //Guard agains async reset requests. This guard is also needed for the
    //scenario where we are waiting to ping and device is reset. Then we will
    //still be in timeout list, but also reset. Since we then re-add port to
    //timeout (there is no USB timer), we create infinite loop and that is that
    if (gport->timeout_next.le_next != NULL ||
            gport->timeout_next.le_prev != NULL)
        usb_monitor_lists_del_timeout((struct usb_port*) gport);

    //POWER_OFF is 0, so then we should switch on port
    if (!gport->pwr_state)
        gpio_val = 1;

    //Do a write, if write is successful then we update power state
    snprintf(file_path, sizeof(file_path), "/sys/class/gpio/gpio%u/value", gport->port_num);

    fd = open(file_path, O_WRONLY | FD_CLOEXEC);

    if (fd == -1) {
        USB_DEBUG_PRINT(port->ctx->logfile, "Failed to open gpio file\n");
        usb_helpers_start_timeout((struct usb_port*) gport, DEFAULT_TIMEOUT_SEC);
        return;
    }

    if (gpio_val)
        bytes_written = write(fd, "1", 1);
    else
        bytes_written = write(fd, "0", 1);

    close(fd);

    if (bytes_written > 0) {
        gport->pwr_state = !gport->pwr_state;

        if (gport->pwr_state) {
            gport->msg_mode = IDLE;
            return;
        }
    }

    //There is no error case. If we fail, then we simply sleep and try again. No
    //device to free or anything

    //Sleep no matter if write is successful or not
    usb_helpers_start_timeout((struct usb_port*) gport, GPIO_TIMEOUT_SLEEP_SEC);

    //TODO: How to check if we are done? If we get here, and inverse of
    //power_state is off, then we have switched? Or?
    //USB_DEBUG_PRINT(stderr, "GPIO update\n");
}