RNDIS Составное устройство не может запуститься

Я разрабатываю составное устройство RNDIS, которое включает в себя устройство RNDIS, устройство usbnet, модемное устройство и самоопределяемое устройство CDC.

На ПК установлена ​​32-разрядная версия Win7, и я использую драйвер RNDIS по умолчанию. Когда я отвечаю на перечисление Windows только устройством RNDIS, все работает нормально. Но когда я включаю все 4 устройства в дескриптор как составное устройство, Windows по-прежнему правильно перечисляет, а остальные 3 устройства работают нормально, но устройство RNDIS сталкивается с проблемой «не удается запустить код ошибки 10».

Я проследил поток данных USB с помощью USB-анализатора и обнаружил, что драйвер Windows RNDIS не отправлял сообщения об инициализации RNDIS после «Set Configuration».

Дескриптор составного устройства выглядит следующим образом:

         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

person Mario Cao    schedule 28.08.2012    source источник


Ответы (2)


Позвольте мне ответить на мой собственный вопрос, я разобрался с этой проблемой:

Интерфейс RNDIS IAD должен быть первым и вторым составного устройства. Хотя проблема решена, она все еще озадачивает меня.

Надеюсь, что эта заметка поможет другим, столкнувшимся с подобными проблемами.

person Mario Cao    schedule 30.08.2012
comment
Каково было решение, на самом деле? :) Ты что-нибудь менял в линуксовом драйвере? (редактировать: я понял, что вы создали собственный составной файл. У меня проблема со стандартным устройством, которое также является составным, хотя только с RNDIS и CDC Ethernet. Оно также получает код 10 в Windows, хотя конфигурация RNDIS, вероятно, первое в составном дескрипторе - странно...) - person BjornW; 18.01.2016
comment
@mariocao, как ты это понял? Есть ли там какой-нибудь док? Спасибо - person rrosa; 09.08.2017
comment
FWIW, этот обходной путь упоминается в support.microsoft.com/en-us/help/2410682/ - person kcstrom; 06.10.2017

Для тех из вас, кто столкнулся с этой веткой, потому что у вас есть аналогичные проблемы с ошибками RNDIS и Windows Code 10, используя встроенное устройство configfs libcomposite, после тонны поиска в Google и просмотра кода в Интернете, код в модуль libcomposite..... Я обнаружил, что вместо исправления драйвера я мог бы обойти это, если бы принудительно загрузил модуль usb_f_rndis сразу после модуля libcomposite, это принудительно заставит usb_f_rndis в первый и второй слот iad. Остальные модули для libcomposite устройств будут загружаться по мере добавления устройств в configfs, и Windows будет этому рада.

Кроме того, чтобы заставить Windows загружать правильный драйвер, убедитесь, что вы настроили os_desc. Здесь есть хорошее руководство по этому поводу: http://irq5.io/2016/12/22/raspberry-pi-zero-as-multiple-usb-gadgets/

person Gavin_darkglider    schedule 14.03.2018