Statistics
| Branch: | Tag: | Revision:

root / LUFA / Drivers / USB / Class / Device / RNDIS.c @ 978b99e5

History | View | Annotate | Download (19.8 KB)

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 "RNDIS.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