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