]> git.gir.st - tmk_keyboard.git/blob - tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c
Merge commit 'f6d56675f9f981c5464f0ca7a1fbb0162154e8c5'
[tmk_keyboard.git] / tmk_core / protocol / lufa / LUFA-git / LUFA / Drivers / USB / Class / Device / RNDISClassDevice.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2014.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7 */
8
9 /*
10 Copyright 2014 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 disclaims 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->Config.MessageBuffer, 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->Config.MessageBuffer;
96
97 if (!(MessageHeader->MessageLength))
98 {
99 RNDISInterfaceInfo->Config.MessageBuffer[0] = 0;
100 MessageHeader->MessageLength = CPU_TO_LE32(1);
101 }
102
103 Endpoint_ClearSETUP();
104 Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->Config.MessageBuffer, 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 RNDISInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK;
119 RNDISInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
120 RNDISInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT;
121
122 if (RNDISInterfaceInfo->Config.MessageBuffer == NULL)
123 return false;
124
125 if (RNDISInterfaceInfo->Config.MessageBufferLength < RNDIS_DEVICE_MIN_MESSAGE_BUFFER_LENGTH)
126 return false;
127
128 if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataINEndpoint, 1)))
129 return false;
130
131 if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataOUTEndpoint, 1)))
132 return false;
133
134 if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.NotificationEndpoint, 1)))
135 return false;
136
137 return true;
138 }
139
140 void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
141 {
142 if (USB_DeviceState != DEVICE_STATE_Configured)
143 return;
144
145 Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.NotificationEndpoint.Address);
146
147 if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.ResponseReady)
148 {
149 USB_Request_Header_t Notification = (USB_Request_Header_t)
150 {
151 .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
152 .bRequest = RNDIS_NOTIF_ResponseAvailable,
153 .wValue = CPU_TO_LE16(0),
154 .wIndex = CPU_TO_LE16(0),
155 .wLength = CPU_TO_LE16(0),
156 };
157
158 Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL);
159
160 Endpoint_ClearIN();
161
162 RNDISInterfaceInfo->State.ResponseReady = false;
163 }
164 }
165
166 void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
167 {
168 /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
169 this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
170
171 RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)RNDISInterfaceInfo->Config.MessageBuffer;
172
173 switch (le32_to_cpu(MessageHeader->MessageType))
174 {
175 case REMOTE_NDIS_INITIALIZE_MSG:
176 RNDISInterfaceInfo->State.ResponseReady = true;
177
178 RNDIS_Initialize_Message_t* INITIALIZE_Message =
179 (RNDIS_Initialize_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
180 RNDIS_Initialize_Complete_t* INITIALIZE_Response =
181 (RNDIS_Initialize_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
182
183 INITIALIZE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_CMPLT);
184 INITIALIZE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Initialize_Complete_t));
185 INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId;
186 INITIALIZE_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
187
188 INITIALIZE_Response->MajorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR);
189 INITIALIZE_Response->MinorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR);
190 INITIALIZE_Response->DeviceFlags = CPU_TO_LE32(REMOTE_NDIS_DF_CONNECTIONLESS);
191 INITIALIZE_Response->Medium = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3);
192 INITIALIZE_Response->MaxPacketsPerTransfer = CPU_TO_LE32(1);
193 INITIALIZE_Response->MaxTransferSize = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) + ETHERNET_FRAME_SIZE_MAX);
194 INITIALIZE_Response->PacketAlignmentFactor = CPU_TO_LE32(0);
195 INITIALIZE_Response->AFListOffset = CPU_TO_LE32(0);
196 INITIALIZE_Response->AFListSize = CPU_TO_LE32(0);
197
198 RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Initialized;
199 break;
200 case REMOTE_NDIS_HALT_MSG:
201 RNDISInterfaceInfo->State.ResponseReady = false;
202
203 MessageHeader->MessageLength = CPU_TO_LE32(0);
204
205 RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Uninitialized;
206 break;
207 case REMOTE_NDIS_QUERY_MSG:
208 RNDISInterfaceInfo->State.ResponseReady = true;
209
210 RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
211 RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
212 uint32_t Query_Oid = CPU_TO_LE32(QUERY_Message->Oid);
213
214 void* QueryData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Message_Header_t) +
215 le32_to_cpu(QUERY_Message->InformationBufferOffset)];
216 void* ResponseData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Query_Complete_t)];
217 uint16_t ResponseSize;
218
219 QUERY_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_QUERY_CMPLT);
220
221 if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo, Query_Oid, QueryData, le32_to_cpu(QUERY_Message->InformationBufferLength),
222 ResponseData, &ResponseSize))
223 {
224 QUERY_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
225 QUERY_Response->MessageLength = cpu_to_le32(sizeof(RNDIS_Query_Complete_t) + ResponseSize);
226
227 QUERY_Response->InformationBufferLength = CPU_TO_LE32(ResponseSize);
228 QUERY_Response->InformationBufferOffset = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t) - sizeof(RNDIS_Message_Header_t));
229 }
230 else
231 {
232 QUERY_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_NOT_SUPPORTED);
233 QUERY_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t));
234
235 QUERY_Response->InformationBufferLength = CPU_TO_LE32(0);
236 QUERY_Response->InformationBufferOffset = CPU_TO_LE32(0);
237 }
238
239 break;
240 case REMOTE_NDIS_SET_MSG:
241 RNDISInterfaceInfo->State.ResponseReady = true;
242
243 RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
244 RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
245 uint32_t SET_Oid = le32_to_cpu(SET_Message->Oid);
246
247 SET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_SET_CMPLT);
248 SET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Set_Complete_t));
249 SET_Response->RequestId = SET_Message->RequestId;
250
251 void* SetData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Message_Header_t) +
252 le32_to_cpu(SET_Message->InformationBufferOffset)];
253
254 SET_Response->Status = RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData,
255 le32_to_cpu(SET_Message->InformationBufferLength)) ?
256 REMOTE_NDIS_STATUS_SUCCESS : REMOTE_NDIS_STATUS_NOT_SUPPORTED;
257 break;
258 case REMOTE_NDIS_RESET_MSG:
259 RNDISInterfaceInfo->State.ResponseReady = true;
260
261 RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
262
263 RESET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_RESET_CMPLT);
264 RESET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Reset_Complete_t));
265 RESET_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
266 RESET_Response->AddressingReset = CPU_TO_LE32(0);
267
268 break;
269 case REMOTE_NDIS_KEEPALIVE_MSG:
270 RNDISInterfaceInfo->State.ResponseReady = true;
271
272 RNDIS_KeepAlive_Message_t* KEEPALIVE_Message =
273 (RNDIS_KeepAlive_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
274 RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response =
275 (RNDIS_KeepAlive_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
276
277 KEEPALIVE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_CMPLT);
278 KEEPALIVE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Complete_t));
279 KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
280 KEEPALIVE_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
281
282 break;
283 }
284 }
285
286 static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
287 const uint32_t OId,
288 void* const QueryData,
289 const uint16_t QuerySize,
290 void* ResponseData,
291 uint16_t* const ResponseSize)
292 {
293 (void)QueryData;
294 (void)QuerySize;
295
296 switch (OId)
297 {
298 case OID_GEN_SUPPORTED_LIST:
299 *ResponseSize = sizeof(AdapterSupportedOIDList);
300
301 memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
302
303 return true;
304 case OID_GEN_PHYSICAL_MEDIUM:
305 *ResponseSize = sizeof(uint32_t);
306
307 /* Indicate that the device is a true ethernet link */
308 *((uint32_t*)ResponseData) = CPU_TO_LE32(0);
309
310 return true;
311 case OID_GEN_HARDWARE_STATUS:
312 *ResponseSize = sizeof(uint32_t);
313
314 *((uint32_t*)ResponseData) = CPU_TO_LE32(NDIS_HardwareStatus_Ready);
315
316 return true;
317 case OID_GEN_MEDIA_SUPPORTED:
318 case OID_GEN_MEDIA_IN_USE:
319 *ResponseSize = sizeof(uint32_t);
320
321 *((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3);
322
323 return true;
324 case OID_GEN_VENDOR_ID:
325 *ResponseSize = sizeof(uint32_t);
326
327 /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
328 *((uint32_t*)ResponseData) = CPU_TO_LE32(0x00FFFFFF);
329
330 return true;
331 case OID_GEN_MAXIMUM_FRAME_SIZE:
332 case OID_GEN_TRANSMIT_BLOCK_SIZE:
333 case OID_GEN_RECEIVE_BLOCK_SIZE:
334 *ResponseSize = sizeof(uint32_t);
335
336 *((uint32_t*)ResponseData) = CPU_TO_LE32(ETHERNET_FRAME_SIZE_MAX);
337
338 return true;
339 case OID_GEN_VENDOR_DESCRIPTION:
340 *ResponseSize = (strlen(RNDISInterfaceInfo->Config.AdapterVendorDescription) + 1);
341
342 memcpy(ResponseData, RNDISInterfaceInfo->Config.AdapterVendorDescription, *ResponseSize);
343
344 return true;
345 case OID_GEN_MEDIA_CONNECT_STATUS:
346 *ResponseSize = sizeof(uint32_t);
347
348 *((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIA_STATE_CONNECTED);
349
350 return true;
351 case OID_GEN_LINK_SPEED:
352 *ResponseSize = sizeof(uint32_t);
353
354 /* Indicate 10Mb/s link speed */
355 *((uint32_t*)ResponseData) = CPU_TO_LE32(100000);
356
357 return true;
358 case OID_802_3_PERMANENT_ADDRESS:
359 case OID_802_3_CURRENT_ADDRESS:
360 *ResponseSize = sizeof(MAC_Address_t);
361
362 memcpy(ResponseData, &RNDISInterfaceInfo->Config.AdapterMACAddress, sizeof(MAC_Address_t));
363
364 return true;
365 case OID_802_3_MAXIMUM_LIST_SIZE:
366 *ResponseSize = sizeof(uint32_t);
367
368 /* Indicate only one multicast address supported */
369 *((uint32_t*)ResponseData) = CPU_TO_LE32(1);
370
371 return true;
372 case OID_GEN_CURRENT_PACKET_FILTER:
373 *ResponseSize = sizeof(uint32_t);
374
375 *((uint32_t*)ResponseData) = cpu_to_le32(RNDISInterfaceInfo->State.CurrPacketFilter);
376
377 return true;
378 case OID_GEN_XMIT_OK:
379 case OID_GEN_RCV_OK:
380 case OID_GEN_XMIT_ERROR:
381 case OID_GEN_RCV_ERROR:
382 case OID_GEN_RCV_NO_BUFFER:
383 case OID_802_3_RCV_ERROR_ALIGNMENT:
384 case OID_802_3_XMIT_ONE_COLLISION:
385 case OID_802_3_XMIT_MORE_COLLISIONS:
386 *ResponseSize = sizeof(uint32_t);
387
388 /* Unused statistic OIDs - always return 0 for each */
389 *((uint32_t*)ResponseData) = CPU_TO_LE32(0);
390
391 return true;
392 case OID_GEN_MAXIMUM_TOTAL_SIZE:
393 *ResponseSize = sizeof(uint32_t);
394
395 /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
396 *((uint32_t*)ResponseData) = CPU_TO_LE32(RNDISInterfaceInfo->Config.MessageBufferLength + ETHERNET_FRAME_SIZE_MAX);
397
398 return true;
399 default:
400 return false;
401 }
402 }
403
404 static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
405 const uint32_t OId,
406 const void* SetData,
407 const uint16_t SetSize)
408 {
409 (void)SetSize;
410
411 switch (OId)
412 {
413 case OID_GEN_CURRENT_PACKET_FILTER:
414 RNDISInterfaceInfo->State.CurrPacketFilter = le32_to_cpu(*((uint32_t*)SetData));
415 RNDISInterfaceInfo->State.CurrRNDISState = (RNDISInterfaceInfo->State.CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Initialized;
416
417 return true;
418 case OID_802_3_MULTICAST_LIST:
419 /* Do nothing - throw away the value from the host as it is unused */
420
421 return true;
422 default:
423 return false;
424 }
425 }
426
427 bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
428 {
429 if ((USB_DeviceState != DEVICE_STATE_Configured) ||
430 (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
431 {
432 return false;
433 }
434
435 Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpoint.Address);
436 return Endpoint_IsOUTReceived();
437 }
438
439 uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
440 void* Buffer,
441 uint16_t* const PacketLength)
442 {
443 if ((USB_DeviceState != DEVICE_STATE_Configured) ||
444 (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
445 {
446 return ENDPOINT_RWSTREAM_DeviceDisconnected;
447 }
448
449 Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpoint.Address);
450
451 *PacketLength = 0;
452
453 if (!(Endpoint_IsOUTReceived()))
454 return ENDPOINT_RWSTREAM_NoError;
455
456 RNDIS_Packet_Message_t RNDISPacketHeader;
457 Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL);
458
459 if (le32_to_cpu(RNDISPacketHeader.DataLength) > ETHERNET_FRAME_SIZE_MAX)
460 {
461 Endpoint_StallTransaction();
462
463 return RNDIS_ERROR_LOGICAL_CMD_FAILED;
464 }
465
466 *PacketLength = (uint16_t)le32_to_cpu(RNDISPacketHeader.DataLength);
467
468 Endpoint_Read_Stream_LE(Buffer, *PacketLength, NULL);
469 Endpoint_ClearOUT();
470
471 return ENDPOINT_RWSTREAM_NoError;
472 }
473
474 uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
475 void* Buffer,
476 const uint16_t PacketLength)
477 {
478 uint8_t ErrorCode;
479
480 if ((USB_DeviceState != DEVICE_STATE_Configured) ||
481 (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
482 {
483 return ENDPOINT_RWSTREAM_DeviceDisconnected;
484 }
485
486 Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataINEndpoint.Address);
487
488 if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
489 return ErrorCode;
490
491 RNDIS_Packet_Message_t RNDISPacketHeader;
492
493 memset(&RNDISPacketHeader, 0, sizeof(RNDIS_Packet_Message_t));
494
495 RNDISPacketHeader.MessageType = CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG);
496 RNDISPacketHeader.MessageLength = cpu_to_le32(sizeof(RNDIS_Packet_Message_t) + PacketLength);
497 RNDISPacketHeader.DataOffset = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
498 RNDISPacketHeader.DataLength = cpu_to_le32(PacketLength);
499
500 Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL);
501 Endpoint_Write_Stream_LE(Buffer, PacketLength, NULL);
502 Endpoint_ClearIN();
503
504 return ENDPOINT_RWSTREAM_NoError;
505 }
506
507 #endif
508
Imprint / Impressum