Advertisement
mar-kim

simple-usb.c

Sep 28th, 2016
300
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.76 KB | None | 0 0
  1. /*
  2. Endpoint Descriptor:
  3.     bLength                 9
  4.     bDescriptorType         5
  5.     bEndpointAddress     0x01  EP 1 OUT
  6.     bmAttributes            9
  7.       Transfer Type            Isochronous
  8.       Synch Type               Adaptive
  9.       Usage Type               Data
  10.     wMaxPacketSize     0x00c0  1x 192 bytes
  11.     bInterval               1
  12.     bRefresh                0
  13.     bSynchAddress           0
  14.     AudioControl Endpoint Descriptor:
  15.       bLength                 7
  16.       bDescriptorType        37
  17.       bDescriptorSubtype      1 (EP_GENERAL)
  18.       bmAttributes         0x00
  19.       bLockDelayUnits         2 Decoded PCM samples
  20.       wLockDelay            512 Decoded PCM samples
  21. */
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <libusb-1.0/libusb.h>
  27. #include <signal.h>
  28. #include <time.h>
  29.  
  30. #define DEBUG
  31. #define VID 0x0582
  32. #define PID 0x0073
  33. #define EPT 0x01
  34. #define NUM_ISO_PACKETS 10
  35. #define PKT_SIZE 192
  36.  
  37. libusb_device ** list;
  38. libusb_device_handle *handle;
  39. static int aborted = 0;
  40. FILE * outfile;
  41. timer_t timerid;
  42.  
  43. void fatal(int code, char * msg, int line)
  44. {
  45.     if (code) {
  46.         dprintf(2, "ERR %d : %d : %s\n", code, line, msg);
  47.         exit(code);
  48.     }
  49. }
  50.  
  51. void timer_callback(union sigval val)
  52. {
  53.     aborted = 1;
  54.     printf("Timer fired\n");
  55. }
  56.  
  57. static void capture_callback(struct libusb_transfer *transfer)
  58. {
  59.     int i;
  60.     printf("cap cb stat %d\n", transfer->status);
  61.  
  62.     for (i = 0; i < NUM_ISO_PACKETS; i++) {
  63.         struct libusb_iso_packet_descriptor *desc =
  64.             &transfer->iso_packet_desc[i];
  65.         unsigned char *pbuf = transfer->buffer + (i * PKT_SIZE);
  66.         if (desc->status != 0) {
  67.             printf("packet %d has status %d\n", i, desc->status);
  68.             continue;
  69.         }
  70.         if (desc->actual_length != PKT_SIZE)
  71.             printf("unexpected data length %d vs %d\n", desc->actual_length, PKT_SIZE);
  72.         fwrite(transfer->buffer + (i * PKT_SIZE), desc->actual_length, 1, outfile);
  73.     }
  74.     if (!aborted) libusb_submit_transfer(transfer);
  75. }
  76.  
  77.  
  78. static struct libusb_transfer *alloc_capture_transfer(void)
  79. {
  80.     int bufflen = PKT_SIZE * NUM_ISO_PACKETS;
  81.     int i;
  82.     struct libusb_transfer *transfer = libusb_alloc_transfer(NUM_ISO_PACKETS);
  83.  
  84.     fatal(!transfer, "transfer alloc failure", __LINE__);
  85.     transfer->dev_handle = handle;
  86.     transfer->endpoint = EPT;
  87.     transfer->type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS;
  88.     transfer->timeout = 5000;
  89.     transfer->buffer = malloc(bufflen);
  90.     transfer->length = bufflen;
  91.     transfer->callback = capture_callback;
  92.     transfer->num_iso_packets = NUM_ISO_PACKETS;
  93.    
  94.     for (i = 0; i < NUM_ISO_PACKETS; i++) {
  95.         transfer->iso_packet_desc[i].length = PKT_SIZE;
  96.     }
  97.     return transfer;
  98. }
  99.  
  100. void read_dev()
  101. {
  102.     int r;
  103.     // get handle
  104.     handle = libusb_open_device_with_vid_pid(NULL, VID, PID);
  105.     fatal(handle == NULL, "no matching device found", __LINE__);
  106.     // claim interface, connect
  107.     int intf_i = 1;
  108.     int alts_i = 1;
  109.     r = libusb_detach_kernel_driver(handle, intf_i); // okay to fail b/c the driver may already have been detached
  110.     r = libusb_claim_interface(handle, intf_i);
  111.     fatal(r, "libusb_claim_interface", __LINE__);
  112.     r = libusb_set_interface_alt_setting(handle, intf_i, alts_i);
  113.     fatal(r, "libusb_set_interface_alt_setting", __LINE__);
  114.     // open outfile
  115.     outfile = fopen("raw.pcm", "wb");
  116.     // submit transfers
  117.     struct libusb_transfer *tx1 = alloc_capture_transfer();
  118.     struct libusb_transfer *tx2 = alloc_capture_transfer();
  119.     r = libusb_submit_transfer(tx1);
  120.     fatal(r, "transfer submit 1", __LINE__);
  121.     r = libusb_submit_transfer(tx2);
  122.     fatal(r, "transfer submit 2", __LINE__);
  123.  
  124.     // wait until xfers complete
  125.     while (!aborted)
  126.         if (libusb_handle_events(NULL) < 0)
  127.             break;
  128.  
  129.     // release
  130.     fclose(outfile);
  131.     r = libusb_set_interface_alt_setting(handle, intf_i, 0);
  132.     fatal(r, "libusb_set_interface_alt_setting 0", __LINE__);
  133.     libusb_close(handle);
  134. }
  135.  
  136.  
  137. static void sighandler(int signum)
  138. {
  139.     printf("got signal %d\n", signum);
  140.     aborted = 1;
  141. }
  142.  
  143. int main(int argc, char * argv[])
  144. {
  145.     int rc;
  146.     #ifdef DEBUG
  147.     printf("starting\n");
  148.     #endif
  149.  
  150.     // signal handling
  151.     struct sigaction sigact;
  152.     sigact.sa_handler = sighandler;
  153.     sigemptyset(&sigact.sa_mask);
  154.     sigact.sa_flags = 0;
  155.     sigaction(SIGINT, &sigact, NULL);
  156.     sigaction(SIGTERM, &sigact, NULL);
  157.     sigaction(SIGQUIT, &sigact, NULL);
  158.  
  159.     // timer
  160.     struct sigevent sige;
  161.     sige.sigev_notify = SIGEV_THREAD;
  162.     sige.sigev_notify_function = timer_callback;
  163.     rc = timer_create(CLOCK_REALTIME, &sige, &timerid);
  164.     fatal(rc, "timer_create failed", __LINE__);
  165.     struct itimerspec its;
  166.     its.it_value.tv_sec = its.it_interval.tv_sec = 1;
  167.     its.it_value.tv_nsec = its.it_interval.tv_nsec = 0;
  168.     rc = timer_settime(timerid, 0, &its, NULL);
  169.  
  170.     // init libusb
  171.     rc = libusb_init(NULL);
  172.     fatal(rc, "libusb_init", __LINE__);
  173.  
  174.     // take action
  175.     read_dev();
  176.  
  177.     // de-init libusb
  178.     libusb_exit(NULL);
  179.     return 0;
  180. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement