当前位置:   article > 正文

应用程序利用libusb读取usb设备数据_libusb获取设备信息

libusb获取设备信息
USB HID类是USB设备的一个标准设备类,属于人机交互操作的设备,包括鼠标、键盘等,主要用于人与计算机进行交互,它还可用来传输数据、控制设备等。
非标USB设备,应用程序可以通过libusb读取数据,当然也可以读取标准HID类设备如鼠标等。
一、移植libusb-1.0.24
./configure --host=arm-linux-gnueabihf --prefix=$PWD/_install --disable-udev
二、编写usb_test程序并编译
arm-linux-gnueabihf-gcc main.c -I ../libusb-1.0.24/_install/include/libusb-1.0/ ../libusb-1.0.24/_install/lib/libusb-1.0.a -o usb_test -lpthread
测试代码:
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <errno.h>
  4. #include <stdlib.h>
  5. #include <stdint.h>
  6. #include <errno.h>
  7. #include <fcntl.h>
  8. #include <unistd.h>
  9. #include <time.h>
  10. #include <getopt.h>
  11. #include <ctype.h>
  12. #include <signal.h>
  13.  
  14. #include "libusb.h"
  15.  
  16. int verbose = 1;
  17.  
  18. static volatile sig_atomic_t rcv_exit;
  19.  
  20.  
  21. static void print_endpoint_comp(const struct libusb_ss_endpoint_companion_descriptor *ep_comp)
  22. {
  23. printf("      USB 3.0 Endpoint Companion:\n");
  24. printf("        bMaxBurst:           %u\n", ep_comp->bMaxBurst);
  25. printf("        bmAttributes:        %02xh\n", ep_comp->bmAttributes);
  26. printf("        wBytesPerInterval:   %u\n", ep_comp->wBytesPerInterval);
  27. }
  28.  
  29. static void print_endpoint(const struct libusb_endpoint_descriptor *endpoint)
  30. {
  31. int i, ret;
  32.  
  33. printf("      Endpoint:\n");
  34. printf("        bEndpointAddress:    %02xh\n", endpoint->bEndpointAddress);
  35. printf("        bmAttributes:        %02xh\n", endpoint->bmAttributes);
  36. printf("        wMaxPacketSize:      %u\n", endpoint->wMaxPacketSize);
  37. printf("        bInterval:           %u\n", endpoint->bInterval);
  38. printf("        bRefresh:            %u\n", endpoint->bRefresh);
  39. printf("        bSynchAddress:       %u\n", endpoint->bSynchAddress);
  40.  
  41. for (i = 0; i < endpoint->extra_length;) {
  42. if (LIBUSB_DT_SS_ENDPOINT_COMPANION == endpoint->extra[i + 1]) {
  43. struct libusb_ss_endpoint_companion_descriptor *ep_comp;
  44.  
  45. ret = libusb_get_ss_endpoint_companion_descriptor(NULL, endpoint, &ep_comp);
  46. if (LIBUSB_SUCCESS != ret)
  47. continue;
  48.  
  49. print_endpoint_comp(ep_comp);
  50.  
  51. libusb_free_ss_endpoint_companion_descriptor(ep_comp);
  52. }
  53.  
  54. i += endpoint->extra[i];
  55. }
  56. }
  57.  
  58. static void print_altsetting(const struct libusb_interface_descriptor *interface)
  59. {
  60. uint8_t i;
  61.  
  62. printf("    Interface:\n");
  63. printf("      bInterfaceNumber:      %u\n", interface->bInterfaceNumber);
  64. printf("      bAlternateSetting:     %u\n", interface->bAlternateSetting);
  65. printf("      bNumEndpoints:         %u\n", interface->bNumEndpoints);
  66. printf("      bInterfaceClass:       %u\n", interface->bInterfaceClass);
  67. printf("      bInterfaceSubClass:    %u\n", interface->bInterfaceSubClass);
  68. printf("      bInterfaceProtocol:    %u\n", interface->bInterfaceProtocol);
  69. printf("      iInterface:            %u\n", interface->iInterface);
  70.  
  71. for (i = 0; i < interface->bNumEndpoints; i++)
  72. print_endpoint(&interface->endpoint[i]);
  73. }
  74.  
  75. static void print_2_0_ext_cap(struct libusb_usb_2_0_extension_descriptor *usb_2_0_ext_cap)
  76. {
  77. printf("    USB 2.0 Extension Capabilities:\n");
  78. printf("      bDevCapabilityType:    %u\n", usb_2_0_ext_cap->bDevCapabilityType);
  79. printf("      bmAttributes:          %08xh\n", usb_2_0_ext_cap->bmAttributes);
  80. }
  81.  
  82. static void print_ss_usb_cap(struct libusb_ss_usb_device_capability_descriptor *ss_usb_cap)
  83. {
  84. printf("    USB 3.0 Capabilities:\n");
  85. printf("      bDevCapabilityType:    %u\n", ss_usb_cap->bDevCapabilityType);
  86. printf("      bmAttributes:          %02xh\n", ss_usb_cap->bmAttributes);
  87. printf("      wSpeedSupported:       %u\n", ss_usb_cap->wSpeedSupported);
  88. printf("      bFunctionalitySupport: %u\n", ss_usb_cap->bFunctionalitySupport);
  89. printf("      bU1devExitLat:         %u\n", ss_usb_cap->bU1DevExitLat);
  90. printf("      bU2devExitLat:         %u\n", ss_usb_cap->bU2DevExitLat);
  91. }
  92.  
  93. static void print_bos(libusb_device_handle *handle)
  94. {
  95. struct libusb_bos_descriptor *bos;
  96. uint8_t i;
  97. int ret;
  98.  
  99. ret = libusb_get_bos_descriptor(handle, &bos);
  100. if (ret < 0)
  101. return;
  102.  
  103. printf("  Binary Object Store (BOS):\n");
  104. printf("    wTotalLength:            %u\n", bos->wTotalLength);
  105. printf("    bNumDeviceCaps:          %u\n", bos->bNumDeviceCaps);
  106.  
  107. for (i = 0; i < bos->bNumDeviceCaps; i++) {
  108. struct libusb_bos_dev_capability_descriptor *dev_cap = bos->dev_capability[i];
  109.  
  110. if (dev_cap->bDevCapabilityType == LIBUSB_BT_USB_2_0_EXTENSION) {
  111. struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension;
  112.  
  113. ret = libusb_get_usb_2_0_extension_descriptor(NULL, dev_cap, &usb_2_0_extension);
  114. if (ret < 0)
  115. return;
  116.  
  117. print_2_0_ext_cap(usb_2_0_extension);
  118. libusb_free_usb_2_0_extension_descriptor(usb_2_0_extension);
  119. } else if (dev_cap->bDevCapabilityType == LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) {
  120. struct libusb_ss_usb_device_capability_descriptor *ss_dev_cap;
  121.  
  122. ret = libusb_get_ss_usb_device_capability_descriptor(NULL, dev_cap, &ss_dev_cap);
  123. if (ret < 0)
  124. return;
  125.  
  126. print_ss_usb_cap(ss_dev_cap);
  127. libusb_free_ss_usb_device_capability_descriptor(ss_dev_cap);
  128. }
  129. }
  130.  
  131. libusb_free_bos_descriptor(bos);
  132. }
  133.  
  134. static void print_interface(const struct libusb_interface *interface)
  135. {
  136. int i;
  137.  
  138. for (i = 0; i < interface->num_altsetting; i++)
  139. print_altsetting(&interface->altsetting[i]);
  140. }
  141.  
  142. static void print_configuration(struct libusb_config_descriptor *config)
  143. {
  144. uint8_t i;
  145.  
  146. printf("  Configuration:\n");
  147. printf("    wTotalLength:            %u\n", config->wTotalLength);
  148. printf("    bNumInterfaces:          %u\n", config->bNumInterfaces);
  149. printf("    bConfigurationValue:     %u\n", config->bConfigurationValue);
  150. printf("    iConfiguration:          %u\n", config->iConfiguration);
  151. printf("    bmAttributes:            %02xh\n", config->bmAttributes);
  152. printf("    MaxPower:                %u\n", config->MaxPower);
  153.  
  154. for (i = 0; i < config->bNumInterfaces; i++)
  155. print_interface(&config->interface[i]);
  156. }
  157.  
  158.  
  159. static void print_device(libusb_device *dev, libusb_device_handle *handle, uint16_t vid, uint16_t pid)
  160. {
  161. struct libusb_device_descriptor desc;
  162. unsigned char string[256];
  163. const char *speed;
  164. int ret;
  165. uint8_t i;
  166.  
  167. switch (libusb_get_device_speed(dev)) {
  168. case LIBUSB_SPEED_LOW: speed = "1.5M"; break;
  169. case LIBUSB_SPEED_FULL: speed = "12M"; break;
  170. case LIBUSB_SPEED_HIGH: speed = "480M"; break;
  171. case LIBUSB_SPEED_SUPER: speed = "5G"; break;
  172. case LIBUSB_SPEED_SUPER_PLUS: speed = "10G"; break;
  173. default: speed = "Unknown";
  174. }
  175.  
  176. ret = libusb_get_device_descriptor(dev, &desc);
  177. if (ret < 0) {
  178. fprintf(stderr, "failed to get device descriptor");
  179. return;
  180. }
  181.  
  182. if (!handle)
  183. libusb_open(dev, &handle);
  184.  
  185. if((desc.idVendor == vid) && (desc.idProduct == pid))
  186. {
  187. printf("Dev (bus %u, device %u): %04X - %04X speed: %s\n",
  188.    libusb_get_bus_number(dev), libusb_get_device_address(dev),
  189.    desc.idVendor, desc.idProduct, speed);
  190.  
  191. if (handle)
  192. {
  193. if (desc.iManufacturer) {
  194. ret = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, string, sizeof(string));
  195. if (ret > 0)
  196. printf("  Manufacturer:              %s\n", (char *)string);
  197. }
  198.  
  199. if (desc.iProduct) {
  200. ret = libusb_get_string_descriptor_ascii(handle, desc.iProduct, string, sizeof(string));
  201. if (ret > 0)
  202. printf("  Product:                   %s\n", (char *)string);
  203. }
  204.  
  205. if (desc.iSerialNumber && verbose) {
  206. ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, string, sizeof(string));
  207. if (ret > 0)
  208. printf("  Serial Number:             %s\n", (char *)string);
  209. }
  210. }
  211.  
  212. if (verbose) {
  213. for (i = 0; i < desc.bNumConfigurations; i++) {
  214. struct libusb_config_descriptor *config;
  215.  
  216. ret = libusb_get_config_descriptor(dev, i, &config);
  217. if (LIBUSB_SUCCESS != ret) {
  218. printf("  Couldn't retrieve descriptors\n");
  219. continue;
  220. }
  221.  
  222. print_configuration(config);
  223.  
  224. libusb_free_config_descriptor(config);
  225. }
  226.  
  227. if (handle && desc.bcdUSB >= 0x0201)
  228. print_bos(handle);
  229. }
  230.  
  231. }
  232.  
  233. if(handle)
  234. {
  235. libusb_close(handle);
  236. }
  237. }
  238.  
  239.  
  240. static int test_wrapped_device(const char *device_name, uint16_t vendor_id, uint16_t product_id)
  241. {
  242. libusb_device_handle *handle;
  243. int r, fd;
  244.  
  245. fd = open(device_name, O_RDWR);
  246. if (fd < 0) {
  247. printf("Error could not open %s: %s\n", device_name, strerror(errno));
  248. return 1;
  249. }
  250. r = libusb_wrap_sys_device(NULL, fd, &handle);
  251. if (r) {
  252. printf("Error wrapping device: %s: %s\n", device_name, libusb_strerror(r));
  253. close(fd);
  254. return 1;
  255. }
  256. print_device(libusb_get_device(handle), handle, vendor_id, product_id);
  257. close(fd);
  258. return 0;
  259. }
  260.  
  261.  
  262.  
  263. static void sig_handler(int signum)
  264. {
  265. switch (signum) {
  266. case SIGTERM:
  267. rcv_exit = 1;
  268. break;
  269. case SIGINT:
  270. rcv_exit = 1;
  271. break;
  272. case SIGUSR1:
  273. break;
  274. }
  275. }
  276.  
  277.  
  278. static void usage(char *program)
  279. {
  280. printf("%s - test usb data transfers to/from usb device\n",
  281. program);
  282. printf("Usage:\n");
  283. printf("  %s [options]\n", program);
  284. printf("options are:\n");
  285. printf("Common:\n");
  286. printf("  --help (or -h)\n");
  287. printf("  -v vendor_id\n");
  288. printf("  -p product_id\n");
  289. printf("  -d device name\n");
  290. }
  291.  
  292. static int interrupt_data_rw(uint16_t vendor_id, uint16_t product_id)
  293. {
  294. int kernelDriverDetached = 0;
  295. unsigned char data_in[64]={0};
  296. int length = 0;
  297. int r,j;
  298. libusb_device_handle *handle;
  299.  
  300. handle = libusb_open_device_with_vid_pid(NULL, vendor_id, product_id);
  301. if (handle == NULL
  302. {
  303. printf("libusb_open() failed\n");
  304. return -1;;
  305. }
  306.  
  307.  
  308. /*驱动必须解绑定,否则数据由驱动程序处理*/ if(libusb_kernel_driver_active(handle, 0))
  309. {
  310. printf("Kernel Driver Active\n");
  311. r = libusb_detach_kernel_driver(handle, 0);
  312. if (r == 0)
  313. {
  314. printf("Detach Kernel Driver\n");
  315. kernelDriverDetached = 1;
  316. }
  317. else
  318. {
  319. fprintf(stderr, "Error detaching kernel driver.\n");
  320. return -1;;
  321. }
  322. }
  323.   /* 指定当前接口 */
  324. r = libusb_claim_interface(handle, 0);
  325. if (r != 0)
  326. {
  327. fprintf(stderr, "Error claiming interface.\n");
  328. goto exit;
  329. }
  330.  
  331. while(!rcv_exit)
  332. {
  333. memset(data_in, 0, sizeof(data_in));
  334. /*中断方式读取断点数据,
  335. 由端点描述符可知端点地址 0x81 为鼠标输入端点
  336. 读取长度为5字节,超时时间为1000ms*/
  337.  
  338. r = libusb_interrupt_transfer(handle, 0x81, data_in, 5, &length, 1000);
  339. if ((r < 0) || (length == 0))
  340. {
  341. printf("bulk recive error,r:%d length:%d\n",r,length);
  342. }
  343. else
  344. {
  345. printf("receive data:\n");
  346. for(j=0; j<length; j++)
  347. {
  348. printf("0x%x ",data_in[j]);
  349. }
  350. printf("\n");
  351. }
  352. usleep(500000);
  353. }
  354.  
  355.   /* 释放指定的接口 */
  356. r = libusb_release_interface(handle, 0);
  357. if (0 != r)
  358. {
  359. fprintf(stderr, "Error releasing interface.\n");
  360. }
  361. exit:
  362. if(kernelDriverDetached)
  363. {
  364. //恢复驱动绑定,否则鼠标不可用
  365.     libusb_attach_kernel_driver(handle, 0);
  366. }
  367.  
  368. libusb_close(handle);
  369. return r;
  370.  
  371. }
  372.  
  373.  
  374. int main(int argc, char *argv[])
  375. {
  376. char *program = argv[0];
  377. int option;
  378. const char *device_name = NULL; //"/dev/bus/usb/001/005"
  379. libusb_device **devs;
  380. ssize_t cnt;
  381. int r, i;
  382. uint16_t vid=0, pid=0;
  383. libusb_device_handle *handle = NULL;
  384.  
  385. static const struct option options[] = {
  386. { "vendid", required_argument, NULL, 'v' },
  387. { "productid",  required_argument, NULL, 'p' },
  388. { "devicename",   required_argument, NULL, 'd' },
  389. { "help",   no_argument, NULL, 'h' },
  390. };
  391.  
  392. /* Parse command line options, if any */
  393. while ((option = getopt_long_only(argc, argv,
  394. "hv:p:d:",options, NULL)))
  395. {
  396. if (option == -1)
  397. break;
  398. switch (option) {
  399. case 'v':
  400. vid = strtoul(optarg, NULL, 0);
  401. break;
  402. case 'p':
  403. pid = strtoul(optarg, NULL, 0);
  404. break;
  405. case 'd':
  406. device_name = optarg;
  407. break;
  408. case 'h':
  409. usage(program);
  410. exit(EXIT_SUCCESS);
  411. break;
  412. default:
  413. printf("ERROR: Invalid command line option\n");
  414. usage(program);
  415. exit(EXIT_FAILURE);
  416. }
  417. }
  418.  
  419.  
  420. printf("vid:0x%x pid:0x%x devicename:%s\n",vid,pid,device_name);
  421.  
  422.  
  423. r = libusb_init(NULL);
  424. if (r < 0)
  425. return r;
  426.  
  427. if (device_name) {
  428. printf("test_wrapped_device\n");
  429. r = test_wrapped_device(device_name,vid,pid);
  430. } else {
  431. cnt = libusb_get_device_list(NULL, &devs);
  432. if (cnt < 0) {
  433. libusb_exit(NULL);
  434. return 1;
  435. }
  436.  
  437. for (i = 0; devs[i]; i++)
  438. print_device(devs[i], handle,vid,pid);
  439.  
  440. libusb_free_device_list(devs, 1);
  441. }
  442.  
  443.  
  444. signal(SIGINT, sig_handler);
  445. signal(SIGTERM, sig_handler);
  446.  
  447. //read mouse data
  448. interrupt_data_rw(vid,pid);
  449.  
  450. libusb_exit(NULL);
  451. return r;
  452. }

 
三、测试
lsusb查看鼠标设备的VID和PID
Bus 001 Device 001: ID 1d6b:0002
Bus 001 Device 003: ID 413c:301a
Bus 001 Device 002: ID 1a86:8091
usb_test -v 0x413c -p 0x301a 根据VID和PID读取数据
 
  1. vid:0x413c pid:0x301a devicename:(null)
  2. Dev (bus 1, device 3): 413C - 301A speed: 1.5M
  3.   Manufacturer:              PixArt
  4.   Product:                   Dell MS116 USB Optical Mouse
  5.   Configuration:
  6.     wTotalLength:            34
  7.     bNumInterfaces:          1
  8.     bConfigurationValue:     1
  9.     iConfiguration:          0
  10.     bmAttributes:            a0h
  11.     MaxPower:                50
  12.     Interface:
  13.       bInterfaceNumber:      0
  14.       bAlternateSetting:     0
  15.       bNumEndpoints:         1
  16.       bInterfaceClass:       3
  17.       bInterfaceSubClass:    1
  18.       bInterfaceProtocol:    2
  19.       iInterface:            0
  20.       Endpoint:
  21.         bEndpointAddress:    81h
  22.         bmAttributes:        03h
  23.         wMaxPacketSize:      4
  24.         bInterval:           10
  25.         bRefresh:            0
  26.         bSynchAddress:       0
  27. Kernel Driver Active
  28. Detach Kernel Driver
  29. bulk recive error,r:-7 length:0
  30. receive data:
  31. 0x0 0x1 0x0 0x0 0x0 
  32. receive data:
  33. 0x0 0x7f 0xd4 0x0 0x0 
  34. receive data:
  35. 0x0 0x7f 0xa7 0x0 0x0 
  36. receive data:
  37. 0x0 0x7f 0x81 0x0 0x0 
  38. receive data:
  39. 0x0 0x81 0x81 0x0 0x0 
  40. receive data:
  41. 0x0 0x81 0x7f 0x0 0x0 
  42. receive data:
  43. 0x0 0x83 0xcc 0x0 0x0 
  44. receive data:
  45. 0x0 0x7f 0x6e 0x0 0x0 
  46. receive data:
  47. 0x0 0x7f 0xc2 0x0 0x0 
  48. receive data:
  49. 0x0 0x81 0x5e 0x0 0x0 
  50. receive data:
  51. 0x0 0x7f 0xde 0x0 0x0 
  52. receive data:
  53. 0x0 0xdd 0xf6 0x0 0x0 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/246767
推荐阅读
相关标签
  

闽ICP备14008679号