xref: /nrf52832-nimble/rt-thread/components/drivers/usb/usbdevice/class/rndis.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
1 /*
2  * Copyright (c) 2006-2018, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author            Notes
8  * 2012-12-24     heyuanjie87       first version
9  * 2013-04-13     aozima            update ethernet driver.
10  * 2013-04-26     aozima            align the desc to 4byte.
11  * 2013-05-08     aozima            pad a dummy when send MAX_PKT_SIZE.
12  * 2013-05-09     aozima            add delay linkup feature.
13  * 2013-07-09     aozima            support respone chain list.
14  * 2013-07-18     aozima            re-initial respone chain list when RNDIS restart.
15  * 2017-11-25     ZYH               fix it and add OS descriptor
16  */
17 
18 #include <rtdevice.h>
19 #include "cdc.h"
20 #include "rndis.h"
21 #include "ndis.h"
22 
23 //#define RNDIS_DEBUG
24 //#define RNDIS_DELAY_LINK_UP
25 
26 #ifdef  RNDIS_DEBUG
27 #define RNDIS_PRINTF                rt_kprintf("[RNDIS] "); rt_kprintf
28 #else
29 #define RNDIS_PRINTF(...)
30 #endif /* RNDIS_DEBUG */
31 
32 /* RT-Thread LWIP ethernet interface */
33 #include <netif/ethernetif.h>
34 
35 
36 struct rt_rndis_response
37 {
38     struct rt_list_node list;
39     const void * buffer;
40 };
41 
42 #define MAX_ADDR_LEN    6
43 struct rt_rndis_eth
44 {
45     /* inherit from ethernet device */
46     struct eth_device parent;
47     struct ufunction *func;
48     /* interface address info */
49     rt_uint8_t  host_addr[MAX_ADDR_LEN];
50     rt_uint8_t  dev_addr[MAX_ADDR_LEN];
51 
52 #ifdef RNDIS_DELAY_LINK_UP
53     struct rt_timer timer;
54 #endif /* RNDIS_DELAY_LINK_UP */
55 
56     ALIGN(4)
57     rt_uint8_t rx_pool[512];
58     ALIGN(4)
59     rt_uint8_t tx_pool[512];
60 
61     rt_uint32_t cmd_pool[2];
62     ALIGN(4)
63     char rx_buffer[sizeof(struct rndis_packet_msg) + USB_ETH_MTU + 14];
64     rt_size_t rx_offset;
65     rt_size_t rx_length;
66     rt_bool_t rx_flag;
67     rt_bool_t rx_frist;
68 
69     ALIGN(4)
70     char tx_buffer[sizeof(struct rndis_packet_msg) + USB_ETH_MTU + 14];
71     struct rt_semaphore tx_buffer_free;
72 
73     struct rt_list_node response_list;
74     rt_bool_t  need_notify;
75     struct cdc_eps eps;
76 };
77 typedef struct rt_rndis_eth * rt_rndis_eth_t;
78 static rt_uint32_t oid_packet_filter = 0x0000000;
79 
80 ALIGN(4)
81 static struct udevice_descriptor _dev_desc =
82 {
83     USB_DESC_LENGTH_DEVICE,   /* bLength */
84     USB_DESC_TYPE_DEVICE,     /* type */
85     USB_BCD_VERSION,          /* bcdUSB */
86     0xEF,                     /* bDeviceClass */
87     0x04,                     /* bDeviceSubClass */
88     0x01,                     /* bDeviceProtocol */
89     USB_CDC_BUFSIZE,          /* bMaxPacketSize0 */
90     _VENDOR_ID,               /* idVendor */
91     _PRODUCT_ID,              /* idProduct */
92     USB_BCD_DEVICE,           /* bcdDevice */
93     USB_STRING_MANU_INDEX,    /* iManufacturer */
94     USB_STRING_PRODUCT_INDEX, /* iProduct */
95     USB_STRING_SERIAL_INDEX,  /* iSerialNumber */
96     USB_DYNAMIC               /* bNumConfigurations */
97 };
98 
99 /* communcation interface descriptor */
100 ALIGN(4)
101 const static struct ucdc_comm_descriptor _comm_desc =
102 {
103 #ifdef RT_USB_DEVICE_COMPOSITE
104     /* Interface Association Descriptor */
105     {
106         USB_DESC_LENGTH_IAD,
107         USB_DESC_TYPE_IAD,
108         USB_DYNAMIC,
109         0x02,
110         USB_CDC_CLASS_COMM,
111         USB_CDC_SUBCLASS_ACM,
112         USB_CDC_PROTOCOL_VENDOR,
113         0x00,
114     },
115 #endif
116     /* Interface Descriptor */
117     {
118         USB_DESC_LENGTH_INTERFACE,
119         USB_DESC_TYPE_INTERFACE,
120         USB_DYNAMIC,
121         0x00,
122         0x01,
123         USB_CDC_CLASS_COMM,
124         USB_CDC_SUBCLASS_ACM,
125         USB_CDC_PROTOCOL_VENDOR,
126         0x00,
127     },
128     /* Header Functional Descriptor */
129     {
130         0x05,
131         USB_CDC_CS_INTERFACE,
132         USB_CDC_SCS_HEADER,
133         0x0110,
134     },
135     /* Call Management Functional Descriptor */
136     {
137         0x05,
138         USB_CDC_CS_INTERFACE,
139         USB_CDC_SCS_CALL_MGMT,
140         0x00,
141         USB_DYNAMIC,
142     },
143     /* Abstract Control Management Functional Descriptor */
144     {
145         0x04,
146         USB_CDC_CS_INTERFACE,
147         USB_CDC_SCS_ACM,
148         0x02,
149     },
150     /* Union Functional Descriptor */
151     {
152         0x05,
153         USB_CDC_CS_INTERFACE,
154         USB_CDC_SCS_UNION,
155         USB_DYNAMIC,
156         USB_DYNAMIC,
157     },
158     /* Endpoint Descriptor */
159     {
160         USB_DESC_LENGTH_ENDPOINT,
161         USB_DESC_TYPE_ENDPOINT,
162         USB_DIR_IN | USB_DYNAMIC,
163         USB_EP_ATTR_INT,
164         0x08,
165         0x0A,
166     },
167 };
168 
169 /* data interface descriptor */
170 ALIGN(4)
171 const static struct ucdc_data_descriptor _data_desc =
172 {
173     /* interface descriptor */
174     {
175         USB_DESC_LENGTH_INTERFACE,
176         USB_DESC_TYPE_INTERFACE,
177         USB_DYNAMIC,
178         0x00,
179         0x02,
180         USB_CDC_CLASS_DATA,
181         0x00,
182         0x00,
183         0x00,
184     },
185     /* endpoint, bulk out */
186     {
187         USB_DESC_LENGTH_ENDPOINT,
188         USB_DESC_TYPE_ENDPOINT,
189         USB_DIR_OUT | USB_DYNAMIC,
190         USB_EP_ATTR_BULK,
191         USB_DYNAMIC,
192         0x00,
193     },
194     /* endpoint, bulk in */
195     {
196         USB_DESC_LENGTH_ENDPOINT,
197         USB_DESC_TYPE_ENDPOINT,
198         USB_DYNAMIC | USB_DIR_IN,
199         USB_EP_ATTR_BULK,
200         USB_DYNAMIC,
201         0x00,
202     },
203 };
204 
205 ALIGN(4)
206 const static char* _ustring[] =
207 {
208     "Language",                 /* LANGID */
209     "RT-Thread Team.",          /* MANU */
210     "RT-Thread RNDIS device",   /* PRODUCT */
211     "1.1.0",                    /* SERIAL */
212     "Configuration",            /* CONFIG */
213     "Interface",                /* INTERFACE */
214     USB_STRING_OS
215 };
216 
217 ALIGN(4)
218 struct usb_os_function_comp_id_descriptor rndis_func_comp_id_desc =
219 {
220     .bFirstInterfaceNumber = USB_DYNAMIC,
221     .reserved1          = 0x01,
222     .compatibleID       = {'R', 'N', 'D', 'I', 'S', 0x00, 0x00, 0x00},
223     .subCompatibleID    = {'5', '1', '6', '2', '0', '0', '1', 0x00},
224     .reserved2          = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
225 };
226 
227 //FS and HS needed
228 ALIGN(4)
229 static struct usb_qualifier_descriptor dev_qualifier =
230 {
231     sizeof(dev_qualifier),          //bLength
232     USB_DESC_TYPE_DEVICEQUALIFIER,  //bDescriptorType
233     0x0200,                         //bcdUSB
234     USB_CLASS_CDC,                  //bDeviceClass
235     USB_CDC_SUBCLASS_ACM,           //bDeviceSubClass
236     USB_CDC_PROTOCOL_VENDOR,        //bDeviceProtocol
237     64,                             //bMaxPacketSize0
238     0x01,                           //bNumConfigurations
239     0,
240 };
241 
242 /* supported OIDs */
243 ALIGN(4)
244 const static rt_uint32_t oid_supported_list[] =
245 {
246     /* General OIDs */
247     OID_GEN_SUPPORTED_LIST,
248     OID_GEN_HARDWARE_STATUS,
249     OID_GEN_MEDIA_SUPPORTED,
250     OID_GEN_MEDIA_IN_USE,
251     OID_GEN_MAXIMUM_FRAME_SIZE,
252     OID_GEN_LINK_SPEED,
253     OID_GEN_TRANSMIT_BLOCK_SIZE,
254     OID_GEN_RECEIVE_BLOCK_SIZE,
255     OID_GEN_VENDOR_ID,
256     OID_GEN_VENDOR_DESCRIPTION,
257     OID_GEN_VENDOR_DRIVER_VERSION,
258     OID_GEN_CURRENT_PACKET_FILTER,
259     OID_GEN_MAXIMUM_TOTAL_SIZE,
260     OID_GEN_MEDIA_CONNECT_STATUS,
261 
262     OID_GEN_PHYSICAL_MEDIUM,
263 
264     /* General Statistic OIDs */
265     OID_GEN_XMIT_OK,
266     OID_GEN_RCV_OK,
267     OID_GEN_XMIT_ERROR,
268     OID_GEN_RCV_ERROR,
269     OID_GEN_RCV_NO_BUFFER,
270 
271     /* Please configure us */
272     OID_GEN_RNDIS_CONFIG_PARAMETER,
273 
274     /* 802.3 OIDs */
275     OID_802_3_PERMANENT_ADDRESS,
276     OID_802_3_CURRENT_ADDRESS,
277     OID_802_3_MULTICAST_LIST,
278     OID_802_3_MAXIMUM_LIST_SIZE,
279 
280     /* 802.3 Statistic OIDs */
281     OID_802_3_RCV_ERROR_ALIGNMENT,
282     OID_802_3_XMIT_ONE_COLLISION,
283     OID_802_3_XMIT_MORE_COLLISIONS,
284 
285     OID_802_3_MAC_OPTIONS,
286 };
287 
288 static rt_uint8_t rndis_message_buffer[RNDIS_MESSAGE_BUFFER_SIZE];
289 
290 static void _rndis_response_available(ufunction_t func)
291 {
292     rt_rndis_eth_t device = (rt_rndis_eth_t)func->user_data;
293     rt_uint32_t * data;
294     if(device->need_notify == RT_TRUE)
295     {
296         device->need_notify = RT_FALSE;
297         data = (rt_uint32_t *)device->eps.ep_cmd->buffer;
298         data[0] = RESPONSE_AVAILABLE;
299         data[1] = 0;
300         device->eps.ep_cmd->request.buffer = device->eps.ep_cmd->buffer;
301         device->eps.ep_cmd->request.size = 8;
302         device->eps.ep_cmd->request.req_type = UIO_REQUEST_WRITE;
303         rt_usbd_io_request(func->device, device->eps.ep_cmd, &device->eps.ep_cmd->request);
304     }
305 }
306 
307 static rt_err_t _rndis_init_response(ufunction_t func, rndis_init_msg_t msg)
308 {
309     rndis_init_cmplt_t resp;
310     struct rt_rndis_response * response;
311 
312     response = rt_malloc(sizeof(struct rt_rndis_response));
313     resp = rt_malloc(sizeof(struct rndis_init_cmplt));
314 
315     if( (response == RT_NULL) || (resp == RT_NULL) )
316     {
317         RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
318 
319         if(response != RT_NULL)
320             rt_free(response);
321 
322         if(resp != RT_NULL)
323             rt_free(resp);
324 
325         return -RT_ENOMEM;
326     }
327 
328     resp->RequestId = msg->RequestId;
329     resp->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
330     resp->MessageLength = sizeof(struct rndis_init_cmplt);
331     resp->MajorVersion = RNDIS_MAJOR_VERSION;
332     resp->MinorVersion = RNDIS_MAJOR_VERSION;
333     resp->Status = RNDIS_STATUS_SUCCESS;
334     resp->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
335     resp->Medium = RNDIS_MEDIUM_802_3;
336     resp->MaxPacketsPerTransfer = 1;
337     resp->MaxTransferSize = USB_ETH_MTU + 58;   /* Space for 1280 IP buffer, Ethernet Header,
338                                                 RNDIS messages */
339     resp->PacketAlignmentFactor = 3;
340     resp->AfListOffset = 0;
341     resp->AfListSize = 0;
342 
343     response->buffer = resp;
344 
345     {
346         rt_base_t level = rt_hw_interrupt_disable();
347         rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
348         rt_hw_interrupt_enable(level);
349     }
350 
351 
352     return RT_EOK;
353 }
354 
355 static rndis_query_cmplt_t _create_resp(rt_size_t size)
356 {
357     rndis_query_cmplt_t resp;
358 
359     resp = rt_malloc(sizeof(struct rndis_query_cmplt) + size);
360 
361     if(resp == RT_NULL)
362     {
363         RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
364         return RT_NULL;
365     }
366 
367     resp->InformationBufferLength = size;
368 
369     return resp;
370 }
371 
372 static void _copy_resp(rndis_query_cmplt_t resp, const void * buffer)
373 {
374     char * resp_buffer = (char *)resp + sizeof(struct rndis_query_cmplt);
375     memcpy(resp_buffer, buffer, resp->InformationBufferLength);
376 }
377 
378 static void _set_resp(rndis_query_cmplt_t resp, rt_uint32_t value)
379 {
380     rt_uint32_t * response = (rt_uint32_t *)((char *)resp + sizeof(struct rndis_query_cmplt));
381     *response = value;
382 }
383 
384 static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg)
385 {
386     rndis_query_cmplt_t resp = RT_NULL;
387     struct rt_rndis_response * response;
388     rt_err_t ret = RT_EOK;
389 
390     switch (msg->Oid)
391     {
392         /*
393          * general OIDs
394          */
395     case OID_GEN_SUPPORTED_LIST:
396         resp = _create_resp(sizeof(oid_supported_list));
397         if(resp == RT_NULL) break;
398         _copy_resp(resp, oid_supported_list);
399         break;
400 
401     case OID_GEN_PHYSICAL_MEDIUM:
402         resp = _create_resp(4);
403         if(resp == RT_NULL) break;
404         _set_resp(resp, NDIS_MEDIUM_802_3);
405         break;
406 
407     case OID_GEN_MAXIMUM_FRAME_SIZE:
408     case OID_GEN_TRANSMIT_BLOCK_SIZE:
409     case OID_GEN_RECEIVE_BLOCK_SIZE:
410         resp = _create_resp(4);
411         if(resp == RT_NULL) break;
412         _set_resp(resp, USB_ETH_MTU);
413         break;
414 
415     case OID_GEN_MAXIMUM_TOTAL_SIZE:
416         resp = _create_resp(4);
417         if(resp == RT_NULL) break;
418         _set_resp(resp, USB_ETH_MTU + RNDIS_MESSAGE_BUFFER_SIZE);
419         break;
420 
421     case OID_GEN_LINK_SPEED:
422         resp = _create_resp(4);
423         if(resp == RT_NULL) break;
424         _set_resp(resp, func->device->dcd->device_is_hs ? (480UL * 1000 *1000) : (12UL * 1000 * 1000) / 100);
425         break;
426 
427     case OID_GEN_MEDIA_CONNECT_STATUS:
428         /* link_status */
429         resp = _create_resp(4);
430         if(resp == RT_NULL) break;
431 
432 #ifdef  RNDIS_DELAY_LINK_UP
433         if(((rt_rndis_eth_t)func->user_data)->parent.link_status)
434         {
435             _set_resp(resp, NDIS_MEDIA_STATE_CONNECTED);
436         }
437         else
438         {
439             _set_resp(resp, NDIS_MEDIA_STATE_DISCONNECTED);
440         }
441 #else
442         _set_resp(resp, NDIS_MEDIA_STATE_CONNECTED);
443 #endif /* RNDIS_DELAY_LINK_UP */
444         break;
445 
446     case OID_GEN_VENDOR_ID:
447         resp = _create_resp(4);
448         if(resp == RT_NULL) break;
449         _set_resp(resp, 0x12345678);    /* only for test */
450         break;
451 
452     case OID_GEN_VENDOR_DESCRIPTION:
453     {
454         const char vendor_desc[] = "RT-Thread RNDIS";
455 
456         resp = _create_resp(sizeof(vendor_desc));
457         if(resp == RT_NULL) break;
458         _copy_resp(resp, vendor_desc);
459     }
460     break;
461 
462     case OID_GEN_VENDOR_DRIVER_VERSION:
463         resp = _create_resp(4);
464         if(resp == RT_NULL) break;
465         _set_resp(resp, 0x0000200);
466         break;
467 
468         /* statistics OIDs */
469     case OID_GEN_XMIT_OK:
470     case OID_GEN_RCV_OK:
471         resp = _create_resp(4);
472         if(resp == RT_NULL) break;
473         _set_resp(resp, 1);
474         break;
475 
476     case OID_GEN_XMIT_ERROR:
477     case OID_GEN_RCV_ERROR:
478     case OID_GEN_RCV_NO_BUFFER:
479         resp = _create_resp(4);
480         if(resp == RT_NULL) break;
481         _set_resp(resp, 0);
482         break;
483 
484         /*
485          * ieee802.3 OIDs
486          */
487     case OID_802_3_MAXIMUM_LIST_SIZE:
488         resp = _create_resp(4);
489         if(resp == RT_NULL) break;
490         _set_resp(resp, 1);
491         break;
492 
493     case OID_802_3_PERMANENT_ADDRESS:
494     case OID_802_3_CURRENT_ADDRESS:
495         resp = _create_resp(sizeof(((rt_rndis_eth_t)func->user_data)->host_addr));
496         if(resp == RT_NULL) break;
497         _copy_resp(resp, ((rt_rndis_eth_t)func->user_data)->host_addr);
498         break;
499 
500     case OID_802_3_MULTICAST_LIST:
501         resp = _create_resp(4);
502         if(resp == RT_NULL) break;
503         _set_resp(resp, 0xE000000);
504         break;
505 
506     case OID_802_3_MAC_OPTIONS:
507         resp = _create_resp(4);
508         if(resp == RT_NULL) break;
509         _set_resp(resp, 0);
510         break;
511 
512     default:
513         RNDIS_PRINTF("OID %X\n", msg->Oid);
514         ret = -RT_ERROR;
515         break;
516     }
517 
518     response = rt_malloc(sizeof(struct rt_rndis_response));
519     if( (response == RT_NULL) || (resp == RT_NULL) )
520     {
521         RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
522 
523         if(response != RT_NULL)
524             rt_free(response);
525 
526         if(resp != RT_NULL)
527             rt_free(resp);
528 
529         return -RT_ENOMEM;
530     }
531 
532     resp->RequestId = msg->RequestId;
533     resp->MessageType = REMOTE_NDIS_QUERY_CMPLT;
534     resp->InformationBufferOffset = 16;
535 
536     resp->Status = RNDIS_STATUS_SUCCESS;
537     resp->MessageLength = sizeof(struct rndis_query_cmplt) + resp->InformationBufferLength;
538 
539     response->buffer = resp;
540 
541     {
542         rt_base_t level = rt_hw_interrupt_disable();
543         rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
544         rt_hw_interrupt_enable(level);
545     }
546 
547     return ret;
548 }
549 
550 static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
551 {
552     rndis_set_cmplt_t resp;
553     struct rt_rndis_response * response;
554 
555     response = rt_malloc(sizeof(struct rt_rndis_response));
556     resp = rt_malloc(sizeof(struct rndis_set_cmplt));
557 
558     if( (response == RT_NULL) || (resp == RT_NULL) )
559     {
560         RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
561 
562         if(response != RT_NULL)
563             rt_free(response);
564 
565         if(resp != RT_NULL)
566             rt_free(resp);
567 
568         return -RT_ENOMEM;
569     }
570 
571     resp->RequestId = msg->RequestId;
572     resp->MessageType = REMOTE_NDIS_SET_CMPLT;
573     resp->MessageLength = sizeof(struct rndis_set_cmplt);
574 
575     switch (msg->Oid)
576     {
577     case OID_GEN_CURRENT_PACKET_FILTER:
578         oid_packet_filter = *((rt_uint32_t *)((rt_uint8_t *)&(msg->RequestId) + \
579                                               msg->InformationBufferOffset));
580         oid_packet_filter = oid_packet_filter;
581         RNDIS_PRINTF("OID_GEN_CURRENT_PACKET_FILTER\r\n");
582 
583 #ifdef  RNDIS_DELAY_LINK_UP
584         /* link up. */
585         rt_timer_start(&((rt_rndis_eth_t)func->user_data)->timer);
586 #else
587         eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_TRUE);
588 #endif /* RNDIS_DELAY_LINK_UP */
589         break;
590 
591     case OID_802_3_MULTICAST_LIST:
592         break;
593 
594     default:
595         resp->Status = RNDIS_STATUS_FAILURE;
596         return RT_EOK;
597     }
598 
599     resp->Status = RNDIS_STATUS_SUCCESS;
600 
601     response->buffer = resp;
602 
603     {
604         rt_base_t level = rt_hw_interrupt_disable();
605         rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
606         rt_hw_interrupt_enable(level);
607     }
608 
609     return RT_EOK;
610 }
611 
612 static rt_err_t _rndis_keepalive_response(ufunction_t func,rndis_keepalive_msg_t msg)
613 {
614     rndis_keepalive_cmplt_t resp;
615     struct rt_rndis_response * response;
616 
617     response = rt_malloc(sizeof(struct rt_rndis_response));
618     resp = rt_malloc(sizeof(struct rndis_keepalive_cmplt));
619 
620     if( (response == RT_NULL) || (resp == RT_NULL) )
621     {
622         RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
623 
624         if(response != RT_NULL)
625             rt_free(response);
626 
627         if(resp != RT_NULL)
628             rt_free(resp);
629 
630         return -RT_ENOMEM;
631     }
632 
633     resp->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
634     resp->MessageLength = sizeof(struct rndis_keepalive_cmplt);
635     resp->Status = RNDIS_STATUS_SUCCESS;
636 
637     response->buffer = resp;
638 
639     {
640         rt_base_t level = rt_hw_interrupt_disable();
641         rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
642         rt_hw_interrupt_enable(level);
643     }
644 
645     return RT_EOK;
646 }
647 
648 static rt_err_t _rndis_msg_parser(ufunction_t func, rt_uint8_t *msg)
649 {
650     rt_err_t ret = -RT_ERROR;
651 
652     switch (((rndis_gen_msg_t) msg)->MessageType)
653     {
654     case REMOTE_NDIS_INITIALIZE_MSG:
655         ret = _rndis_init_response(func, (rndis_init_msg_t) msg);
656         break;
657 
658     case REMOTE_NDIS_HALT_MSG:
659         RNDIS_PRINTF("halt\n");
660         /* link down. */
661         eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
662         break;
663 
664     case REMOTE_NDIS_QUERY_MSG:
665         ret = _rndis_query_response(func,(rndis_query_msg_t) msg);
666         break;
667 
668     case REMOTE_NDIS_SET_MSG:
669         ret = _rndis_set_response(func,(rndis_set_msg_t) msg);
670         RNDIS_PRINTF("set\n");
671         break;
672 
673     case REMOTE_NDIS_RESET_MSG:
674         RNDIS_PRINTF("reset\n");
675         break;
676 
677     case REMOTE_NDIS_KEEPALIVE_MSG:
678         ret = _rndis_keepalive_response(func,(rndis_keepalive_msg_t) msg);
679         break;
680 
681     default:
682         RNDIS_PRINTF("msg %X\n", ((rndis_gen_msg_t) msg)->MessageType);
683         ret = -RT_ERROR;
684         break;
685     }
686 
687     if (ret == RT_EOK)
688         _rndis_response_available(func);
689 
690     return ret;
691 }
692 
693 static ufunction_t function = RT_NULL;
694 static rt_err_t send_encapsulated_command_done(udevice_t device, rt_size_t size)
695 {
696     if(function != RT_NULL)
697     {
698         dcd_ep0_send_status(device->dcd);
699         _rndis_msg_parser(function, rndis_message_buffer);
700         function = RT_NULL;
701     }
702     return RT_EOK;
703 }
704 //#error here have bug ep 0x82 send failed
705 static rt_err_t _rndis_send_encapsulated_command(ufunction_t func, ureq_t setup)
706 {
707     RT_ASSERT(setup->wLength <= sizeof(rndis_message_buffer));
708     function = func;
709     rt_usbd_ep0_read(func->device,rndis_message_buffer,setup->wLength,send_encapsulated_command_done);
710 
711     return RT_EOK;
712 }
713 
714 static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
715 {
716     rndis_gen_msg_t msg;
717     struct rt_rndis_response * response;
718 
719     if(rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
720     {
721         RNDIS_PRINTF("response_list is empty!\r\n");
722         ((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE;
723         return RT_EOK;
724     }
725 
726     response = (struct rt_rndis_response *)((rt_rndis_eth_t)func->user_data)->response_list.next;
727 
728     msg = (rndis_gen_msg_t)response->buffer;
729     rt_usbd_ep0_write(func->device, (void*)msg, msg->MessageLength);
730 
731     {
732         rt_base_t level = rt_hw_interrupt_disable();
733         rt_list_remove(&response->list);
734         rt_hw_interrupt_enable(level);
735     }
736 
737     rt_free((void *)response->buffer);
738     rt_free(response);
739 
740     if(!rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
741     {
742         rt_uint32_t * data;
743 
744         RNDIS_PRINTF("auto append next response!\r\n");
745         data = (rt_uint32_t *)((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->buffer;
746         data[0] = RESPONSE_AVAILABLE;
747         data[1] = 0;
748         ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->request.buffer = ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->buffer;
749         ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->request.size = 8;
750         ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->request.req_type = UIO_REQUEST_WRITE;
751         rt_usbd_io_request(func->device, ((rt_rndis_eth_t)func->user_data)->eps.ep_cmd, &((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->request);
752     }
753     else
754     {
755         ((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE;
756     }
757 
758     return RT_EOK;
759 }
760 
761 #ifdef  RNDIS_DELAY_LINK_UP
762 /**
763  * This function will set rndis connect status.
764  *
765  * @param device the usb device object.
766  * @param status the connect status.
767  *
768  * @return RT_EOK on successful.
769  */
770 static rt_err_t _rndis_indicate_status_msg(ufunction_t func, rt_uint32_t status)
771 {
772     rndis_indicate_status_msg_t resp;
773     struct rt_rndis_response * response;
774 
775     response = rt_malloc(sizeof(struct rt_rndis_response));
776     resp = rt_malloc(sizeof(struct rndis_indicate_status_msg));
777 
778     if( (response == RT_NULL) || (resp == RT_NULL) )
779     {
780         RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
781 
782         if(response != RT_NULL)
783             rt_free(response);
784 
785         if(resp != RT_NULL)
786             rt_free(resp);
787 
788         return -RT_ENOMEM;
789     }
790 
791     resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
792     resp->MessageLength = 20; /* sizeof(struct rndis_indicate_status_msg) */
793     resp->Status = status;
794     resp->StatusBufferLength = 0;
795     resp->StatusBufferOffset = 0;
796 
797     response->buffer = resp;
798     {
799         rt_base_t level = rt_hw_interrupt_disable();
800         rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
801         rt_hw_interrupt_enable(level);
802     }
803 
804     _rndis_response_available(func);
805 
806     return RT_EOK;
807 }
808 #endif /* RNDIS_DELAY_LINK_UP */
809 
810 /**
811  * This function will handle rndis interface request.
812  *
813  * @param device the usb device object.
814  * @param setup the setup request.
815  *
816  * @return RT_EOK on successful.
817  */
818 static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
819 {
820     RT_ASSERT(func != RT_NULL);
821     RT_ASSERT(setup != RT_NULL);
822 
823     switch(setup->bRequest)
824     {
825     case CDC_SEND_ENCAPSULATED_COMMAND:
826         _rndis_send_encapsulated_command(func, setup);
827         break;
828 
829     case CDC_GET_ENCAPSULATED_RESPONSE:
830         _rndis_get_encapsulated_response(func, setup);
831         break;
832 
833     default:
834         RNDIS_PRINTF("unkown setup->request!\r\n");
835         break;
836     }
837 
838     return RT_EOK;
839 }
840 
841 /**
842  * This function will handle rndis bulk in endpoint request.
843  *
844  * @param device the usb device object.
845  * @param size request size.
846  *
847  * @return RT_EOK.
848  */
849 
850 static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size)
851 {
852     rt_sem_release(&((rt_rndis_eth_t)func->user_data)->tx_buffer_free);
853     return RT_EOK;
854 }
855 
856 /**
857  * This function will handle RNDIS bulk out endpoint request.
858  *
859  * @param device the usb device object.
860  * @param size request size.
861  *
862  * @return RT_EOK.
863  */
864 static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size)
865 {
866     cdc_eps_t eps;
867     char* data = RT_NULL;
868 
869     eps = (cdc_eps_t)&((rt_rndis_eth_t)func->user_data)->eps;
870     data = (char*)eps->ep_out->buffer;
871 
872     if(((rt_rndis_eth_t)func->user_data)->rx_frist == RT_TRUE)
873     {
874         rndis_packet_msg_t msg = (rndis_packet_msg_t)data;
875 
876         ((rt_rndis_eth_t)func->user_data)->rx_length = msg->DataLength;
877         ((rt_rndis_eth_t)func->user_data)->rx_offset = 0;
878 
879         if (size >= 44)
880         {
881             data += sizeof(struct rndis_packet_msg);
882             size -= sizeof(struct rndis_packet_msg);
883             ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_FALSE;
884             memcpy(&((rt_rndis_eth_t)func->user_data)->rx_buffer[((rt_rndis_eth_t)func->user_data)->rx_offset], data, size);
885             ((rt_rndis_eth_t)func->user_data)->rx_offset += size;
886         }
887     }
888     else
889     {
890         memcpy(&((rt_rndis_eth_t)func->user_data)->rx_buffer[((rt_rndis_eth_t)func->user_data)->rx_offset], data, size);
891         ((rt_rndis_eth_t)func->user_data)->rx_offset += size;
892     }
893 
894     if(((rt_rndis_eth_t)func->user_data)->rx_offset >= ((rt_rndis_eth_t)func->user_data)->rx_length)
895     {
896         ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
897         ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_TRUE;
898         eth_device_ready(&(((rt_rndis_eth_t)func->user_data)->parent));
899     }
900     else
901     {
902         eps->ep_out->request.buffer = eps->ep_out->buffer;
903         eps->ep_out->request.size = EP_MAXPACKET(eps->ep_out);
904         eps->ep_out->request.req_type = UIO_REQUEST_READ_BEST;
905         rt_usbd_io_request(func->device, eps->ep_out, &eps->ep_out->request);
906     }
907 
908     return RT_EOK;
909 }
910 
911 /**
912  * This function will handle RNDIS interrupt in endpoint request.
913  *
914  * @param device the usb device object.
915  * @param size request size.
916  *
917  * @return RT_EOK.
918  */
919 static rt_err_t _ep_cmd_handler(ufunction_t func, rt_size_t size)
920 {
921 //    _rndis_response_available(func);
922     return RT_EOK;
923 }
924 
925 /**
926  * This function will run cdc class, it will be called on handle set configuration request.
927  *
928  * @param device the usb device object.
929  *
930  * @return RT_EOK on successful.
931  */
932 static rt_err_t _function_enable(ufunction_t func)
933 {
934     cdc_eps_t eps;
935 
936     eps = (cdc_eps_t)&((rt_rndis_eth_t)func->user_data)->eps;
937     eps->ep_in->buffer  = ((rt_rndis_eth_t)func->user_data)->tx_pool;
938     eps->ep_out->buffer = ((rt_rndis_eth_t)func->user_data)->rx_pool;
939     eps->ep_cmd->buffer = (rt_uint8_t*)((rt_rndis_eth_t)func->user_data)->cmd_pool;
940 
941     eps->ep_out->request.buffer = eps->ep_out->buffer;
942     eps->ep_out->request.size = EP_MAXPACKET(eps->ep_out);
943     eps->ep_out->request.req_type = UIO_REQUEST_READ_BEST;
944     rt_usbd_io_request(func->device, eps->ep_out, &eps->ep_out->request);
945 
946     ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
947     ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
948 
949 #ifdef  RNDIS_DELAY_LINK_UP
950     /* stop link up timer. */
951     rt_timer_stop(&((rt_rndis_eth_t)func->user_data)->timer);
952 #endif /* RNDIS_DELAY_LINK_UP */
953 
954     /* clean resp chain list. */
955     {
956         struct rt_rndis_response * response;
957         rt_base_t level = rt_hw_interrupt_disable();
958 
959         while(!rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
960         {
961             response = (struct rt_rndis_response *)((rt_rndis_eth_t)func->user_data)->response_list.next;
962 
963             rt_list_remove(&response->list);
964             rt_free((void *)response->buffer);
965             rt_free(response);
966         }
967 
968         ((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE;
969         rt_hw_interrupt_enable(level);
970     }
971 
972     return RT_EOK;
973 }
974 
975 /**
976  * This function will stop cdc class, it will be called on handle set configuration request.
977  *
978  * @param device the usb device object.
979  *
980  * @return RT_EOK on successful.
981  */
982 static rt_err_t _function_disable(ufunction_t func)
983 {
984     RNDIS_PRINTF("plugged out\n");
985 
986 #ifdef  RNDIS_DELAY_LINK_UP
987     /* stop link up timer. */
988     rt_timer_stop(&((rt_rndis_eth_t)func->user_data)->timer);
989 #endif /* RNDIS_DELAY_LINK_UP */
990 
991     /* clean resp chain list. */
992     {
993         struct rt_rndis_response * response;
994         rt_base_t level = rt_hw_interrupt_disable();
995 
996         while(!rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
997         {
998             response = (struct rt_rndis_response *)((rt_rndis_eth_t)func->user_data)->response_list.next;
999             RNDIS_PRINTF("remove resp chain list!\r\n");
1000 
1001             rt_list_remove(&response->list);
1002             rt_free((void *)response->buffer);
1003             rt_free(response);
1004         }
1005 
1006         ((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE;
1007         rt_hw_interrupt_enable(level);
1008     }
1009 
1010     /* link down. */
1011     eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
1012     return RT_EOK;
1013 }
1014 
1015 
1016 static struct ufunction_ops ops =
1017 {
1018     _function_enable,
1019     _function_disable,
1020     RT_NULL,
1021 };
1022 
1023 /**
1024  * This function will configure cdc descriptor.
1025  *
1026  * @param comm the communication interface number.
1027  * @param data the data interface number.
1028  *
1029  * @return RT_EOK on successful.
1030  */
1031 static rt_err_t _cdc_descriptor_config(ucdc_comm_desc_t comm, rt_uint8_t cintf_nr, ucdc_data_desc_t data, rt_uint8_t dintf_nr, rt_uint8_t device_is_hs)
1032 {
1033     comm->call_mgmt_desc.data_interface = dintf_nr;
1034     comm->union_desc.master_interface = cintf_nr;
1035     comm->union_desc.slave_interface0 = dintf_nr;
1036 #ifdef RT_USB_DEVICE_COMPOSITE
1037     comm->iad_desc.bFirstInterface = cintf_nr;
1038 #endif
1039     data->ep_out_desc.wMaxPacketSize = device_is_hs ? 512 : 64;
1040     data->ep_in_desc.wMaxPacketSize = device_is_hs ? 512 : 64;
1041     return RT_EOK;
1042 }
1043 
1044 #ifdef RT_USING_LWIP
1045 /* initialize the interface */
1046 static rt_err_t rt_rndis_eth_init(rt_device_t dev)
1047 {
1048     return RT_EOK;
1049 }
1050 
1051 static rt_err_t rt_rndis_eth_open(rt_device_t dev, rt_uint16_t oflag)
1052 {
1053     return RT_EOK;
1054 }
1055 
1056 static rt_err_t rt_rndis_eth_close(rt_device_t dev)
1057 {
1058     return RT_EOK;
1059 }
1060 
1061 static rt_size_t rt_rndis_eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
1062 {
1063     rt_set_errno(-RT_ENOSYS);
1064     return 0;
1065 }
1066 
1067 static rt_size_t rt_rndis_eth_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
1068 {
1069     rt_set_errno(-RT_ENOSYS);
1070     return 0;
1071 }
1072 static rt_err_t rt_rndis_eth_control(rt_device_t dev, int cmd, void *args)
1073 {
1074     rt_rndis_eth_t rndis_eth_dev = (rt_rndis_eth_t)dev;
1075     switch(cmd)
1076     {
1077     case NIOCTL_GADDR:
1078         /* get mac address */
1079         if(args) rt_memcpy(args, rndis_eth_dev->dev_addr, MAX_ADDR_LEN);
1080         else return -RT_ERROR;
1081         break;
1082 
1083     default :
1084         break;
1085     }
1086 
1087     return RT_EOK;
1088 }
1089 
1090 /* ethernet device interface */
1091 
1092 
1093 /* reception packet. */
1094 struct pbuf *rt_rndis_eth_rx(rt_device_t dev)
1095 {
1096     struct pbuf* p = RT_NULL;
1097     rt_uint32_t offset = 0;
1098     rt_rndis_eth_t device = (rt_rndis_eth_t)dev;
1099     if(device->rx_flag == RT_FALSE)
1100     {
1101         return p;
1102     }
1103 
1104     if(device->rx_length != 0)
1105     {
1106         /* allocate buffer */
1107         p = pbuf_alloc(PBUF_LINK, device->rx_length, PBUF_RAM);
1108         if (p != RT_NULL)
1109         {
1110             struct pbuf* q;
1111 
1112             for (q = p; q != RT_NULL; q= q->next)
1113             {
1114                 /* Copy the received frame into buffer from memory pointed by the current ETHERNET DMA Rx descriptor */
1115                 memcpy(q->payload,
1116                        (rt_uint8_t *)((device->rx_buffer) + offset),
1117                        q->len);
1118                 offset += q->len;
1119             }
1120         }
1121     }
1122 
1123     {
1124         device->rx_flag = RT_FALSE;
1125         device->eps.ep_out->request.buffer = device->eps.ep_out->buffer;
1126         device->eps.ep_out->request.size = EP_MAXPACKET(device->eps.ep_out);
1127         device->eps.ep_out->request.req_type = UIO_REQUEST_READ_BEST;
1128         rt_usbd_io_request(device->func->device, device->eps.ep_out, &device->eps.ep_out->request);
1129     }
1130 
1131     return p;
1132 }
1133 
1134 /* transmit packet. */
1135 rt_err_t rt_rndis_eth_tx(rt_device_t dev, struct pbuf* p)
1136 {
1137     struct pbuf* q;
1138     char * buffer;
1139     rt_err_t result = RT_EOK;
1140     rt_rndis_eth_t device = (rt_rndis_eth_t)dev;
1141 
1142     if(!device->parent.link_status)
1143     {
1144         RNDIS_PRINTF("linkdown, drop pkg\r\n");
1145         return RT_EOK;
1146     }
1147 
1148     RT_ASSERT(p->tot_len < sizeof(device->tx_buffer));
1149     if(p->tot_len > sizeof(device->tx_buffer))
1150     {
1151         RNDIS_PRINTF("RNDIS MTU is:%d, but the send packet size is %d\r\n",
1152                      sizeof(device->tx_buffer), p->tot_len);
1153         p->tot_len = sizeof(device->tx_buffer);
1154     }
1155 
1156     /* wait for buffer free. */
1157     result = rt_sem_take(&device->tx_buffer_free, RT_WAITING_FOREVER);
1158     if(result != RT_EOK)
1159     {
1160         return result;
1161     }
1162 
1163     buffer = (char *)&device->tx_buffer + sizeof(struct rndis_packet_msg);
1164     for (q = p; q != NULL; q = q->next)
1165     {
1166         memcpy(buffer, q->payload, q->len);
1167         buffer += q->len;
1168     }
1169 
1170     /* send */
1171     {
1172         rndis_packet_msg_t msg;
1173 
1174         msg = (rndis_packet_msg_t)&device->tx_buffer;
1175 
1176         msg->MessageType = REMOTE_NDIS_PACKET_MSG;
1177         msg->DataOffset = sizeof(struct rndis_packet_msg) - 8;
1178         msg->DataLength = p->tot_len;
1179         msg->OOBDataLength = 0;
1180         msg->OOBDataOffset = 0;
1181         msg->NumOOBDataElements = 0;
1182         msg->PerPacketInfoOffset = 0;
1183         msg->PerPacketInfoLength = 0;
1184         msg->VcHandle = 0;
1185         msg->Reserved = 0;
1186         msg->MessageLength = sizeof(struct rndis_packet_msg) + p->tot_len;
1187 
1188         if((msg->MessageLength & 0x3F) == 0)
1189         {
1190             /* pad a dummy. */
1191             msg->MessageLength += 1;
1192         }
1193 
1194         device->eps.ep_in->request.buffer = (void *)&device->tx_buffer;
1195         device->eps.ep_in->request.size = msg->MessageLength;
1196         device->eps.ep_in->request.req_type = UIO_REQUEST_WRITE;
1197         rt_usbd_io_request(device->func->device, device->eps.ep_in, &device->eps.ep_in->request);
1198     }
1199 
1200     return result;
1201 }
1202 
1203 #ifdef RT_USING_DEVICE_OPS
1204 const static struct rt_device_ops rndis_device_ops =
1205 {
1206     rt_rndis_eth_init,
1207     rt_rndis_eth_open,
1208     rt_rndis_eth_close,
1209     rt_rndis_eth_read,
1210     rt_rndis_eth_write,
1211     rt_rndis_eth_control
1212 };
1213 #endif
1214 
1215 #endif /* RT_USING_LWIP */
1216 
1217 #ifdef  RNDIS_DELAY_LINK_UP
1218 /* the delay linkup timer handler. */
1219 static void timer_timeout(void* parameter)
1220 {
1221     RNDIS_PRINTF("delay link up!\r\n");
1222     _rndis_indicate_status_msg(((rt_rndis_eth_t)parameter)->parent.parent.user_data,
1223                                RNDIS_STATUS_MEDIA_CONNECT);
1224     eth_device_linkchange(&((rt_rndis_eth_t)parameter)->parent, RT_TRUE);
1225 }
1226 #endif /* RNDIS_DELAY_LINK_UP */
1227 
1228 /**
1229  * This function will create a cdc rndis class instance.
1230  *
1231  * @param device the usb device object.
1232  *
1233  * @return RT_EOK on successful.
1234  */
1235 ufunction_t rt_usbd_function_rndis_create(udevice_t device)
1236 {
1237     ufunction_t cdc;
1238     rt_rndis_eth_t _rndis;
1239     cdc_eps_t eps;
1240     uintf_t intf_comm, intf_data;
1241     ualtsetting_t comm_setting, data_setting;
1242     ucdc_data_desc_t data_desc;
1243     ucdc_comm_desc_t comm_desc;
1244 
1245     /* parameter check */
1246     RT_ASSERT(device != RT_NULL);
1247 
1248     /* set usb device string description */
1249     rt_usbd_device_set_string(device, _ustring);
1250 
1251     /* create a cdc class */
1252     cdc = rt_usbd_function_new(device, &_dev_desc, &ops);
1253     rt_usbd_device_set_qualifier(device, &dev_qualifier);
1254     _rndis= rt_malloc(sizeof(struct rt_rndis_eth));
1255     rt_memset(_rndis, 0, sizeof(struct rt_rndis_eth));
1256     cdc->user_data = _rndis;
1257 
1258     _rndis->func = cdc;
1259     /* create a cdc class endpoints collection */
1260     eps = &_rndis->eps;
1261     /* create a cdc communication interface and a cdc data interface */
1262     intf_comm = rt_usbd_interface_new(device, _interface_handler);
1263     intf_data = rt_usbd_interface_new(device, _interface_handler);
1264 
1265     /* create a communication alternate setting and a data alternate setting */
1266     comm_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_comm_descriptor));
1267     data_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_data_descriptor));
1268 
1269     /* config desc in alternate setting */
1270     rt_usbd_altsetting_config_descriptor(comm_setting, &_comm_desc,
1271                                          (rt_off_t)&((ucdc_comm_desc_t)0)->intf_desc);
1272     rt_usbd_altsetting_config_descriptor(data_setting, &_data_desc, 0);
1273     /* configure the cdc interface descriptor */
1274     _cdc_descriptor_config(comm_setting->desc, intf_comm->intf_num, data_setting->desc, intf_data->intf_num, device->dcd->device_is_hs);
1275 
1276     /* create a command endpoint */
1277     comm_desc = (ucdc_comm_desc_t)comm_setting->desc;
1278     eps->ep_cmd = rt_usbd_endpoint_new(&comm_desc->ep_desc, _ep_cmd_handler);
1279     /* add the command endpoint to the cdc communication interface */
1280     rt_usbd_altsetting_add_endpoint(comm_setting, eps->ep_cmd);
1281 
1282     /* add the communication alternate setting to the communication interface,
1283        then set default setting of the interface */
1284     rt_usbd_interface_add_altsetting(intf_comm, comm_setting);
1285     rt_usbd_set_altsetting(intf_comm, 0);
1286     /* add the communication interface to the cdc class */
1287     rt_usbd_function_add_interface(cdc, intf_comm);
1288 
1289     /* create a bulk in and a bulk out endpoint */
1290     data_desc = (ucdc_data_desc_t)data_setting->desc;
1291     eps->ep_out = rt_usbd_endpoint_new(&data_desc->ep_out_desc, _ep_out_handler);
1292     eps->ep_in = rt_usbd_endpoint_new(&data_desc->ep_in_desc, _ep_in_handler);
1293 
1294     /* add the bulk out and bulk in endpoints to the data alternate setting */
1295     rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_in);
1296     rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_out);
1297 
1298     /* add the data alternate setting to the data interface
1299             then set default setting of the interface */
1300     rt_usbd_interface_add_altsetting(intf_data, data_setting);
1301     rt_usbd_set_altsetting(intf_data, 0);
1302 
1303     /* add the cdc data interface to cdc class */
1304     rt_usbd_function_add_interface(cdc, intf_data);
1305 
1306     rt_usbd_os_comp_id_desc_add_os_func_comp_id_desc(device->os_comp_id_desc, &rndis_func_comp_id_desc);
1307 
1308 
1309 #ifdef RT_USING_LWIP
1310 
1311     rt_list_init(&_rndis->response_list);
1312     _rndis->need_notify = RT_TRUE;
1313 
1314     rt_sem_init(&_rndis->tx_buffer_free, "ue_tx", 1, RT_IPC_FLAG_FIFO);
1315 
1316 #ifdef  RNDIS_DELAY_LINK_UP
1317     rt_timer_init(&_rndis->timer,
1318                   "RNDIS",
1319                   timer_timeout,
1320                   _rndis,
1321                   RT_TICK_PER_SECOND * 2,
1322                   RT_TIMER_FLAG_ONE_SHOT);
1323 #endif  /* RNDIS_DELAY_LINK_UP */
1324 
1325     /* OUI 00-00-00, only for test. */
1326     _rndis->dev_addr[0]                 = 0x34;
1327     _rndis->dev_addr[1]                 = 0x97;
1328     _rndis->dev_addr[2]                 = 0xF6;
1329     /* generate random MAC. */
1330     _rndis->dev_addr[3]                 = 0x94;//*(const rt_uint8_t *)(0x1fff7a10);
1331     _rndis->dev_addr[4]                 = 0xEA;//*(const rt_uint8_t *)(0x1fff7a14);
1332     _rndis->dev_addr[5]                 = 0x12;//(const rt_uint8_t *)(0x1fff7a18);
1333     /* OUI 00-00-00, only for test. */
1334     _rndis->host_addr[0]                = 0x34;
1335     _rndis->host_addr[1]                = 0x97;
1336     _rndis->host_addr[2]                = 0xF6;
1337     /* generate random MAC. */
1338     _rndis->host_addr[3]                = 0x94;//*(const rt_uint8_t *)(0x0FE081F0);
1339     _rndis->host_addr[4]                = 0xEA;//*(const rt_uint8_t *)(0x0FE081F1);
1340     _rndis->host_addr[5]                = 0x13;//*(const rt_uint8_t *)(0x0FE081F2);
1341 
1342 #ifdef RT_USING_DEVICE_OPS
1343     _rndis->parent.parent.ops           = &rndis_device_ops;
1344 #else
1345     _rndis->parent.parent.init          = rt_rndis_eth_init;
1346     _rndis->parent.parent.open          = rt_rndis_eth_open;
1347     _rndis->parent.parent.close         = rt_rndis_eth_close;
1348     _rndis->parent.parent.read          = rt_rndis_eth_read;
1349     _rndis->parent.parent.write         = rt_rndis_eth_write;
1350     _rndis->parent.parent.control       = rt_rndis_eth_control;
1351 #endif
1352     _rndis->parent.parent.user_data     = device;
1353 
1354     _rndis->parent.eth_rx               = rt_rndis_eth_rx;
1355     _rndis->parent.eth_tx               = rt_rndis_eth_tx;
1356 
1357     /* register eth device */
1358     eth_device_init(&((rt_rndis_eth_t)cdc->user_data)->parent, "u0");
1359 
1360 #endif /* RT_USING_LWIP */
1361 
1362     return cdc;
1363 }
1364 
1365 struct udclass rndis_class =
1366 {
1367     .rt_usbd_function_create = rt_usbd_function_rndis_create
1368 };
1369 
1370 int rt_usbd_rndis_class_register(void)
1371 {
1372     rt_usbd_class_register(&rndis_class);
1373     return 0;
1374 }
1375 INIT_PREV_EXPORT(rt_usbd_rndis_class_register);