使用libusb库实时监测usb设备插拔信息,信息包括USB插拔状态、USB接口号、设备名称iProduct、厂商名称iManufacturer、设备编号idProduct、厂商编号idVendor、接口编号、USB类型码bDeviceClass,与lsusb -v所获取的信息一致,接口号与lsusb -t显示信息一致,厂商名称id为0时,名称获取不到,用厂商编号填充。
class LibusbContext {
public:
LibusbContext() {
ctx=NULL;
libusb_init(&ctx);
}
~LibusbContext() {
libusb_exit(ctx);
}
libusb_context *get() {
return ctx;
}
private:
libusb_context *ctx;
};
struct usb_info
{
// USB接口号
//std::string usbNum;
//设备名称
//std::string iProduct;
//厂商名称
// std::string iManufacturer;
/** 设备编号 */
uint16_t idProduct;
/** 厂商编号 */
uint16_t idVendor;
// USB接口号
//std::string Interface;
uint8_t bDeviceClass;
std::string msg;
};
map<unsigned short, usb_info> usbList;
string get_device(libusb_device *dev)
{
std::string str;
libusb_device_handle *handle = NULL;
libusb_device_descriptor desc;
libusb_get_device_descriptor(dev, &desc);
int result = libusb_open(dev, &handle);
if (result != LIBUSB_SUCCESS) {
// 处理错误
return str;
}
sleep(1);
unsigned char iProduct[256]={0};
unsigned char iManufacturer[256]={0};
int ret;
if (desc.bDeviceClass == 0) {
libusb_config_descriptor *config;
libusb_get_config_descriptor(dev, 0, &config);
printf("bNumInterfaces:%d\n",config->bNumInterfaces);
for (int i = 0; i < config->bNumInterfaces; i++)
{
const libusb_interface *inter = &config->interface[i];
const libusb_interface_descriptor *interdesc = &inter->altsetting[0];
printf("Interface Class Code: %d\n", interdesc->bInterfaceClass);
desc.bDeviceClass = interdesc->bInterfaceClass;
}
libusb_free_config_descriptor(config);
}
ret = libusb_get_string_descriptor_ascii(handle, desc.iProduct, iProduct, sizeof(iProduct));
if ( ret<= 0 ) {
printf("iProduct: err %x %s\n",desc.iProduct,libusb_error_name(ret));//设备名称iProduct
sprintf((char*)iProduct,"%04x",desc.iProduct);
}
ret = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, iManufacturer, sizeof(iManufacturer));
if (ret <= 0 || iManufacturer[0] == ' ') {
printf("Manufacturer:err %x %s\n", desc.iManufacturer,libusb_error_name(ret));//厂商名称iManufacturer
sprintf((char*)iManufacturer,"%04x",desc.idVendor);
}
char usbNum[128]={0};
uint8_t path[8];
char port[16]={0};
int r = libusb_get_port_numbers(dev,path, sizeof(path));
if (r > 0) {
for (int j = 0; j < r; j++) {
char temp[4];
sprintf(temp, "%d.", path[j]);
strcat(port, temp);
}
port[strlen(port) - 1] = '\0'; // 移除末尾的点
printf("port: %s\n", port);
}
sprintf(usbNum,"{%x-%c}", libusb_get_bus_number(dev),port[0]);
str+=usbNum;
char minfo[128]={0};
sprintf(minfo,"{%s}{%s}{%04x}{%04x}", iProduct,iManufacturer,desc.idProduct,desc.idVendor);
str+=minfo;
char intf[128]={0};
sprintf(intf,"<%x-%s:%x.0@%02x>", libusb_get_bus_number(dev),port/* libusb_get_port_number(dev)*/,
desc.bNumConfigurations,desc.bDeviceClass);
str+=intf;
//desc.idVendor
usb_info info = {desc.idProduct,desc.idVendor,desc.bDeviceClass,str};
usbList.insert(map<unsigned short, usb_info>::value_type(desc.idVendor,info));
libusb_close(handle);
return str;
}
int hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{
struct libusb_device_descriptor desc;
(void)libusb_get_device_descriptor(dev, &desc);
//usbMonitor* usbptr = static_cast<usbMonitor*>(user_data);
map<unsigned short, usb_info>::iterator it = usbList.find(desc.idVendor);
int flag = 0;
std::string info;
if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)
{
flag = 1;
if(it != usbList.end())
{
printf("设备已插入:%s\n",it->second.msg.c_str());
info = it->second.msg.c_str();
}
else
{
libusb_device **devs;
ssize_t cnt;
LibusbContext ctx;
cnt = libusb_get_device_list(ctx.get(), &devs);//USB设备列表
if(cnt < 0) {
printf("Get Device Error\n");
return 0;
}
for(ssize_t i = 0; i < cnt; i++) {
if(libusb_get_bus_number(dev) == libusb_get_bus_number(devs[i]) &&
libusb_get_device_address(dev) == libusb_get_device_address(devs[i]))
{
info = get_device(devs[i]);
if(info.empty())return 0;
printf("设备已插入:%s\n",info.c_str());
it = usbList.find(desc.idVendor);
break;
}
}
libusb_free_device_list(devs, 1);
}
}
else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
{
flag = 2;
if(it == usbList.end())
{
printf("已拔出\n");
return 0;
}
else
{
info = it->second.msg;
usbList.erase(it);
printf("设备已拔出:%s\n",info.c_str());
}
}
printf("type:%02x\n",it->second.bDeviceClass);
return 0;
}
void startMonitor()
{
if(libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) == 0)//检查当前运行的libusb库是否支持热插拔功能的函数调用
{
printf("libusb不支持热插拔\n");
}
LibusbContext ctx;
if (!ctx.get()) {
printf("Failed to initialize libusb\n");
return ;
}
libusb_hotplug_register_callback(ctx.get(), (libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED|LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) ,
LIBUSB_HOTPLUG_NO_FLAGS, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY,
LIBUSB_HOTPLUG_MATCH_ANY, (libusb_hotplug_callback_fn)hotplug_callback, NULL,NULL);
// 主循环
int result;
bool running = true;
while (running)
{
timeval tv = {0, 1000}; // 设置超时时间为1000毫秒
result = libusb_handle_events_timeout_completed(ctx.get(), &tv, NULL);
}
return ;
}
int main1() {
const struct libusb_version *version;
version = libusb_get_version();
std::cout << "libusb version: " << version->major << "." << version->minor << "." << version->micro << std::endl;
startMonitor();
return 0;
}