|
From: <IC-...@t-...> - 2006-09-04 09:22:46
|
Hello,
>From: Dan Ellis <de...@ne...>
>
>kosel wrote:
>>
>> Hello,
>>
>>
>> is there a recommended way for disconnect detection for applications using
>> libusb?
>> In the past I terminated my application if data transfer from device
>> failed.
>> But this also hapens during start and end of suspend.
>> And for certification reasons, the application must not terminate during
>> suspend.
>>
>What certification problems are caused by your application terminating
>during suspend? Surely as long as it picks up again upon resume then it
>should be OK.
USB-IF certification demands that host enters S1 suspend while application
is active.
After the host resumes, the application must continue without error.
My application is a simple shell application, as I wrote it for Linux.
So the application does not listen for Windows powermanagement messages.
So the application could not distinguish if errocode -5 from usb_bulk_read
is caused by a device disconnect or a device suspend.
I have just tried the following:
After usb_bulk_read returns a errorcode < 0, the application releases the
interface and closes the device.
Then the application searches in a loop for the device to become available
again.
It seems, that this prevents the host (XP SP2) to wake up my device after S1
resume!
I am also not sure, if allways all the certified USB 2.0 hubs have received a
resume.
My loop:
#ifdef unix
// see ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1031/dnucmg/html/UCMGch09.htm
#include <time.h>
#define SECONDS 1 // unix measures time in sleep in seconds
#else
#include <windows.h>
#define SECONDS 1000 // microsoft sleep uses milliseconds
#define sleep(x) Sleep(x*SECONDS)
#endif
while(!udev) {
udev = getUsbStepcounter(devicenumber);
fflush(stderr);
if(!udev) {
printf("Waiting for device %d to reconnect\n",
devicenumber);
fflush(stdout); // flush iobuffers before
// sleepling
sleep(1);
}
}
the getDevice function:
usb_dev_handle* getUsbStepcounter(const unsigned char n) {
// Returns a handle to the n-th USB Stepcounter,
// or a NULL pointer if the n-th device doesn't exits.
struct usb_bus *bus;
struct usb_device *dev;
unsigned char i = 0;
usb_dev_handle* udev = NULL;
int errcode;
usb_find_busses();
usb_find_devices();
#ifdef DEBUG
fprintf(stderr,"Searching for %d device with vid %04X and pid
%04X\n",
n,STEPCOUNTER_VENDOR_ID,STEPCOUNTER_PRODUCT_ID);
#endif
for (bus = usb_get_busses(); bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
#ifdef DEBUG
fprintf(stderr,"%s/%s %04X/%04X\n", bus->dirname,
dev->filename,
dev->descriptor.idVendor,
dev->descriptor.idProduct);
#endif
if( dev->descriptor.idVendor == STEPCOUNTER_VENDOR_ID
&& dev->descriptor.idProduct ==
STEPCOUNTER_PRODUCT_ID) {
// Vendorid and Productid match
// now compare endpoints etc
if(dev->config[0].bNumInterfaces != 1) {
#ifdef DEBUG
fprintf(stderr,"bNumInterfaces =
%d\n",dev->config[0].bNumInterfaces);
#endif
} else if
(dev->config[0].interface[0].altsetting[0].endpoint[0].bEndpointAddress !=
POSITION_ENDPOINT ) {
#ifdef DEBUG
fprintf(stderr,"config[0].interface[0].altsetting[0].endpoint[0].bEndpointAddres
s = %02xh\n",
dev->config[0].interface[0].altsetting[0].endpoint[0].bEndpointAddress);
#endif
} else if
(dev->config[0].interface[0].altsetting[0].endpoint[1].bEndpointAddress !=
CONFIG_ENDPOINT ) {
#ifdef DEBUG
fprintf(stderr,"config[0].interface[0].altsetting[0].endpoint[1].bEndpointAddres
s = %02xh\n",
dev->config[0].interface[0].altsetting[0].endpoint[1].bEndpointAddress);
#endif
} else {
i++;
}
#ifdef DEBUG
fprintf(stderr,"Found USB Stepcounter %d\n",i);
#endif
usb_dev_handle* getUsbStepcounter(const unsigned char n) {
// Returns a handle to the n-th USB Stepcounter,
// or a NULL pointer if the n-th device doesn't exits.
struct usb_bus *bus;
struct usb_device *dev;
unsigned char i = 0;
usb_dev_handle* udev = NULL;
int errcode;
usb_find_busses();
usb_find_devices();
#ifdef DEBUG
fprintf(stderr,"Searching for %d device with vid %04X and pid
%04X\n",
n,STEPCOUNTER_VENDOR_ID,STEPCOUNTER_PRODUCT_ID);
#endif
for (bus = usb_get_busses(); bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
#ifdef DEBUG
fprintf(stderr,"%s/%s %04X/%04X\n", bus->dirname,
dev->filename,
dev->descriptor.idVendor,
dev->descriptor.idProduct);
#endif
if( dev->descriptor.idVendor == STEPCOUNTER_VENDOR_ID
&& dev->descriptor.idProduct ==
STEPCOUNTER_PRODUCT_ID) {
// Vendorid and Productid match
// now compare endpoints etc
if(dev->config[0].bNumInterfaces != 1) {
#ifdef DEBUG
fprintf(stderr,"bNumInterfaces =
%d\n",dev->config[0].bNumInterfaces);
#endif
} else if
(dev->config[0].interface[0].altsetting[0].endpoint[0].bEndpointAddress !=
POSITION_ENDPOINT ) {
#ifdef DEBUG
fprintf(stderr,"config[0].interface[0].altsetting[0].endpoint[0].bEndpointAddres
s = %02xh\n",
dev->config[0].interface[0].altsetting[0].endpoint[0].bEndpointAddress);
#endif
} else if
(dev->config[0].interface[0].altsetting[0].endpoint[1].bEndpointAddress !=
CONFIG_ENDPOINT ) {
#ifdef DEBUG
fprintf(stderr,"config[0].interface[0].altsetting[0].endpoint[1].bEndpointAddres
s = %02xh\n",
dev->config[0].interface[0].altsetting[0].endpoint[1].bEndpointAddress);
#endif
} else {
i++;
}
#ifdef DEBUG
fprintf(stderr,"Found USB Stepcounter %d\n",i);
#endif
if(i==n) {
// the n-th USB Stepcounter is found
udev = usb_open(dev);
if(!udev) {
fprintf(stderr,"Can't open
device");
return NULL;
}
errcode = usb_set_configuration(udev,1);
if(errcode) {
#ifdef DEBUG
fprintf(stderr,"Failed to set
USB Stepcounter 1 configuration 1\n");
reportError(errcode);
#endif
usb_close(udev);
udev = NULL;
return NULL;
}
errcode = usb_claim_interface(udev,0);
if(errcode) {
#ifdef DEBUG
fprintf(stderr,"Failed to get
USB Stepcounter 1, interface 0\n");
if(errcode<0)
reportError(-errcode);
#endif
usb_close(udev);
udev = NULL;
}
return udev;
}
}
}
}
return NULL;
}
Have I done anything wrong with my code,
what keeps the USB system from resuming devices?
Greetings
Juergen
|