20 #include "../../gsmstate.h"    21 #if defined(GSM_ENABLE_DKU2PHONET) && defined(GSM_ENABLE_USBDEVICE)    24 #include "../../gsmcomon.h"    26 #include "../../../helper/string.h"    31 #define NOKIA_VENDOR_ID 0x0421    36 #define USB_CDC_CLASS           0x02    40 #define USB_CDC_FBUS_SUBCLASS       0xfe    45 struct cdc_union_desc {
    47     u_int8_t      bDescriptorType;
    48     u_int8_t      bDescriptorSubType;
    50     u_int8_t      bMasterInterface0;
    51     u_int8_t      bSlaveInterface0;
    52 } __attribute__ ((packed));
    54 struct cdc_extra_desc {
    56     u_int8_t      bDescriptorType;
    57     u_int8_t      bDescriptorSubType;
    58 } __attribute__ ((packed));
    61 #define CDC_HEADER_TYPE         0x00    62 #define CDC_UNION_TYPE          0x06    63 #define CDC_FBUS_TYPE           0x15    66 #define USB_DT_CS_INTERFACE     0x24    80                 case LIBUSB_ERROR_INVALID_PARAM:
    84                 case LIBUSB_ERROR_ACCESS:
    85                         smprintf(s, 
"Access denied (insufficient permissions)\n");
    88                 case LIBUSB_ERROR_NO_DEVICE:
    89                         smprintf(s, 
"No such device (it may have been disconnected)\n");
    92                 case LIBUSB_ERROR_NOT_FOUND:
    96                 case LIBUSB_ERROR_BUSY:
   100                 case LIBUSB_ERROR_TIMEOUT:
   101                         smprintf(s, 
"Operation timed out\n");
   104                 case LIBUSB_ERROR_OVERFLOW:
   108                 case LIBUSB_ERROR_PIPE:
   112                 case LIBUSB_ERROR_INTERRUPTED:
   113                         smprintf(s, 
"System call interrupted (perhaps due to signal)\n");
   116                 case LIBUSB_ERROR_NO_MEM:
   117                         smprintf(s, 
"Insufficient memory\n");
   120                 case LIBUSB_ERROR_NOT_SUPPORTED:
   121                         smprintf(s, 
"Operation not supported or unimplemented on this platform\n");
   124                 case LIBUSB_ERROR_OTHER:
   154         if (*serial != NULL) {
   155                 while (isspace(**serial) && **serial != 0) {
   156                         *serial = *serial + 1;
   158                 smprintf(s, 
"Will search for serial = %s\n", *serial);
   167         if (*endptr == 
'x') {
   172                 smprintf(s, 
"Will search for deviceid = %d\n", *deviceid);
   175         if (*endptr == 
':') {
   178                 num = strtol(next, &endptr, 10);
   179                 if (*endptr == 
'x') {
   180                         num = strtol(next, &endptr, 16);
   183                 smprintf(s, 
"Will search for vendor = 0x%04x, deviceid = 0x%04x\n", *vendor, *product);
   190         if (*endptr == 
'.') {
   193                 num = strtol(next, &endptr, 10);
   194                 if (*endptr == 
'x') {
   195                         num = strtol(next, &endptr, 16);
   198                 smprintf(s, 
"Will search for bus = %d, deviceid = %d\n", *bus, *deviceid);
   216         struct libusb_device_descriptor desc;
   217         struct libusb_config_descriptor *config;
   219         int vendor = -1, product = -1, bus = -1, deviceid = -1;
   225         GSM_USB_ParseDevice(s, &vendor, &product, &bus, &deviceid, &serial);
   226         do_match = (vendor != -1 || product != -1 || bus != -1 || deviceid != -1 || serial != NULL);
   228         cnt = libusb_get_device_list(d->
context, &devs);
   230                 smprintf(s, 
"Failed to list USB devices (%d)!\n", (
int)cnt);
   231                 return GSM_USB_Error(s, cnt);
   236         while ((dev = devs[i++]) != NULL) {
   237                 rc = libusb_get_device_descriptor(dev, &desc);
   239                         smprintf(s, 
"Failed to get device descriptor (%d)!\n", rc);
   240                         GSM_USB_Error(s, rc);
   244                 smprintf(s, 
"Checking %04x:%04x (bus %d, device %d)\n",
   245                         desc.idVendor, desc.idProduct,
   246                         libusb_get_bus_number(dev), libusb_get_device_address(dev));
   249                         if (vendor != -1 && vendor != desc.idVendor) {
   250                                 smprintf(s, 
"Vendor does not match requested 0x%04x, ignoring\n", vendor);
   253                         if (product != -1 && product != desc.idProduct) {
   254                                 smprintf(s, 
"Product does not match requested 0x%04x, ignoring\n", product);
   257                         if (bus != -1 && bus != libusb_get_bus_number(dev)) {
   258                                 smprintf(s, 
"Bus does not match requested %d, ignoring\n", bus);
   261                         if (deviceid != -1 && deviceid != libusb_get_device_address(dev)) {
   262                                 smprintf(s, 
"Device address does not match requested %d, ignoring\n", deviceid);
   265                         if (serial != NULL && desc.iSerialNumber) {
   266                                 rc = libusb_open(dev, &d->
handle);
   268                                         smprintf(s, 
"Failed to read serial!\n");
   270                                         libusb_get_string_descriptor_ascii(d->
handle, desc.iSerialNumber, buffer, 
sizeof(buffer) - 1);
   271                                         smprintf(s, 
"Device serial: %s\n", buffer);
   273                                         if (strcasecmp(buffer, serial) != 0) {
   274                                                 smprintf(s, 
"Device serial does not match requested %s, ignoring\n", serial);
   281                 if (matcher(s, dev, &desc)) {
   291         smprintf(s, 
"Trying to open device, config=%d, c_iface=%d, c_alt=%d, d_iface=%d, d_alt=%d\n",
   294         rc = libusb_open(dev, &d->
handle);
   297                 error = GSM_USB_Error(s, rc);
   302         rc = libusb_get_active_config_descriptor(dev, &config);
   304                 smprintf(s, 
"Failed to get current device configuration!\n");
   307                 error = GSM_USB_Error(s, rc);
   313                 smprintf(s, 
"Will change configuration, unhooking all interfaces!\n");
   314                 for (i = 0; i < config->bNumInterfaces; i++) {
   315                         if (libusb_kernel_driver_active(d->
handle, i) == 1) {
   316                                 smprintf(s, 
"Detaching kernel driver from interface %d\n", i);
   317                                 rc = libusb_detach_kernel_driver(d->
handle, i);
   319                                         smprintf(s, 
"Failed to detach kernel driver!\n");
   320                                         libusb_free_config_descriptor(config);
   323                                         error = GSM_USB_Error(s, rc);
   330                 smprintf(s, 
"Configuring USB device...\n");
   334                         libusb_free_config_descriptor(config);
   337                         error = GSM_USB_Error(s, rc);
   341                 smprintf(s, 
"Configuration change not required, unhooking only required interfaces!\n");
   347                                 smprintf(s, 
"Failed to detach kernel driver!\n");
   348                                 libusb_free_config_descriptor(config);
   351                                 error = GSM_USB_Error(s, rc);
   360                                 smprintf(s, 
"Failed to detach kernel driver!\n");
   361                                 libusb_free_config_descriptor(config);
   364                                 error = GSM_USB_Error(s, rc);
   369         libusb_free_config_descriptor(config);
   371         smprintf(s, 
"Claiming USB control interface...\n");
   377                 error = GSM_USB_Error(s, rc);
   381         smprintf(s, 
"Configuring USB control interface...\n");
   387                 error = GSM_USB_Error(s, rc);
   391         smprintf(s, 
"Claiming USB data interface...\n");
   397                 error = GSM_USB_Error(s, rc);
   401         smprintf(s, 
"Configuring USB data interface...\n");
   407                 error = GSM_USB_Error(s, rc);
   429                 smprintf(s, 
"Failed to init libusb (%d)!\n", rc);
   430                 return GSM_USB_Error(s, rc);
   444                         smprintf(s, 
"Failed to set idle settings\n");
   445                         return GSM_USB_Error(s, rc);
   449                         smprintf(s, 
"Failed to release control interface\n");
   450                         return GSM_USB_Error(s, rc);
   454                         smprintf(s, 
"Failed to release data interface\n");
   455                         return GSM_USB_Error(s, rc);
   471         int rc = LIBUSB_ERROR_TIMEOUT, ret = 0, repeat = 0;
   473         while (repeat < 10 && (rc == LIBUSB_ERROR_TIMEOUT || rc == LIBUSB_ERROR_INTERRUPTED || rc == LIBUSB_ERROR_OTHER || rc == LIBUSB_ERROR_NO_MEM)) {
   474                 rc = libusb_bulk_transfer(d->
handle, d->
ep_read, buf, nbytes, &ret, 1000);
   476                 if (rc == LIBUSB_ERROR_OTHER && ret != 0) {
   477                         smprintf(s, 
"Other error while reading, but got some data\n");
   481                 if (rc == LIBUSB_ERROR_TIMEOUT && ret != 0) {
   482                         smprintf(s, 
"Timeout while reading, but got some data\n");
   487                         smprintf(s, 
"Failed to read from usb (%d)!\n", rc);
   488                         GSM_USB_Error(s, rc);
   502         int rc = LIBUSB_ERROR_TIMEOUT, ret = 0, repeat = 0;
   504         while (repeat < 10 && (rc == LIBUSB_ERROR_TIMEOUT || rc == LIBUSB_ERROR_INTERRUPTED || rc == LIBUSB_ERROR_OTHER || rc == LIBUSB_ERROR_NO_MEM)) {
   505                 rc = libusb_bulk_transfer(d->
handle, d->
ep_write, (
void *)buf, nbytes, &ret, 1000);
   507                 if (rc == LIBUSB_ERROR_OTHER && ret != 0) {
   508                         smprintf(s, 
"Other error while writing, but got some data\n");
   512                 if (rc == LIBUSB_ERROR_TIMEOUT && ret != 0) {
   513                         smprintf(s, 
"Timeout while write, but some data were written\n");
   518                         smprintf(s, 
"Failed to write to usb (%d)!\n", rc);
   519                         GSM_USB_Error(s, rc);
   537         struct libusb_config_descriptor *config;
   539         const unsigned char *buffer;
   541         struct cdc_extra_desc *extra_desc;
   542         struct cdc_union_desc *union_desc = NULL;
   543         const struct libusb_endpoint_descriptor *ep1, *ep2;
   546         if (desc->idVendor != NOKIA_VENDOR_ID) 
return FALSE;
   549         for (c = 0; c < desc->bNumConfigurations; c++) {
   550                 rc = libusb_get_config_descriptor(dev, c, &config);
   552                         GSM_USB_Error(s, rc);
   556                 for (i = 0; i < config->bNumInterfaces; i++) {
   557                         for (a = 0; a < config->interface[i].num_altsetting; a++) {
   559                                 if (config->interface[i].altsetting[a].bInterfaceClass == USB_CDC_CLASS
   560                                                 && config->interface[i].altsetting[a].bInterfaceSubClass == USB_CDC_FBUS_SUBCLASS
   567                 libusb_free_config_descriptor(config);
   575         d->
control_iface = config->interface[i].altsetting[a].bInterfaceNumber;
   581         buffer = config->interface[i].altsetting[a].extra;
   582         buflen = config->interface[i].altsetting[a].extra_length;
   586                 extra_desc = (
struct cdc_extra_desc *)buffer; 
   587                 if (extra_desc->bDescriptorType != USB_DT_CS_INTERFACE) {
   588                         smprintf(s, 
"Extra CDC header: %d\n", extra_desc->bDescriptorType);
   592                 switch (extra_desc->bDescriptorSubType) {
   594                                 union_desc = (
struct cdc_union_desc *)buffer;
   596                         case CDC_HEADER_TYPE:
   601                                 smprintf(s, 
"Extra CDC subheader: %d\n", extra_desc->bDescriptorSubType);
   605                 buflen -= extra_desc->bLength;
   606                 buffer += extra_desc->bLength;
   609         if (union_desc == NULL) {
   610                 smprintf(s, 
"Failed to find data end points!\n");
   611                 libusb_free_config_descriptor(config);
   619         for (i = 0; i < config->bNumInterfaces; i++) {
   620                 for (a = 0; a < config->interface[i].num_altsetting; a++) {
   622                         if (config->interface[i].altsetting[a].bInterfaceNumber == d->
data_iface) {
   624                                 if (config->interface[i].altsetting[a].bNumEndpoints == 2) {
   626                                         ep1 = &(config->interface[i].altsetting[a].endpoint[0]);
   627                                         ep2 = &(config->interface[i].altsetting[a].endpoint[1]);
   628                                         if ((ep1->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) != LIBUSB_TRANSFER_TYPE_BULK ||
   629                                                 (ep2->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) != LIBUSB_TRANSFER_TYPE_BULK) {
   633                                         if ((ep1->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN &&
   634                                                 (ep2->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) {
   635                                                 d->
ep_read = ep1->bEndpointAddress;
   636                                                 d->
ep_write = ep2->bEndpointAddress;
   637                                         } 
else  if ((ep2->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN &&
   638                                                 (ep1->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) {
   639                                                 d->
ep_read = ep2->bEndpointAddress;
   640                                                 d->
ep_write = ep1->bEndpointAddress;
   644                                         d->
data_altsetting = config->interface[i].altsetting[a].bAlternateSetting;
   645                                 } 
else if (config->interface[i].altsetting[a].bNumEndpoints == 0) {
   654                 libusb_free_config_descriptor(config);
   659         libusb_free_config_descriptor(config);
   667         error = GSM_USB_Init(s);
   668         if (error != 
ERR_NONE) 
return error;
   670         error = GSM_USB_Probe(s, FBUSUSB_Match);
   671         if (error != 
ERR_NONE) 
return error;
 
GSM_Config * CurrentConfig
 
union GSM_Device::@0 Data
 
gboolean(* GSM_USB_Match_Function)(GSM_StateMachine *s, libusb_device *dev, struct_libusb_device_descriptor *desc)
 
libusb_device_handle * handle
 
int smprintf(GSM_StateMachine *s, const char *format,...)