|
From: Robert R. <R.R...@Qu...> - 2021-09-21 23:35:18
|
I am running under Windows and check for my device when I get a
DBT_DEVICEARRIVAL event and check to see if it is gone when I get a
DBT_DEVICEREMOVECOMPLETE event.
The scenario is that I can open the device, do some transfers
(actually download firmware), then tell the device to boot. It
disconnects, and I release the interface and close it successfully.
When the firmware boots I get DBT_DEVICEARRIVAL event and look for my
device. I can get the device list and descriptors but when I find my
device and try to open I get this error.
LIBUSB_ERROR_NOT_SUPPORTED seems like a strange error code to get for
libusb_open. I have single stepped through it many times and it
seems right but I must be missing something.
DBT_DEVICEARRIVAL code:
vector<shared_ptr<SF_USB::USB_Dev_t>>
SF_USB::IsUnitAttached()
{
libusb_device** DevList_pp =
nullptr; /* Pointer List of all
detected devices */
struct libusb_device_descriptor
DevDescr; /* Device descriptor
structure */
libusb_device_handle* Handle =
nullptr; /* LibUSB Device
Handle */
vector<shared_ptr<USB_Dev_t>>
AttachedDevs; /* Smart-Fly Attached
Devices */
unsigned char
SN[24]; /* Buffer for
serial Number */
int Error = libusb_get_device_list(nullptr,
&DevList_pp); /* Get device list from LibUSB */
assert(0 <=
Error); /*
Make sure there is no Error */
libusb_device*
Dev_p; /*
Device from Device List */
uint DevIndex =
0; /* Device
list index */
while((Dev_p = DevList_pp[DevIndex]) !=
nullptr) /* Valid device pointer? */
{
/* Yes */
Error = libusb_get_device_descriptor(Dev_p,
&DevDescr); /* Get device descriptor for VID & PID */
assert(0 <=
Error); /* Make
sure there is no Error */
if(VENDOR_ID ==
DevDescr.idVendor) /* Device
match vendor ID? */
{
/* Yes, our device */
bool Found =
true; /* Found new
device flag */
Error = libusb_open(Dev_p,
&Handle); /* Open the device, get
device handle */
assert(0 <=
Error); /* Make sure
there is no Error */
uint8_t StrIdx =
DevDescr.iSerialNumber; /* Get Serial
Number Descriptor number */
int Chars = libusb_get_string_descriptor_ascii(Handle,
StrIdx, SN, /* Get Serial Number string */
SERIAL_NO_LEN);
assert(0 <=
Chars); /* Make sure
there is no Error */
libusb_close(Handle);
/* Close device */
for(auto OpenDev_p :
OpenDevs) /* Loop over list of
open devices */
{
if(DevDescr.idProduct ==
OpenDev_p->PID) /* Found device PID match Open
Device? */
{
/* Yes, check serial number */
if(reinterpret_cast<const char*>(SN) ==
OpenDev_p->SN) /* Serial Numbers match? */
{
/* Yes */
Found =
false; /* Device already
open */
break;
/* Leave Open Device loop */
}
}
}
if(Found)
/* New device Found? */
{
/* Yes */
Error = libusb_open(Dev_p,
&Handle); /* Open the device, get device handle */
assert(0 <=
Error); /* Make sure
there is no Error */
Error = libusb_claim_interface(Handle,
0); /* Claim device interface */
assert(0 <=
Error); /* Make sure
there is no Error */
shared_ptr<SF_USB::USB_Dev_t> USB_Open_p
= /* Make Shared Pointer to new USB_Dev_t */
make_shared<SF_USB::USB_Dev_t>();
*USB_Open_p = {Handle, VENDOR_ID,
DevDescr.idProduct, /* Intialize USB_Dev_t */
reinterpret_cast<const char*>(SN)};
OpenDevs.push_back(USB_Open_p);
/* Push back on Open Devices vector */
AttachedDevs.push_back(OpenDevs.back());
/* Save in Attached Devices vector */
}
}
DevIndex++;
/* Index next device pointer in list */
}
libusb_free_device_list(DevList_pp,
1); /* Free device list after
opening */
return
AttachedDevs;
/* Return Attached Devices vector */
}
DBT_DEVICEREMOVECOMPLETE code:
vector<shared_ptr<SF_USB::USB_Dev_t>>
SF_USB::IsUnitDetached()
{
libusb_device**
DevList_pp; /* List of
pointers to all detected devices */
struct libusb_device_descriptor
DevDescr; /* Device descriptor
structure */
libusb_device_handle*
Handle; /* Device
handle */
unsigned char
SN[24]; /* Buffer for
serial Number */
vector<shared_ptr<USB_Dev_t>>
DetachedDevs; /* Smart-Fly Detached
Devices */
int Error = libusb_get_device_list(nullptr,
&DevList_pp); /* Get device list from LibUSB */
assert(0 <=
Error); /*
Make sure there is no Error */
for(auto OpenDev_p = OpenDevs.begin(); OpenDev_p !=
OpenDevs.end();) /* Iterate over open devices */
{
bool Attached =
false; /* Device
still attached? */
libusb_device*
Dev_p; /* Device
from Device List */
uint DevIndex =
0; /* Device
list Index */
while((Dev_p = DevList_pp[DevIndex]) !=
nullptr) /* Valid device pointer? */
{
/* Yes */
Error = libusb_get_device_descriptor(Dev_p,
&DevDescr); /* Get device descriptor for VID & PID */
assert(0 <=
Error); /* Make sure
there is no Error */
if(VENDOR_ID ==
DevDescr.idVendor) /* Device match
vendor ID? */
{
/* Yes, our device */
if((*OpenDev_p)->PID ==
DevDescr.idProduct) /* Product ID
match? */
{
/* Yes, check Serial Number */
Error = libusb_open(Dev_p,
&Handle); /* Open device, get device handle */
assert(0 <=
Error); /* Make sure there is
no Error */
uint8_t StrIdx =
DevDescr.iSerialNumber; /* Get Serial Number
Descriptor number */
int Chars =
libusb_get_string_descriptor_ascii(Handle, /* Get Serial Number
string */
StrIdx,
SN, SERIAL_NO_LEN);
assert(0 <=
Chars); /* Make sure there is
no Error */
libusb_close(Handle);
/* Close device */
if(reinterpret_cast<const char*>(SN) ==
(*OpenDev_p)->SN) /* Serial Numbers match? */
{
/* Yes, our device */
Attached =
true; /* Device still
attached */
break;
/* Exit attached devices loop */
}
}
}
DevIndex++;
/* Index next device pointer in list */
}
if(!Attached)
/* Is device still attached? */
{
/* No */
DetachedDevs.push_back(*OpenDev_p);
/* Push on closed Devices */
OpenDev_p =
OpenDevs.erase(OpenDev_p); /* Erase item
from Open List */
}
else
{
OpenDev_p++;
}
}
libusb_free_device_list(DevList_pp,
1); /* Free device list after
opening */
for(auto DetachedDev :
DetachedDevs) /* Loop over
Closed devices */
{
libusb_device_handle* DevHandle =
DetachedDev->Handle; /* Get Closed Device's
Handle */
Error = libusb_release_interface(DevHandle,
0); /* Release Interface of detached dev */
assert(0 <=
Error); /* Make
sure there is no Error */
libusb_close(DevHandle);
/* Close the Device */
DetachedDev->Handle =
nullptr; /* Set device
pointer to NULL */
}
return
DetachedDevs;
/* Return success */
}
Thank you,
Robert Ritchey
Quest Engineering
Tempe, AZ
(480) 460-2652 |