Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RNDIS "Composite device" cannot start

Tags:

driver

usb

rndis

I am developing a RNDIS composite device which includes a RNDIS device, a usbnet device ,a modem device and a self-defined CDC device.

The PC is running Win7 32bit, and I am using the default RNDIS driver. When I answers the Windows enumeration with only RNDIS device, everything works fine. But when I compose all 4 device into the descriptor as composite device, Windows still enumerates correctly and the other 3 devices works fine, but RNDIS device encounters with "cannot start error code 10" issue.

I traced the USB data flow with a USB analyzer, found that Windows RNDIS driver did not send RNDIS initialize messages after “Set Configuration”.

The composite device descriptor is as posted:

         devDesc[0]  = 0x12; //  bLength             - Descriptor length
         devDesc[1]  = 0x01; //  bDescriptorType     - Descriptor  Type
         devDesc[2]  = bcdUSB_LSB; //  bcdUSB (LSB)        - Device Compliant to USB specification ..
         devDesc[3]  = bcdUSB_MSB; //  bcdUSB (MSB)
         devDesc[4]  = 0x00; //  bDeviceClass        - class of the device
         devDesc[5]  = 0x00; //  bDeviceSubClass     - subclass of the device
         devDesc[6]  = 0x00; //  bDeviceProtocol     - protocol of the device
         devDesc[7]  = bEp0MaxPacketSize; //  bMaxPacketSize0     - Max Packet Size for EP zero
         devDesc[8]  = 0x86; //  idVendor (LSB)      - Vendor ID
         devDesc[9]  = 0x12; //  idVendor (MSB)
         devDesc[10] = 0x0E; //  idProduct (LSB)     - Product ID
         devDesc[11] = 0x81; //  idProduct (MSB)
         devDesc[12] = 0x02; //  bcdDevice (LSB)     - The device release number
         devDesc[13] = 0x00; //  bcdDevice (MSB)
         devDesc[14] = 0x01; //  iManufacturer       - Index of string descriptor describing Manufacturer
         devDesc[15] = 0x03; //  iProduct            - Index of string descriptor describing Product
         devDesc[16] = 0x04; //  iSerialNumber       - Index of string descriptor describing Serial number
         devDesc[17] = 0x01; //  bNumConfigurations  - Number of configurations

         //Configuration Descriptor
         configDesc[0]  = 0x09; // bLength               - Descriptor length
         configDesc[1]  = 0x02; // bDescriptorType       - Descriptor Type
         configDesc[2]  = 177;   // wTotalLength (LSB)   - Total Data length for the configuration,
         configDesc[3]  = 0x00; // wTotalLength (MSB)    - includes all descriptors for this configuration
         configDesc[4]  = 0x05; // bNumInterfaces        - Number of interfaces this configuration supports
         configDesc[5]  = 0x01; // bConfigurationValue   - The Value that should be used to select this configuration
         configDesc[6]  = 0x00; // iConfiguration        - Index of string descriptor describing this configuration
         configDesc[7]  = 0xC0; // bmAttributes          - bit6: Self-Powered, bit5: RemoteWakeup
         configDesc[8]  = 0xfa; // MaxPower              - Maximum power consumption for this configuration (mA)


         //Interface Descriptor 0 usbnet
         configDesc[9]  = 0x09; // bLength               - Descriptor length
         configDesc[10] = 0x04; // bDescriptorType       - Descriptor Type
         configDesc[11] = 0x00; // bInterfaceNumber      - Index (Number) of this interfaces
         configDesc[12] = 0x00; // bAlternateSetting     - The value to select alternate setting of this interface
         configDesc[13] = 0x03; // bNumEndpoints         - Number endpoints  used by this interface
         configDesc[14] = 0xff; // bInterfaceClass       - Class of this Interface
         configDesc[15] = 0xff; // bInterfaceSubClass    - Sub class of this Interface
         configDesc[16] = 0x00; // bInterfaceProtocol    - Protocol of this Interface
         configDesc[17] = 0x05; // iInterface            - Index of string descriptor describing this Interface


         // usbnet Endpoint Descriptor
         configDesc[18] = 0x07; // bLength               - Descriptor length
         configDesc[19] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[20] = 0x85; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[21] = 0x03; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[22] = 0x0F; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[23] = 0x00; // wMaxPacketSize (MSB)
         configDesc[24] = bInterval; // bInterval                - Polling Interval (ms)

         configDesc[25] = 0x07; // bLength               - Descriptor length
         configDesc[26] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[27] = 0x81; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[28] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[29] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[30] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[31] = 0x00; // bInterval             - Polling Interval (ms)

         configDesc[32] = 0x07; // bLength               - Descriptor length
         configDesc[33] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[34] = 0x02; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[35] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[36] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[37] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[38] = 0x00; // bInterval             - Polling Interval (ms)

         //Interface descriptor 1 ICAT
         configDesc[39] = 0x09; // bLength               - Descriptor length
         configDesc[40] = 0x04; // bDescriptorType       - Descriptor Type
         configDesc[41] = 0x01; // bInterfaceNumber      - Index (Number) of this interfaces
         configDesc[42] = 0x00; // bAlternateSetting     - The value to select alternate setting of this interface
         configDesc[43] = 0x02; // bNumEndpoints         - Number endpoints  used by this interface
         configDesc[44] = 0xFF; // bInterfaceClass       - Class of this Interface
         configDesc[45] = 0x00; // bInterfaceSubClass    - Sub class of this Interface
         configDesc[46] = 0x00; // bInterfaceProtocol    - Protocol of this Interface
         configDesc[47] = 0x00; // iInterface            - Index of string descriptor describing this Interface

         //ICAT endpoints
         configDesc[48] = 0x07; // bLength               - Descriptor length
         configDesc[49] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[50] = 0x87; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[51] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[52] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[53] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[54] = 0x00; // bInterval             - Polling Interval (ms)

         configDesc[55] = 0x07; // bLength               - Descriptor length
         configDesc[56] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[57] = 0x08; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[58] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[59] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[60] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[61] = 0x00; // bInterval             - Polling Interval (ms)

         //Modem class specific descriptors
         configDesc[62]  = 0x09; // bLength              - Descriptor length
         configDesc[63] = 0x04; // bDescriptorType       - Descriptor Type
         configDesc[64] = 0x02; // bInterfaceNumber      - Index (Number) of this interfaces
         configDesc[65] = 0x00; // bAlternateSetting     - The value to select alternate setting of this interface
         configDesc[66] = 0x03; // bNumEndpoints         - Number endpoints  used by this interface
         configDesc[67] = 0x02; // bInterfaceClass       - Class of this Interface
         configDesc[68] = 0x02; // bInterfaceSubClass    - Sub class of this Interface
         configDesc[69] = 0x01; // bInterfaceProtocol    - Protocol of this Interface
         configDesc[70] = 0x00; // iInterface            - Index of string descriptor describing this Interface

         configDesc[71] = 0x05; // descriptor length Comms Class CS_INTERFACE 'Functional Descriptors' Triplet
         configDesc[72] = 0x24; // descriptor type
         configDesc[73] = 0x00; // subtype = header
         configDesc[74] = 0x10; // BCD
         configDesc[75] = 0x01; //

         configDesc[76] = 0x05; // 2. descriptor length - Call Manangement Func Desc
         configDesc[77] = 0x24; // descriptor type
         configDesc[78] = 0x01; // subtype = Call management
         configDesc[79] = 0x00; //bmcapabilities; MS driver usbser.sys seems to ignore this bit and sends AT over the data,interface anyway
         configDesc[80] = 0x01; // Interface number of data class interface

         configDesc[81] = 0x04; // 3.descriptor length  Abstract Control Func Desc
         configDesc[82] = 0x24; // descriptor type
         configDesc[83] = 0x02; // subtype = Abstract CM
         configDesc[84] = 0x00; // bmcapabilities 

         configDesc[85] = 0x05; // Size of descriptor. Number of interfaces plus 3 bytes of header
         configDesc[86] = 0x24; // 0x24 - CS_INTERFACE
         configDesc[87] = 0x06; // 0x06 - See table 25 of document "USB Class definitions for Comms Devices"
         configDesc[88] = 0x00;
         configDesc[89] = 0x01;

         //Endpoint Descriptors MODEM
         configDesc[90] = 0x07; // bLength               - Descriptor length
         configDesc[91] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[92] = 0x86; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[93] = 0x03; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[94] = 0x0F; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[95] = 0x00; // wMaxPacketSize (MSB)
         configDesc[96] = bInterval; // bInterval                - Polling Interval (ms)

         configDesc[97] = 0x07; // bLength               - Descriptor length
         configDesc[98] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[99] = 0x83; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[100] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[101] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[102] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[103] = 0x00; // bInterval                - Polling Interval (ms)

         configDesc[104] = 0x07; // bLength              - Descriptor length
         configDesc[105] = 0x05; // bDescriptorType      - Descriptor Type
         configDesc[106] = 0x04; // bEndpointAddress     - Endpoint Address & Direction
         configDesc[107] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[108] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[109] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[110] = 0x00; // bInterval                - Polling Interval (ms)


        //rndis IAD
        configDesc[111] = 0x08; // bLength
        configDesc[112] = 0x0b; // INTERFACE ASSOCIATION DESCRIPTOR bDescriptorType
        configDesc[113] = 0x03; // bFirstInterface
        configDesc[114] = 0x02; // bInterfaceCount
        configDesc[115] = 0x02; // bFunctionClass
        configDesc[116] = 0x02; // bFunctionSubClass
        configDesc[117] = 0xFF; // bFunctionProtocol
        configDesc[118] = 0x03; // Index of string descriptor describing this function

        //rndis comm interface
        configDesc[119] = 0x09; // bLength             - Descriptor length
        configDesc[120] = 0x04; // bDescriptorType     - Descriptor Type
        configDesc[121] = 0x03; //bInterfaceNumber     - for RNDIS
        configDesc[122] = 0x00; // bAlt
        configDesc[123] = 0x01; // bNumEnd
        configDesc[124] = 0x02; //bInterfaceClass
        configDesc[125] = 0x02; // bInterfaceSubclass
        configDesc[126] = 0xFF; // bInterfaceprotocol
        configDesc[127] = 0x00; // iInterface  +++++++++++++++++++++++++++++++++++++need modified


        // Class specified descriptor

        configDesc[128] = 0x05; //
        configDesc[129] = 0x24; // bDescriptorType
        configDesc[130] = 0x00; //bDescriptorSubtype
        configDesc[131] = 0x10; // BCD
        configDesc[132] = 0x01; //

        configDesc[133] = 0x05; //
        configDesc[134] = 0x24; // bDescriptorType
        configDesc[135] = 0x01; // bDescriptorSubtype
        configDesc[136] = 0x00; // bmCapabilities
        configDesc[137] = 0x04; //bDataInterface

        configDesc[138] = 0x04; //
        configDesc[139] = 0x24; // bDescriptorType
        configDesc[140] = 0x02; // bDescriptorSubtype
        configDesc[141] = 0x00; // bmCapabilities

        configDesc[142] = 0x05; //
        configDesc[143] = 0x24; // bDescriptorType
        configDesc[144] = 0x06; // bDescriptorSubtype
        configDesc[145] = 0x03; // bControlInterface
        configDesc[146] = 0x04; // bsubordinateInterface

        //Interrupt In endpoint
        configDesc[147] = 0x07; //
        configDesc[148] = 0x05; //
        configDesc[149] = 0x8C; //bendpointAddress
        configDesc[150] = 0x03; //bmAttributes
        configDesc[151] = 0x08; // wMaxPacketSize
        configDesc[152] = 0x00; //
        configDesc[153] = 0x01; // bInterval

        //rndis data interface
        configDesc[154] = 0x09; // bLength             - Descriptor length
        configDesc[155] = 0x04; // bDescriptorType     - Descriptor Type
        configDesc[156] = 0x04; //bInterfaceNumber     --- for RNDIS
        configDesc[157] = 0x00; // bAlt
        configDesc[158] = 0x02; // NumEndpoints
        configDesc[159] = 0x0a; //bInterfaceClass
        configDesc[160] = 0x00; // bInterfaceSubclass
        configDesc[161] = 0x00; // bInterfaceprotocol
        configDesc[162] = 0x00; // iInterface  +++++++++++++++++++++++++++++++++++++need modified

        //Bulk In endpoint
        configDesc[163] = 0x07; //
        configDesc[164] = 0x05; //
        configDesc[165] = 0x8E; //bendpointAddress
        configDesc[166] = 0x02; //bmAttributes
        configDesc[167] = 0x00; // wMaxPacketSize
        configDesc[168] = 0x02; //
        configDesc[169] = 0x00; // bInterval

        //Bulk Out endpoint
        configDesc[170] = 0x07; //
        configDesc[171] = 0x05; //
        configDesc[172] = 0x0D; //bendpointAddress
        configDesc[173] = 0x02; //bmAttributes
        configDesc[174] = 0x00; // wMaxPacketSize
        configDesc[175] = 0x02; //
        configDesc[176] = 0x00; // bInterva
like image 412
Mario Cao Avatar asked Aug 28 '12 06:08

Mario Cao


1 Answers

Let me answer my own question, I have figured out this issue:

The RNDIS IAD interface must be the first and second of the composite device. Although the problem is solved, it still puzzles me.

Hope this note will help others encountering similar issues.

like image 78
Mario Cao Avatar answered Oct 01 '22 17:10

Mario Cao