我正在开发一种RNDIS复合设备,其中包括RNDIS设备,usbnet设备,调制解调器设备和自定义CDC设备。
PC正在运行Win7 32位,我正在使用默认的RNDIS驱动程序。 当我只使用RNDIS设备回答Windows枚举时,一切正常。 但是当我将所有4个设备组合成描述符作为复合设备时,Windows仍然正确枚举,其他3个设备工作正常,但RNDIS设备遇到“无法启动错误代码10”问题。
我使用USB分析仪追踪USB数据流,发现 Windows RNDIS驱动程序在“设置配置”后没有发送RNDIS初始化消息。
复合设备描述符已发布:
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
答案 0 :(得分:4)
让我回答我自己的问题,我已经找到了这个问题:
RNDIS IAD接口必须是复合设备的第一个和第二个。 虽然问题已经解决,但它仍然让我感到困惑。
希望本说明能帮助其他人遇到类似的问题。
答案 1 :(得分:0)
对于那些遇到过这个帖子的人来说,因为你在使用内置的configfs libcomposite设备时遇到了与RNDIS和windows code 10错误类似的问题,经过大量的谷歌搜索,并在互联网上查找代码, libcomposite模块中的代码.....我发现如果我强制在libcomposite模块之后直接加载usb_f_rndis模块,而不是修补驱动程序,我可以解决这个问题,这会强制usb_f_rndis到第一个和第二个iad插槽。当您在configfs中添加设备时,将加载libcomposite设备的其余模块,Windows将对此感到满意。
另外,要强制窗口加载正确的驱动程序,请确保设置os_desc内容。这里有一个很好的指南:http://irq5.io/2016/12/22/raspberry-pi-zero-as-multiple-usb-gadgets/