| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
RNDISClassDevice.c
Go to the documentation of this file.
1 /*
2 * @brief Device mode driver for the library USB RNDIS Class driver
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * Copyright(C) Dean Camera, 2011, 2012
7 * All rights reserved.
8 *
9 * @par
10 * Software that is described herein is for illustrative purposes only
11 * which provides customers with programming information regarding the
12 * LPC products. This software is supplied "AS IS" without any warranties of
13 * any kind, and NXP Semiconductors and its licensor disclaim any and
14 * all warranties, express or implied, including all implied warranties of
15 * merchantability, fitness for a particular purpose and non-infringement of
16 * intellectual property rights. NXP Semiconductors assumes no responsibility
17 * or liability for the use of the software, conveys no license or rights under any
18 * patent, copyright, mask work right, or any other intellectual property rights in
19 * or to any products. NXP Semiconductors reserves the right to make changes
20 * in the software without notification. NXP Semiconductors also makes no
21 * representation or warranty that such application will be suitable for the
22 * specified use without further testing or modification.
23 *
24 * @par
25 * Permission to use, copy, modify, and distribute this software and its
26 * documentation is hereby granted, under NXP Semiconductors' and its
27 * licensor's relevant copyrights in the software, without fee, provided that it
28 * is used in conjunction with NXP Semiconductors microcontrollers. This
29 * copyright, permission, and disclaimer notice must appear in all copies of
30 * this code.
31 */
32
33 #define __INCLUDE_FROM_USB_DRIVER
34 #include "../../Core/USBMode.h"
35
36 #if defined(USB_CAN_BE_DEVICE)
37
38 #define __INCLUDE_FROM_RNDIS_DRIVER
39 #define __INCLUDE_FROM_RNDIS_DEVICE_C
40 #include "RNDISClassDevice.h"
41
42 static uint32_t PROGMEM AdapterSupportedOIDList[] =
43 {
44 CPU_TO_LE32(OID_GEN_SUPPORTED_LIST),
45 CPU_TO_LE32(OID_GEN_PHYSICAL_MEDIUM),
46 CPU_TO_LE32(OID_GEN_HARDWARE_STATUS),
47 CPU_TO_LE32(OID_GEN_MEDIA_SUPPORTED),
48 CPU_TO_LE32(OID_GEN_MEDIA_IN_USE),
49 CPU_TO_LE32(OID_GEN_MAXIMUM_FRAME_SIZE),
50 CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE),
51 CPU_TO_LE32(OID_GEN_LINK_SPEED),
52 CPU_TO_LE32(OID_GEN_TRANSMIT_BLOCK_SIZE),
53 CPU_TO_LE32(OID_GEN_RECEIVE_BLOCK_SIZE),
54 CPU_TO_LE32(OID_GEN_VENDOR_ID),
55 CPU_TO_LE32(OID_GEN_VENDOR_DESCRIPTION),
56 CPU_TO_LE32(OID_GEN_CURRENT_PACKET_FILTER),
57 CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE),
58 CPU_TO_LE32(OID_GEN_MEDIA_CONNECT_STATUS),
59 CPU_TO_LE32(OID_GEN_XMIT_OK),
60 CPU_TO_LE32(OID_GEN_RCV_OK),
61 CPU_TO_LE32(OID_GEN_XMIT_ERROR),
62 CPU_TO_LE32(OID_GEN_RCV_ERROR),
63 CPU_TO_LE32(OID_GEN_RCV_NO_BUFFER),
64 CPU_TO_LE32(OID_802_3_PERMANENT_ADDRESS),
65 CPU_TO_LE32(OID_802_3_CURRENT_ADDRESS),
66 CPU_TO_LE32(OID_802_3_MULTICAST_LIST),
67 CPU_TO_LE32(OID_802_3_MAXIMUM_LIST_SIZE),
68 CPU_TO_LE32(OID_802_3_RCV_ERROR_ALIGNMENT),
69 CPU_TO_LE32(OID_802_3_XMIT_ONE_COLLISION),
70 CPU_TO_LE32(OID_802_3_XMIT_MORE_COLLISIONS),
71 };
72
73 void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
74 {
75 if (!(Endpoint_IsSETUPReceived(RNDISInterfaceInfo->Config.PortNumber)))
76 return;
77
78 if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->Config.ControlInterfaceNumber)
79 return;
80
81 switch (USB_ControlRequest.bRequest)
82 {
83 case RNDIS_REQ_SendEncapsulatedCommand:
84 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
85 {
86 Endpoint_ClearSETUP(RNDISInterfaceInfo->Config.PortNumber);
87 Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->Config.PortNumber, RNDISInterfaceInfo->State.RNDISMessageBuffer, USB_ControlRequest.wLength);
88 Endpoint_ClearIN(RNDISInterfaceInfo->Config.PortNumber);
89
90 RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo);
91 }
92
93 break;
94 case RNDIS_REQ_GetEncapsulatedResponse:
95 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
96 {
97 RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
98
99 if (!(MessageHeader->MessageLength))
100 {
101 RNDISInterfaceInfo->State.RNDISMessageBuffer[0] = 0;
102 MessageHeader->MessageLength = CPU_TO_LE32(1);
103 }
104
105 Endpoint_ClearSETUP(RNDISInterfaceInfo->Config.PortNumber);
106 Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->Config.PortNumber, RNDISInterfaceInfo->State.RNDISMessageBuffer, le32_to_cpu(MessageHeader->MessageLength));
107 Endpoint_ClearOUT(RNDISInterfaceInfo->Config.PortNumber);
108
109 MessageHeader->MessageLength = CPU_TO_LE32(0);
110 }
111
112 break;
113 }
114 }
115
116 bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
117 {
118 memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State));
119
120 for (uint8_t EndpointNum = 1; EndpointNum < ENDPOINT_TOTAL_ENDPOINTS(RNDISInterfaceInfo->Config.PortNumber); EndpointNum++)
121 {
122 uint16_t Size;
123 uint8_t Type;
124 uint8_t Direction;
125 bool DoubleBanked;
126
127 if (EndpointNum == RNDISInterfaceInfo->Config.DataINEndpointNumber)
128 {
129 Size = RNDISInterfaceInfo->Config.DataINEndpointSize;
130 Direction = ENDPOINT_DIR_IN;
131 Type = EP_TYPE_BULK;
132 DoubleBanked = RNDISInterfaceInfo->Config.DataINEndpointDoubleBank;
133 }
134 else if (EndpointNum == RNDISInterfaceInfo->Config.DataOUTEndpointNumber)
135 {
136 Size = RNDISInterfaceInfo->Config.DataOUTEndpointSize;
137 Direction = ENDPOINT_DIR_OUT;
138 Type = EP_TYPE_BULK;
139 DoubleBanked = RNDISInterfaceInfo->Config.DataOUTEndpointDoubleBank;
140 }
141 else if (EndpointNum == RNDISInterfaceInfo->Config.NotificationEndpointNumber)
142 {
143 Size = RNDISInterfaceInfo->Config.NotificationEndpointSize;
144 Direction = ENDPOINT_DIR_IN;
145 Type = EP_TYPE_INTERRUPT;
146 DoubleBanked = RNDISInterfaceInfo->Config.NotificationEndpointDoubleBank;
147 }
148 else
149 {
150 continue;
151 }
152
153 if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->Config.PortNumber, EndpointNum, Type, Direction, Size,
154 DoubleBanked ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
155 {
156 return false;
157 }
158 }
159
160 return true;
161 }
162
163 void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
164 {
165 if (USB_DeviceState[RNDISInterfaceInfo->Config.PortNumber] != DEVICE_STATE_Configured)
166 return;
167
168 Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.PortNumber, RNDISInterfaceInfo->Config.NotificationEndpointNumber);
169
170 if (Endpoint_IsINReady(RNDISInterfaceInfo->Config.PortNumber) && RNDISInterfaceInfo->State.ResponseReady)
171 {
172 USB_Request_Header_t Notification = (USB_Request_Header_t)
173 {
174 .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
175 .bRequest = RNDIS_NOTIF_ResponseAvailable,
176 .wValue = CPU_TO_LE16(0),
177 .wIndex = CPU_TO_LE16(0),
178 .wLength = CPU_TO_LE16(0),
179 };
180
181 Endpoint_Write_Stream_LE(RNDISInterfaceInfo->Config.PortNumber, &Notification, sizeof(USB_Request_Header_t), NULL);
182
183 Endpoint_ClearIN(RNDISInterfaceInfo->Config.PortNumber);
184
185 RNDISInterfaceInfo->State.ResponseReady = false;
186 }
187 }
188
189 void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
190 {
191 /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
192 this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
193
194 RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
195
196 switch (le32_to_cpu(MessageHeader->MessageType))
197 {
198 case REMOTE_NDIS_INITIALIZE_MSG:
199 {
200 RNDISInterfaceInfo->State.ResponseReady = true;
201
202 RNDIS_Initialize_Message_t* INITIALIZE_Message =
203 (RNDIS_Initialize_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
204 RNDIS_Initialize_Complete_t* INITIALIZE_Response =
205 (RNDIS_Initialize_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
206
207 INITIALIZE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_CMPLT);
208 INITIALIZE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Initialize_Complete_t));
209 INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId;
210 INITIALIZE_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
211
212 INITIALIZE_Response->MajorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR);
213 INITIALIZE_Response->MinorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR);
214 INITIALIZE_Response->DeviceFlags = CPU_TO_LE32(REMOTE_NDIS_DF_CONNECTIONLESS);
215 INITIALIZE_Response->Medium = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3);
216 INITIALIZE_Response->MaxPacketsPerTransfer = CPU_TO_LE32(1);
217 INITIALIZE_Response->MaxTransferSize = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) + ETHERNET_FRAME_SIZE_MAX);
218 INITIALIZE_Response->PacketAlignmentFactor = CPU_TO_LE32(0);
219 INITIALIZE_Response->AFListOffset = CPU_TO_LE32(0);
220 INITIALIZE_Response->AFListSize = CPU_TO_LE32(0);
221
222 RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Initialized;
223 break;
224 }
225 case REMOTE_NDIS_HALT_MSG:
226 {
227 RNDISInterfaceInfo->State.ResponseReady = false;
228
229 MessageHeader->MessageLength = CPU_TO_LE32(0);
230
231 RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Uninitialized;
232 break;
233 }
234 case REMOTE_NDIS_QUERY_MSG:
235 {
236 RNDISInterfaceInfo->State.ResponseReady = true;
237
238 RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
239 RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
240 uint32_t Query_Oid = CPU_TO_LE32(QUERY_Message->Oid);
241
242 void* QueryData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
243 le32_to_cpu(QUERY_Message->InformationBufferOffset)];
244 void* ResponseData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Query_Complete_t)];
245 uint16_t ResponseSize;
246
247 QUERY_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_QUERY_CMPLT);
248
249 if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo, Query_Oid, QueryData, le32_to_cpu(QUERY_Message->InformationBufferLength),
250 ResponseData, &ResponseSize))
251 {
252 QUERY_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
253 QUERY_Response->MessageLength = cpu_to_le32(sizeof(RNDIS_Query_Complete_t) + ResponseSize);
254
255 QUERY_Response->InformationBufferLength = CPU_TO_LE32(ResponseSize);
256 QUERY_Response->InformationBufferOffset = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t) - sizeof(RNDIS_Message_Header_t));
257 }
258 else
259 {
260 QUERY_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_NOT_SUPPORTED);
261 QUERY_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t));
262
263 QUERY_Response->InformationBufferLength = CPU_TO_LE32(0);
264 QUERY_Response->InformationBufferOffset = CPU_TO_LE32(0);
265 }
266
267 break;
268 }
269 case REMOTE_NDIS_SET_MSG:
270 {
271 RNDISInterfaceInfo->State.ResponseReady = true;
272
273 RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
274 RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
275 uint32_t SET_Oid = le32_to_cpu(SET_Message->Oid);
276
277 SET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_SET_CMPLT);
278 SET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Set_Complete_t));
279 SET_Response->RequestId = SET_Message->RequestId;
280
281 void* SetData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
282 le32_to_cpu(SET_Message->InformationBufferOffset)];
283
284 SET_Response->Status = RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData,
285 le32_to_cpu(SET_Message->InformationBufferLength)) ?
286 REMOTE_NDIS_STATUS_SUCCESS : REMOTE_NDIS_STATUS_NOT_SUPPORTED;
287 break;
288 }
289 case REMOTE_NDIS_RESET_MSG:
290 {
291 RNDISInterfaceInfo->State.ResponseReady = true;
292
293 RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
294
295 RESET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_RESET_CMPLT);
296 RESET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Reset_Complete_t));
297 RESET_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
298 RESET_Response->AddressingReset = CPU_TO_LE32(0);
299
300 break;
301 }
302 case REMOTE_NDIS_KEEPALIVE_MSG:
303 {
304 RNDISInterfaceInfo->State.ResponseReady = true;
305
306 RNDIS_KeepAlive_Message_t* KEEPALIVE_Message =
307 (RNDIS_KeepAlive_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
308 RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response =
309 (RNDIS_KeepAlive_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
310
311 KEEPALIVE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_CMPLT);
312 KEEPALIVE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Complete_t));
313 KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
314 KEEPALIVE_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
315
316 break;
317 }
318 }
319 }
320
321 static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
322 const uint32_t OId,
323 void* const QueryData,
324 const uint16_t QuerySize,
325 void* ResponseData,
326 uint16_t* const ResponseSize)
327 {
328 (void)QueryData;
329 (void)QuerySize;
330
331 switch (OId)
332 {
333 case OID_GEN_SUPPORTED_LIST:
334 *ResponseSize = sizeof(AdapterSupportedOIDList);
335
336 memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
337
338 return true;
339 case OID_GEN_PHYSICAL_MEDIUM:
340 *ResponseSize = sizeof(uint32_t);
341
342 /* Indicate that the device is a true ethernet link */
343 *((uint32_t*)ResponseData) = CPU_TO_LE32(0);
344
345 return true;
346 case OID_GEN_HARDWARE_STATUS:
347 *ResponseSize = sizeof(uint32_t);
348
349 *((uint32_t*)ResponseData) = CPU_TO_LE32(NDIS_HardwareStatus_Ready);
350
351 return true;
352 case OID_GEN_MEDIA_SUPPORTED:
353 case OID_GEN_MEDIA_IN_USE:
354 *ResponseSize = sizeof(uint32_t);
355
356 *((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3);
357
358 return true;
359 case OID_GEN_VENDOR_ID:
360 *ResponseSize = sizeof(uint32_t);
361
362 /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
363 *((uint32_t*)ResponseData) = CPU_TO_LE32(0x00FFFFFF);
364
365 return true;
366 case OID_GEN_MAXIMUM_FRAME_SIZE:
367 case OID_GEN_TRANSMIT_BLOCK_SIZE:
368 case OID_GEN_RECEIVE_BLOCK_SIZE:
369 *ResponseSize = sizeof(uint32_t);
370
371 *((uint32_t*)ResponseData) = CPU_TO_LE32(ETHERNET_FRAME_SIZE_MAX);
372
373 return true;
374 case OID_GEN_VENDOR_DESCRIPTION:
375 *ResponseSize = (strlen(RNDISInterfaceInfo->Config.AdapterVendorDescription) + 1);
376
377 memcpy(ResponseData, RNDISInterfaceInfo->Config.AdapterVendorDescription, *ResponseSize);
378
379 return true;
380 case OID_GEN_MEDIA_CONNECT_STATUS:
381 *ResponseSize = sizeof(uint32_t);
382
383 *((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIA_STATE_CONNECTED);
384
385 return true;
386 case OID_GEN_LINK_SPEED:
387 *ResponseSize = sizeof(uint32_t);
388
389 /* Indicate 10Mb/s link speed */
390 *((uint32_t*)ResponseData) = CPU_TO_LE32(100000);
391
392 return true;
393 case OID_802_3_PERMANENT_ADDRESS:
394 case OID_802_3_CURRENT_ADDRESS:
395 *ResponseSize = sizeof(MAC_Address_t);
396
397 memcpy(ResponseData, &RNDISInterfaceInfo->Config.AdapterMACAddress, sizeof(MAC_Address_t));
398
399 return true;
400 case OID_802_3_MAXIMUM_LIST_SIZE:
401 *ResponseSize = sizeof(uint32_t);
402
403 /* Indicate only one multicast address supported */
404 *((uint32_t*)ResponseData) = CPU_TO_LE32(1);
405
406 return true;
407 case OID_GEN_CURRENT_PACKET_FILTER:
408 *ResponseSize = sizeof(uint32_t);
409
410 *((uint32_t*)ResponseData) = cpu_to_le32(RNDISInterfaceInfo->State.CurrPacketFilter);
411
412 return true;
413 case OID_GEN_XMIT_OK:
414 case OID_GEN_RCV_OK:
415 case OID_GEN_XMIT_ERROR:
416 case OID_GEN_RCV_ERROR:
417 case OID_GEN_RCV_NO_BUFFER:
418 case OID_802_3_RCV_ERROR_ALIGNMENT:
419 case OID_802_3_XMIT_ONE_COLLISION:
420 case OID_802_3_XMIT_MORE_COLLISIONS:
421 *ResponseSize = sizeof(uint32_t);
422
423 /* Unused statistic OIDs - always return 0 for each */
424 *((uint32_t*)ResponseData) = CPU_TO_LE32(0);
425
426 return true;
427 case OID_GEN_MAXIMUM_TOTAL_SIZE:
428 *ResponseSize = sizeof(uint32_t);
429
430 /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
431 *((uint32_t*)ResponseData) = CPU_TO_LE32(RNDIS_MESSAGE_BUFFER_SIZE + ETHERNET_FRAME_SIZE_MAX);
432
433 return true;
434 default:
435 return false;
436 }
437 }
438
439 static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
440 const uint32_t OId,
441 const void* SetData,
442 const uint16_t SetSize)
443 {
444 (void)SetSize;
445
446 switch (OId)
447 {
448 case OID_GEN_CURRENT_PACKET_FILTER:
449 RNDISInterfaceInfo->State.CurrPacketFilter = le32_to_cpu(*((uint32_t*)SetData));
450 RNDISInterfaceInfo->State.CurrRNDISState = le32_to_cpu((RNDISInterfaceInfo->State.CurrPacketFilter) ?
451 RNDIS_Data_Initialized : RNDIS_Data_Initialized);
452
453 return true;
454 case OID_802_3_MULTICAST_LIST:
455 /* Do nothing - throw away the value from the host as it is unused */
456
457 return true;
458 default:
459 return false;
460 }
461 }
462
463 bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
464 {
465 if ((USB_DeviceState[RNDISInterfaceInfo->Config.PortNumber] != DEVICE_STATE_Configured) ||
466 (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
467 {
468 return false;
469 }
470
471 Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.PortNumber, RNDISInterfaceInfo->Config.DataOUTEndpointNumber);
472 return Endpoint_IsOUTReceived(RNDISInterfaceInfo->Config.PortNumber);
473 }
474
475 uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
476 void* Buffer,
477 uint16_t* const PacketLength)
478 {
479 if ((USB_DeviceState[RNDISInterfaceInfo->Config.PortNumber] != DEVICE_STATE_Configured) ||
480 (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
481 {
482 return ENDPOINT_RWSTREAM_DeviceDisconnected;
483 }
484
485 Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.PortNumber, RNDISInterfaceInfo->Config.DataOUTEndpointNumber);
486
487 *PacketLength = 0;
488
489 if (!(Endpoint_IsOUTReceived(RNDISInterfaceInfo->Config.PortNumber)))
490 return ENDPOINT_RWSTREAM_NoError;
491
492 RNDIS_Packet_Message_t RNDISPacketHeader;
493 Endpoint_Read_Stream_LE(RNDISInterfaceInfo->Config.PortNumber, &RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL);
494
495 if (le32_to_cpu(RNDISPacketHeader.DataLength) > ETHERNET_FRAME_SIZE_MAX)
496 {
497 Endpoint_StallTransaction(RNDISInterfaceInfo->Config.PortNumber);
498
499 return RNDIS_ERROR_LOGICAL_CMD_FAILED;
500 }
501
502 *PacketLength = (uint16_t)le32_to_cpu(RNDISPacketHeader.DataLength);
503
504 Endpoint_Read_Stream_LE(RNDISInterfaceInfo->Config.PortNumber, Buffer, *PacketLength, NULL);
505 Endpoint_ClearOUT(RNDISInterfaceInfo->Config.PortNumber);
506
507 return ENDPOINT_RWSTREAM_NoError;
508 }
509
510 uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
511 void* Buffer,
512 const uint16_t PacketLength)
513 {
514 uint8_t ErrorCode;
515
516 if ((USB_DeviceState[RNDISInterfaceInfo->Config.PortNumber] != DEVICE_STATE_Configured) ||
517 (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
518 {
519 return ENDPOINT_RWSTREAM_DeviceDisconnected;
520 }
521
522 Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.PortNumber, RNDISInterfaceInfo->Config.DataINEndpointNumber);
523
524 if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
525 return ErrorCode;
526
527 RNDIS_Packet_Message_t RNDISPacketHeader;
528
529 memset(&RNDISPacketHeader, 0, sizeof(RNDIS_Packet_Message_t));
530
531 RNDISPacketHeader.MessageType = CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG);
532 RNDISPacketHeader.MessageLength = cpu_to_le32(sizeof(RNDIS_Packet_Message_t) + PacketLength);
533 RNDISPacketHeader.DataOffset = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
534 RNDISPacketHeader.DataLength = cpu_to_le32(PacketLength);
535
536 Endpoint_Write_Stream_LE(RNDISInterfaceInfo->Config.PortNumber, &RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL);
537 Endpoint_Write_Stream_LE(RNDISInterfaceInfo->Config.PortNumber, Buffer, PacketLength, NULL);
538 Endpoint_ClearIN(RNDISInterfaceInfo->Config.PortNumber);
539
540 return ENDPOINT_RWSTREAM_NoError;
541 }
542
543 #endif
544