1 调用libusb_get_device_descriptor获取USB设备的设备描述符,然后调用libusb_get_config_descriptor获取配置描述符、接口描述符、端点描述符信息。
2 根据上面获取的设备信息匹配设备,通常可以通过设备的PID\VID匹配,设备的class 、subclass 、protocol 来进行匹配,如果是复合设备,则根据interface的class 、subclass、protocol来为每一个interface匹配。
3 调用libusb_claim_interface申请一个设备接口
4 读写设备
示例代码:
typedef struct
{
u_int8_t bInterfaceNumber;
u_int8_t bInEndpointAddress;
u_int8_t bOutEndpointAddress;
u_int16_t idVendor;
u_int16_t idProduct;
}stUsbCtrl;
stUsbCtrl usbctrl;
static int FindEndpoint( u_int8_t * bInAddress , u_int8_t * bOutAddress,const struct libusb_interface_descriptor * interface)
{
int i;
int ret=0;
for(i=0;i<interface->bNumEndpoints;i++)
{
if((interface->endpoint[i].bmAttributes&0x03)==0x02)
{
if(interface->endpoint[i].bEndpointAddress&0x80)
{
ret|=1;
*bInAddress=interface->endpoint[i].bEndpointAddress;
}
else
{
ret|=2;
*bOutAddress=interface->endpoint[i].bEndpointAddress;
}
}
}
if(ret==3)
{
return 1;
}
else
{
return 0;
}
}
int FindInterface(struct libusb_device_descriptor * desc,libusb_device *dev )
{
struct libusb_config_descriptor *conf_desc;
int i,j,k;
int isFind = 0;
u_int8_t bInterfaceNumber;
u_int8_t bInEndpointAddress;
u_int8_t bOutEndpointAddress;
for (i=0; i< desc->bNumConfigurations; i++)
{
libusb_get_config_descriptor(dev, i, &conf_desc);
for (j=0; j< conf_desc->bNumInterfaces; j++)
{
for (k=0; k< conf_desc->interface[j].num_altsetting; k++)
{
if(conf_desc->interface[j].altsetting[k].bInterfaceClass==0xff&&conf_desc->interface[j].altsetting[k].bInterfaceSubClass==0xff)
{
if(FindEndpoint( &bInEndpointAddress , &bOutEndpointAddress , &(conf_desc->interface[j].altsetting[k] ) ))
{
bInterfaceNumber = conf_desc->interface[j].altsetting[k].bInterfaceNumber;
libusb_free_config_descriptor(conf_desc);
isFind=1;
goto DINFINTERFACE;
}
}
}
}
libusb_free_config_descriptor(conf_desc);
}
DINFINTERFACE :
if(isFind)
{
usbctrl.bInEndpointAddress=bInEndpointAddress;
usbctrl.bOutEndpointAddress=bOutEndpointAddress;
usbctrl.bInterfaceNumber=bInterfaceNumber;
usbctrl.idVendor=desc->idVendor ;
usbctrl.idProduct=desc->idProduct;
return 1;
}
else
{
return 0;
}
}
int CheckUsbDevice(libusb_device *dev)
{
struct libusb_device_descriptor desc;
int ret = libusb_get_device_descriptor(dev, &desc);
if (LIBUSB_SUCCESS != ret)
{
printf("Error getting device descriptor %s\n", libusb_error_name(ret));
return -1;
}
if((desc.idVendor==USB_MATCH_VID)&&(desc.idProduct==USB_MATCH_PID))
{
if(FindInterface(&desc,dev))
{
return 1;
}
else
{
return -1;
}
}
else
{
return -1;
}
}
int listalldevice( void )
{
libusb_device **devs;
ssize_t cnt;
int i;
int ret;
cnt = libusb_get_device_list(NULL, &devs);
for(i=0;i<cnt;i++)
{
ret =CheckUsbDevice(devs[i]);
if(ret==1)
{
break;
}
}
libusb_free_device_list(devs, 1);
return ret;
}
int main(int argc, char **argv)
{
unsigned char buf[10];
int iRealLen;
int ret;
libusb_init (NULL);
if(listalldevice()==1)
{
libusb_device_handle *handle = libusb_open_device_with_vid_pid(NULL, usbctrl.idVendor, usbctrl.idProduct);
if(handle==NULL)
{
goto DONE;
}
libusb_set_auto_detach_kernel_driver(handle, 1);
ret=libusb_claim_interface(handle, usbctrl.bInterfaceNumber);
if(ret != LIBUSB_SUCCESS)
{
libusb_reset_device( handle );
ret=libusb_claim_interface(handle, usbctrl.bInterfaceNumber);
}
if(ret != LIBUSB_SUCCESS)
{
libusb_close(handle);
goto DONE;
}
ret = libusb_bulk_transfer(handle,usbctrl.bOutEndpointAddress,buf,10,&iRealLen,0);//发送数据
if(ret!=LIBUSB_SUCCESS)
{
if(ret==LIBUSB_ERROR_PIPE)
{
libusb_clear_halt(handle,usbctrl.bInEndpointAddress);
}
}
ret = libusb_bulk_transfer(handle,usbctrl.bInEndpointAddress,buf,10,&iRealLen,0);//接收数据
if(ret!=LIBUSB_SUCCESS)
{
if(ret==LIBUSB_ERROR_PIPE)
{
libusb_clear_halt(handle,usbctrl.bInEndpointAddress);
}
}
libusb_release_interface(handle, usbctrl.bInterfaceNumber);
libusb_close(handle);
}
DONE:
libusb_exit(NULL);
return 0;
}
2 根据上面获取的设备信息匹配设备,通常可以通过设备的PID\VID匹配,设备的class 、subclass 、protocol 来进行匹配,如果是复合设备,则根据interface的class 、subclass、protocol来为每一个interface匹配。
3 调用libusb_claim_interface申请一个设备接口
4 读写设备
示例代码:
typedef struct
{
u_int8_t bInterfaceNumber;
u_int8_t bInEndpointAddress;
u_int8_t bOutEndpointAddress;
u_int16_t idVendor;
u_int16_t idProduct;
}stUsbCtrl;
stUsbCtrl usbctrl;
static int FindEndpoint( u_int8_t * bInAddress , u_int8_t * bOutAddress,const struct libusb_interface_descriptor * interface)
{
int i;
int ret=0;
for(i=0;i<interface->bNumEndpoints;i++)
{
if((interface->endpoint[i].bmAttributes&0x03)==0x02)
{
if(interface->endpoint[i].bEndpointAddress&0x80)
{
ret|=1;
*bInAddress=interface->endpoint[i].bEndpointAddress;
}
else
{
ret|=2;
*bOutAddress=interface->endpoint[i].bEndpointAddress;
}
}
}
if(ret==3)
{
return 1;
}
else
{
return 0;
}
}
int FindInterface(struct libusb_device_descriptor * desc,libusb_device *dev )
{
struct libusb_config_descriptor *conf_desc;
int i,j,k;
int isFind = 0;
u_int8_t bInterfaceNumber;
u_int8_t bInEndpointAddress;
u_int8_t bOutEndpointAddress;
for (i=0; i< desc->bNumConfigurations; i++)
{
libusb_get_config_descriptor(dev, i, &conf_desc);
for (j=0; j< conf_desc->bNumInterfaces; j++)
{
for (k=0; k< conf_desc->interface[j].num_altsetting; k++)
{
if(conf_desc->interface[j].altsetting[k].bInterfaceClass==0xff&&conf_desc->interface[j].altsetting[k].bInterfaceSubClass==0xff)
{
if(FindEndpoint( &bInEndpointAddress , &bOutEndpointAddress , &(conf_desc->interface[j].altsetting[k] ) ))
{
bInterfaceNumber = conf_desc->interface[j].altsetting[k].bInterfaceNumber;
libusb_free_config_descriptor(conf_desc);
isFind=1;
goto DINFINTERFACE;
}
}
}
}
libusb_free_config_descriptor(conf_desc);
}
DINFINTERFACE :
if(isFind)
{
usbctrl.bInEndpointAddress=bInEndpointAddress;
usbctrl.bOutEndpointAddress=bOutEndpointAddress;
usbctrl.bInterfaceNumber=bInterfaceNumber;
usbctrl.idVendor=desc->idVendor ;
usbctrl.idProduct=desc->idProduct;
return 1;
}
else
{
return 0;
}
}
int CheckUsbDevice(libusb_device *dev)
{
struct libusb_device_descriptor desc;
int ret = libusb_get_device_descriptor(dev, &desc);
if (LIBUSB_SUCCESS != ret)
{
printf("Error getting device descriptor %s\n", libusb_error_name(ret));
return -1;
}
if((desc.idVendor==USB_MATCH_VID)&&(desc.idProduct==USB_MATCH_PID))
{
if(FindInterface(&desc,dev))
{
return 1;
}
else
{
return -1;
}
}
else
{
return -1;
}
}
int listalldevice( void )
{
libusb_device **devs;
ssize_t cnt;
int i;
int ret;
cnt = libusb_get_device_list(NULL, &devs);
for(i=0;i<cnt;i++)
{
ret =CheckUsbDevice(devs[i]);
if(ret==1)
{
break;
}
}
libusb_free_device_list(devs, 1);
return ret;
}
int main(int argc, char **argv)
{
unsigned char buf[10];
int iRealLen;
int ret;
libusb_init (NULL);
if(listalldevice()==1)
{
libusb_device_handle *handle = libusb_open_device_with_vid_pid(NULL, usbctrl.idVendor, usbctrl.idProduct);
if(handle==NULL)
{
goto DONE;
}
libusb_set_auto_detach_kernel_driver(handle, 1);
ret=libusb_claim_interface(handle, usbctrl.bInterfaceNumber);
if(ret != LIBUSB_SUCCESS)
{
libusb_reset_device( handle );
ret=libusb_claim_interface(handle, usbctrl.bInterfaceNumber);
}
if(ret != LIBUSB_SUCCESS)
{
libusb_close(handle);
goto DONE;
}
ret = libusb_bulk_transfer(handle,usbctrl.bOutEndpointAddress,buf,10,&iRealLen,0);//发送数据
if(ret!=LIBUSB_SUCCESS)
{
if(ret==LIBUSB_ERROR_PIPE)
{
libusb_clear_halt(handle,usbctrl.bInEndpointAddress);
}
}
ret = libusb_bulk_transfer(handle,usbctrl.bInEndpointAddress,buf,10,&iRealLen,0);//接收数据
if(ret!=LIBUSB_SUCCESS)
{
if(ret==LIBUSB_ERROR_PIPE)
{
libusb_clear_halt(handle,usbctrl.bInEndpointAddress);
}
}
libusb_release_interface(handle, usbctrl.bInterfaceNumber);
libusb_close(handle);
}
DONE:
libusb_exit(NULL);
return 0;
}