RNDIS Composite Device Cannot Start

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

Win7 32bit is running on the computer, and I use the default RNDIS driver. When I respond to a Windows enumeration with only an RNDIS device, everything works fine. But when I write all 4 devices to the descriptor as a composite device, Windows still lists correctly, and the other 3 devices work fine, but the RNDIS device encounters the problem "do not run error code 10".

I traced the USB data stream using a USB analyzer, found that the Windows RNDIS driver did not send RNDIS to initialize the messages after "Set Configuration".

Compound device descriptor published:

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 
+6
source share
2 answers

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

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

We hope this post helps others encounter similar issues.

+4
source

For those of you who are facing this thread because you are having similar problems with RNDIS and Windows 10 errors using the built-in configfs libcomposite device, after a ton of searching the Internet and sorting through the code on the Internet, the code in the libcomposite module .... I found that instead of fixing the driver, I could get around this if I forcefully loaded the usb_f_rndis module directly after the libcomposite module, this forces usb_f_rndis to use the first and second iad slots. The remaining modules for libcomposite devices will load when devices are added to configfs, and Windows will be happy with it.

In addition, to make the windows load the correct driver, make sure you configure the os_desc file. There is a good reference that talks about it here: http://irq5.io/2016/12/22/raspberry-pi-zero-as-multiple-usb-gadgets/

0
source

Source: https://habr.com/ru/post/923934/


All Articles