User Tools

Site Tools


libusb-sample.c
/*
 * Copyright 2019 Oleg Borodin  <borodin@unix7.org>
 */
 
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
 
#include <libusb.h>
 
#define VENDOR_ID      0x067b
#define PRODUCT_ID     0x2303
 
#define ACM_CTRL_DTR   0x01
#define ACM_CTRL_RTS   0x02
 
static struct libusb_device_handle *devh = NULL;
 
static int ep_in_addr  = 0x83;
static int ep_out_addr = 0x02;
 
void write_char(uint8_t c) {
    int rsize;
    if (libusb_bulk_transfer(devh, ep_out_addr, &c, 1, &rsize, 0) < 0) {
        fprintf(stderr, "error while sending\n");
    }
}
 
void write_str(uint8_t* data, int size) {
    int rsize;
    if (libusb_bulk_transfer(devh, ep_out_addr, data, size, &rsize, 0) < 0) {
        fprintf(stderr, "error while sending\n");
    }
}
 
int read_chars(uint8_t* data, int size) {
    int rsize;
    int rc = libusb_bulk_transfer(devh, ep_in_addr, data, size, &rsize, 1000);
 
    if (rc == LIBUSB_ERROR_TIMEOUT) {
        printf("timeout (%d)\n", rsize);
        return -1;
    } else if (rc < 0) {
        fprintf(stderr, "error while reading\n");
        return -1;
    }
    return rsize;
}
 
int main(int argc, char **argv) {
    int rc;
    rc = libusb_init(NULL);
    if (rc < 0) {
        fprintf(stderr, "unable initializing libusb: %s\n", libusb_error_name(rc));
        exit(1);
    }
    libusb_set_debug(NULL, 0);
    devh = libusb_open_device_with_vid_pid(NULL, VENDOR_ID, PRODUCT_ID);
    if (!devh) {
        fprintf(stderr, "error finding device\n");
            if (devh) {
                libusb_close(devh);
            }
            libusb_exit(NULL);
    }
 
    for (int if_num = 0; if_num < 2; if_num++) {
        if (libusb_kernel_driver_active(devh, if_num)) {
            libusb_detach_kernel_driver(devh, if_num);
        }
        rc = libusb_claim_interface(devh, if_num);
        if (rc < 0) {
            fprintf(stderr, "error claiming interface: %s\n",
                    libusb_error_name(rc));
            if (devh) {
                libusb_close(devh);
            }
            libusb_exit(NULL);
        }
    }
 
    rc = libusb_control_transfer(devh, 0x21, 0x22, ACM_CTRL_DTR | ACM_CTRL_RTS, 0, NULL, 0, 0);
    if (rc < 0) {
        fprintf(stderr, "error during control transfer: %s\n", libusb_error_name(rc));
    }
 
    /* - set line encoding: here 9600 8N1
     * 9600 = 0x2580 ~> 0x80, 0x25 in little endian
     */
    uint8_t encoding[] = { 0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08 };
    rc = libusb_control_transfer(devh, 0x21, 0x20, 0, 0, encoding, sizeof(encoding), 0);
    if (rc < 0) {
        fprintf(stderr, "error during control transfer: %s\n", libusb_error_name(rc));
    }
 
    uint8_t buf[65];
    int len;
 
    while(1) {
        uint8_t str[] = "show clock\r";
        write_str((uint8_t*)str, strlen((char*)str));
        sleep(1);
        len = read_chars(buf, 64);
        buf[len] = 0;
        fprintf(stdout, "%s", buf);
        sleep(1);
    }
 
    libusb_release_interface(devh, 0);
 
 
    if (devh) {
        libusb_close(devh);
    }
    libusb_exit(NULL);
    return 0;
}