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