linux下使用libusb获取系统usb设备具体信息

5 篇文章 0 订阅



一、libusb简介

libusb库提供的api接口供应用层调用,可以对系统中的usb设备操作,如reset一个usb设备,或者获取其具体信息,如configuration、interface及settings等。libusb遵循posix协议,可以跨平台使用,Linux下默认预装libusb1.0版本,开发者可以直接使用,只是在编译时需要链接lib库。

二、libusb的api介绍

1. libusb_init和libusb_exit及struct libusb_context

代码中调用libusb接口函数需要先建立上下文环境,其中结构体struct libusb_context代表一段libusb的会话,官方文档中有对这个结构的说明[libusb]。libusb_init()表示开启会话,libusb_exit()表示结束会话。通俗的理解就是struct libusb_context* ctx中的ctx代表一把钥匙,libusb_init(&ctx)表示开启,libusb_exit(null)表示锁上。

2. libusb中几个重要的数据结构体和接口函数

libusb_device **list;这个结构体用来列举当前系统中的usb设备。

libusb_device_handle *  handle;这个结构体是用来处理具体list中的usb设备的。

上面两个结构体的使用方式:

ssize_t num_devs = libusb_get_device_list(ctx, &list);根据ctx获取系统中的usb设备,返回设备个数,list指向链表头。

libusb_device *dev = list[i];
        libusb_open(dev,&handle);

获取第i个设备并使用handle进行处理。

struct libusb_device_descriptor desc; usb设备描述结构体。

struct libusb_config_descriptor conf;  usb设备配置描述结构体。

libusb_get_device_descriptor(dev, &desc);获取usb设备描述。

libusb_get_config_descriptor(dev, j, &conf); 获取usb设备配置描述。

uint8_t bnum = libusb_get_bus_number(dev); 获取usb设备总线号。
uint8_t dnum = libusb_get_device_address(dev); 获取usb设备端口号。比方3-1.1。

除上述一些接口外还有其它一些接口函数,具体用法可以到官网上查询。

三、 使用libusb获取当前usb设备的具体信息。

#include<stdio.h>
#include<libusb.h>
//#include  <libusb-1.0/libusb.h>  
#include<sys/types.h>
#include<errno.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>

int get_configuration(libusb_device* dev, struct libusb_config_descriptor *config)
{
   int ret = 0;
   ret = libusb_get_config_descriptor(dev, 0, &config);
return ret;
}

static void dump_altsetting(libusb_device_handle *dev, const struct libusb_interface_descriptor *interface)
{
//	char cls[128], subcls[128], proto[128];
//	char *ifstr;

//	get_class_string(cls, sizeof(cls), interface->bInterfaceClass);
//	get_subclass_string(subcls, sizeof(subcls), interface->bInterfaceClass, interface->bInterfaceSubClass);
//	get_protocol_string(proto, sizeof(proto), interface->bInterfaceClass, interface->bInterfaceSubClass, interface->bInterfaceProtocol);
//	ifstr = get_dev_string(dev, interface->iInterface);

	printf("    Interface Descriptor:\n"
	       "      bLength             %5u\n"
	       "      bDescriptorType     %5u\n"
	       "      bInterfaceNumber    %5u\n"
	       "      bAlternateSetting   %5u\n"
	       "      bNumEndpoints       %5u\n"
	       "      bInterfaceClass     %5u\n"
	       "      bInterfaceSubClass  %5u\n"
	       "      bInterfaceProtocol  %5u\n",
	       interface->bLength, interface->bDescriptorType, interface->bInterfaceNumber,
	       interface->bAlternateSetting, interface->bNumEndpoints, interface->bInterfaceClass,
	       interface->bInterfaceSubClass,interface->bInterfaceProtocol);

//	free(ifstr);
}

static void dump_interface(libusb_device_handle *dev, const struct libusb_interface *interface)
{
	int i;

	for (i = 0; i < interface->num_altsetting; i++)
		dump_altsetting(dev, &interface->altsetting[i]);
}

static int list_devices(libusb_context *ctx)
{
	libusb_device **list;
	struct libusb_device_descriptor desc;
	struct libusb_config_descriptor* conf;

	libusb_device_handle *  handle = NULL;
	int config= 0;
	int ret;

	int status;
	ssize_t num_devs, i, j, k;

	status = 1; /* 1 device not found, 0 device found */

	num_devs = libusb_get_device_list(ctx, &list);
	if (num_devs < 0)
		goto error;

	for (i = 0; i < num_devs; ++i) {
		libusb_device *dev = list[i];
		libusb_open(dev,&handle);

		libusb_get_configuration(handle,&config);

 		uint8_t bnum = libusb_get_bus_number(dev);
		uint8_t dnum = libusb_get_device_address(dev);

		libusb_get_device_descriptor(dev, &desc);
		status = 0;
		printf("device:%04x:%04x\n",desc.idVendor,desc.idProduct);
		printf("bDeviceSubClass = %5u\n",desc.bDeviceSubClass);
		printf("bDeviceClass    = %5u\n",desc.bDeviceClass);
		printf("bDeviceProtocol    = %5u\n",desc.bDeviceProtocol);
		for( j = 0; j < desc.bNumConfigurations; ++j) {
                        ret = libusb_get_config_descriptor(dev, j, &conf);
                        if (ret) {
                                fprintf(stderr, "Couldn't get configuration "
                                                "descriptor %lu, some information will "
                                                "be missing\n", j);
                        } else {
				printf("bNumberInterfaces = %5u\n",conf->bNumInterfaces);
				printf("bConfigurationValue = %5u\n",conf->bConfigurationValue);
				
				for (k = 0 ; k < conf->bNumInterfaces ; k++)
					dump_interface(handle, &conf->interface[k]);
                                libusb_free_config_descriptor(conf);
                        }
                }
		
	}

	libusb_free_device_list(list, 0);
error:
	return status;
}

int main(int argc, char* args[])
{
   
   int err = 0;
   libusb_context *ctx;
   err = libusb_init(&ctx);
   if (err) {
	fprintf(stderr, "unable to initialize libusb: %i\n", err);
	return EXIT_FAILURE;
   }

   list_devices(ctx);

return 0;
}

Makefile

header_src=/usr/include/libusb-1.0

lsusb : lsusb.c
	gcc lsusb.c -o lsusb -lusb-1.0 -I$(header_src)

clean:
	rm ./lsusb 

四、使用libusb重置usb设备

#include <stdio.h>
#include <stdlib.h>
#include <libusb-1.0/libusb.h>

struct libusb_device_handle *devh;
struct libusb_device *dev;
struct libusb_device **devs;
struct libusb_context *ctx;
void resetUSB() {
    int success;
    int bpoint = 0;
    do {
        success = libusb_reset_device(devh);
        ++bpoint;
        if (bpoint > 3) {
            success = 1;
        }
    } while (success < 0);
    if (success) {
        printf("\nreset usb device failed:%d\n", success);
    } else {
        printf("\nreset usb device ok\n");
    }
}
struct libusb_device* search_device(int _busNum, int _devNum) { 
    libusb_device *l_dev;
    int i = 0;
    int l_busNum, l_devNum;
   
    while ((l_dev = devs[i++]) != NULL) {
        printf("check against %d device\n", i);
        l_busNum =(int) libusb_get_bus_number(l_dev);
        l_devNum =(int) libusb_get_device_address(l_dev);
        printf("bus number: %d; device number: %d\n", l_busNum, l_devNum);
        if ((l_busNum == _busNum) && (l_devNum == _devNum)) {
            printf("found device\n");
            return l_dev;
        }
    }
    return NULL;
}
int main(int argc, char **argv) {
    //parse the input parameters to get the bus number and device number
    int l_busNum, l_devNum;
    int l_ret;

    if (argc < 3) {
        printf("not enough arguments!\n");
        printf("usage: ./usbreset <bus number> <dev number>\n");
        return 0;
    }
    printf("bus number: %s\n", argv[1]);
    printf("dev number: %s\n", argv[2]);
    l_busNum = atoi(argv[1]);
    l_devNum = atoi(argv[2]);
    printf("bus number: %d; dev number: %d\n", l_busNum, l_devNum);

   l_ret = libusb_init(&ctx);
   if (l_ret ) {
	fprintf(stderr, "unable to initialize libusb: %i\n", err);
	return EXIT_FAILURE;

    l_ret = libusb_get_device_list(NULL, &devs);
    if (l_ret < 0) {
        return (int) l_ret;
    }
    dev = search_device(l_busNum, l_devNum);
    if (dev == NULL) {
        printf("device not found\n");
        return 0;
    }
    l_ret = libusb_open(dev, &devh);    
    if (l_ret == 0) {
        printf("got the usb handle successfully.\n");
    } else {
        printf("error getting usb handle.\n");
    }
    //reset the usb device
    resetUSB();
    //free the device list
    libusb_free_device_list(devs, 1);
    libusb_exit(NULL);
    return 0;
}

五、总结。

libusb是一个应用层处理usb设备的很好的借口代码,相对于udev来说,libusb更加接近usb驱动,能够从系统级别操作或取得usb的信息。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值