1
0

rndis.c 37 KB

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