]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Class/Host/RNDISClassHost.c
Merge commit 'f6d56675f9f981c5464f0ca7a1fbb0162154e8c5'
[qmk_firmware.git] / tmk_core / protocol / lufa / LUFA-git / LUFA / Drivers / USB / Class / Host / RNDISClassHost.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_HOST)
35
36 #define  __INCLUDE_FROM_RNDIS_DRIVER
37 #define  __INCLUDE_FROM_RNDIS_HOST_C
38 #include "RNDISClassHost.h"
39
40 uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
41                                   uint16_t ConfigDescriptorSize,
42                                   void* ConfigDescriptorData)
43 {
44         USB_Descriptor_Endpoint_t*  DataINEndpoint        = NULL;
45         USB_Descriptor_Endpoint_t*  DataOUTEndpoint       = NULL;
46         USB_Descriptor_Endpoint_t*  NotificationEndpoint  = NULL;
47         USB_Descriptor_Interface_t* RNDISControlInterface = NULL;
48
49         memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State));
50
51         if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
52           return RNDIS_ENUMERROR_InvalidConfigDescriptor;
53
54         RNDISControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
55
56         while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(NotificationEndpoint))
57         {
58                 if (!(RNDISControlInterface) ||
59                     USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
60                                               DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
61                 {
62                         if (NotificationEndpoint)
63                         {
64                                 if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
65                                                                                           DCOMP_RNDIS_Host_NextRNDISDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
66                                 {
67                                         return RNDIS_ENUMERROR_NoCompatibleInterfaceFound;
68                                 }
69
70                                 DataINEndpoint  = NULL;
71                                 DataOUTEndpoint = NULL;
72                         }
73                         else
74                         {
75                                 if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
76                                                                                           DCOMP_RNDIS_Host_NextRNDISControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
77                                 {
78                                         return RNDIS_ENUMERROR_NoCompatibleInterfaceFound;
79                                 }
80
81                                 RNDISControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
82
83                                 NotificationEndpoint = NULL;
84                         }
85
86                         continue;
87                 }
88
89                 USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
90
91                 if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
92                 {
93                         if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
94                           NotificationEndpoint = EndpointData;
95                         else
96                           DataINEndpoint = EndpointData;
97                 }
98                 else
99                 {
100                         DataOUTEndpoint = EndpointData;
101                 }
102         }
103
104         RNDISInterfaceInfo->Config.DataINPipe.Size  = le16_to_cpu(DataINEndpoint->EndpointSize);
105         RNDISInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress;
106         RNDISInterfaceInfo->Config.DataINPipe.Type  = EP_TYPE_BULK;
107
108         RNDISInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
109         RNDISInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress;
110         RNDISInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK;
111
112         RNDISInterfaceInfo->Config.NotificationPipe.Size = le16_to_cpu(NotificationEndpoint->EndpointSize);
113         RNDISInterfaceInfo->Config.NotificationPipe.EndpointAddress = NotificationEndpoint->EndpointAddress;
114         RNDISInterfaceInfo->Config.NotificationPipe.Type = EP_TYPE_INTERRUPT;
115
116         if (!(Pipe_ConfigurePipeTable(&RNDISInterfaceInfo->Config.DataINPipe, 1)))
117           return RNDIS_ENUMERROR_PipeConfigurationFailed;
118
119         if (!(Pipe_ConfigurePipeTable(&RNDISInterfaceInfo->Config.DataOUTPipe, 1)))
120           return RNDIS_ENUMERROR_PipeConfigurationFailed;
121
122         if (!(Pipe_ConfigurePipeTable(&RNDISInterfaceInfo->Config.NotificationPipe, 1)))
123           return RNDIS_ENUMERROR_PipeConfigurationFailed;
124
125         RNDISInterfaceInfo->State.ControlInterfaceNumber = RNDISControlInterface->InterfaceNumber;
126         RNDISInterfaceInfo->State.IsActive = true;
127
128         return RNDIS_ENUMERROR_NoError;
129 }
130
131 static uint8_t DCOMP_RNDIS_Host_NextRNDISControlInterface(void* const CurrentDescriptor)
132 {
133         USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
134
135         if (Header->Type == DTYPE_Interface)
136         {
137                 USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
138
139                 if ((Interface->Class    == CDC_CSCP_CDCClass)    &&
140                     (Interface->SubClass == CDC_CSCP_ACMSubclass) &&
141                     (Interface->Protocol == CDC_CSCP_VendorSpecificProtocol))
142                 {
143                         return DESCRIPTOR_SEARCH_Found;
144                 }
145         }
146
147         return DESCRIPTOR_SEARCH_NotFound;
148 }
149
150 static uint8_t DCOMP_RNDIS_Host_NextRNDISDataInterface(void* const CurrentDescriptor)
151 {
152         USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
153
154         if (Header->Type == DTYPE_Interface)
155         {
156                 USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor,
157                                                                          USB_Descriptor_Interface_t);
158
159                 if ((Interface->Class    == CDC_CSCP_CDCDataClass)   &&
160                     (Interface->SubClass == CDC_CSCP_NoDataSubclass) &&
161                     (Interface->Protocol == CDC_CSCP_NoDataProtocol))
162                 {
163                         return DESCRIPTOR_SEARCH_Found;
164                 }
165         }
166
167         return DESCRIPTOR_SEARCH_NotFound;
168 }
169
170 static uint8_t DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint(void* const CurrentDescriptor)
171 {
172         USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
173
174         if (Header->Type == DTYPE_Endpoint)
175         {
176                 USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
177
178                 uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);
179
180                 if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) &&
181                     !(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))
182                 {
183                         return DESCRIPTOR_SEARCH_Found;
184                 }
185         }
186         else if (Header->Type == DTYPE_Interface)
187         {
188                 return DESCRIPTOR_SEARCH_Fail;
189         }
190
191         return DESCRIPTOR_SEARCH_NotFound;
192 }
193
194 static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
195                                              void* Buffer,
196                                              const uint16_t Length)
197 {
198         USB_ControlRequest = (USB_Request_Header_t)
199                 {
200                         .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
201                         .bRequest      = RNDIS_REQ_SendEncapsulatedCommand,
202                         .wValue        = 0,
203                         .wIndex        = RNDISInterfaceInfo->State.ControlInterfaceNumber,
204                         .wLength       = Length,
205                 };
206
207         Pipe_SelectPipe(PIPE_CONTROLPIPE);
208
209         return USB_Host_SendControlRequest(Buffer);
210 }
211
212 static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
213                                              void* Buffer,
214                                              const uint16_t Length)
215 {
216         USB_ControlRequest = (USB_Request_Header_t)
217                 {
218                         .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
219                         .bRequest      = RNDIS_REQ_GetEncapsulatedResponse,
220                         .wValue        = 0,
221                         .wIndex        = RNDISInterfaceInfo->State.ControlInterfaceNumber,
222                         .wLength       = Length,
223                 };
224
225         Pipe_SelectPipe(PIPE_CONTROLPIPE);
226
227         return USB_Host_SendControlRequest(Buffer);
228 }
229
230 uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
231 {
232         uint8_t ErrorCode;
233
234         RNDIS_KeepAlive_Message_t  KeepAliveMessage;
235         RNDIS_KeepAlive_Complete_t KeepAliveMessageResponse;
236
237         KeepAliveMessage.MessageType     = CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_MSG);
238         KeepAliveMessage.MessageLength   = CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Message_t));
239         KeepAliveMessage.RequestId       = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++);
240
241         if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &KeepAliveMessage,
242                                                        sizeof(RNDIS_KeepAlive_Message_t))) != HOST_SENDCONTROL_Successful)
243         {
244                 return ErrorCode;
245         }
246
247         if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &KeepAliveMessageResponse,
248                                                        sizeof(RNDIS_KeepAlive_Complete_t))) != HOST_SENDCONTROL_Successful)
249         {
250                 return ErrorCode;
251         }
252
253         return HOST_SENDCONTROL_Successful;
254 }
255
256 uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
257 {
258         uint8_t ErrorCode;
259
260         RNDIS_Initialize_Message_t  InitMessage;
261         RNDIS_Initialize_Complete_t InitMessageResponse;
262
263         InitMessage.MessageType     = CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_MSG);
264         InitMessage.MessageLength   = CPU_TO_LE32(sizeof(RNDIS_Initialize_Message_t));
265         InitMessage.RequestId       = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++);
266
267         InitMessage.MajorVersion    = CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR);
268         InitMessage.MinorVersion    = CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR);
269         InitMessage.MaxTransferSize = cpu_to_le32(RNDISInterfaceInfo->Config.HostMaxPacketSize);
270
271         if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &InitMessage,
272                                                        sizeof(RNDIS_Initialize_Message_t))) != HOST_SENDCONTROL_Successful)
273         {
274                 return ErrorCode;
275         }
276
277         if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &InitMessageResponse,
278                                                        sizeof(RNDIS_Initialize_Complete_t))) != HOST_SENDCONTROL_Successful)
279         {
280                 return ErrorCode;
281         }
282
283         if (InitMessageResponse.Status != CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS))
284           return RNDIS_ERROR_LOGICAL_CMD_FAILED;
285
286         RNDISInterfaceInfo->State.DeviceMaxPacketSize = le32_to_cpu(InitMessageResponse.MaxTransferSize);
287
288         return HOST_SENDCONTROL_Successful;
289 }
290
291 uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
292                                     const uint32_t Oid,
293                                     void* Buffer,
294                                     const uint16_t Length)
295 {
296         uint8_t ErrorCode;
297
298         struct
299         {
300                 RNDIS_Set_Message_t SetMessage;
301                 uint8_t             ContiguousBuffer[Length];
302         } SetMessageData;
303
304         RNDIS_Set_Complete_t SetMessageResponse;
305
306         SetMessageData.SetMessage.MessageType    = CPU_TO_LE32(REMOTE_NDIS_SET_MSG);
307         SetMessageData.SetMessage.MessageLength  = cpu_to_le32(sizeof(RNDIS_Set_Message_t) + Length);
308         SetMessageData.SetMessage.RequestId      = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++);
309
310         SetMessageData.SetMessage.Oid            = cpu_to_le32(Oid);
311         SetMessageData.SetMessage.InformationBufferLength = cpu_to_le32(Length);
312         SetMessageData.SetMessage.InformationBufferOffset = CPU_TO_LE32(sizeof(RNDIS_Set_Message_t) - sizeof(RNDIS_Message_Header_t));
313         SetMessageData.SetMessage.DeviceVcHandle = CPU_TO_LE32(0);
314
315         memcpy(&SetMessageData.ContiguousBuffer, Buffer, Length);
316
317         if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &SetMessageData,
318                                                        (sizeof(RNDIS_Set_Message_t) + Length))) != HOST_SENDCONTROL_Successful)
319         {
320                 return ErrorCode;
321         }
322
323         if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &SetMessageResponse,
324                                                        sizeof(RNDIS_Set_Complete_t))) != HOST_SENDCONTROL_Successful)
325         {
326                 return ErrorCode;
327         }
328
329         if (SetMessageResponse.Status != CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS))
330           return RNDIS_ERROR_LOGICAL_CMD_FAILED;
331
332         return HOST_SENDCONTROL_Successful;
333 }
334
335 uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
336                                       const uint32_t Oid,
337                                       void* Buffer,
338                                       const uint16_t MaxLength)
339 {
340         uint8_t ErrorCode;
341
342         RNDIS_Query_Message_t QueryMessage;
343
344         struct
345         {
346                 RNDIS_Query_Complete_t QueryMessageResponse;
347                 uint8_t                ContiguousBuffer[MaxLength];
348         } QueryMessageResponseData;
349
350         QueryMessage.MessageType    = CPU_TO_LE32(REMOTE_NDIS_QUERY_MSG);
351         QueryMessage.MessageLength  = CPU_TO_LE32(sizeof(RNDIS_Query_Message_t));
352         QueryMessage.RequestId      = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++);
353
354         QueryMessage.Oid            = cpu_to_le32(Oid);
355         QueryMessage.InformationBufferLength = CPU_TO_LE32(0);
356         QueryMessage.InformationBufferOffset = CPU_TO_LE32(0);
357         QueryMessage.DeviceVcHandle = CPU_TO_LE32(0);
358
359         if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &QueryMessage,
360                                                        sizeof(RNDIS_Query_Message_t))) != HOST_SENDCONTROL_Successful)
361         {
362                 return ErrorCode;
363         }
364
365         if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &QueryMessageResponseData,
366                                                        sizeof(QueryMessageResponseData))) != HOST_SENDCONTROL_Successful)
367         {
368                 return ErrorCode;
369         }
370
371         if (QueryMessageResponseData.QueryMessageResponse.Status != CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS))
372           return RNDIS_ERROR_LOGICAL_CMD_FAILED;
373
374         memcpy(Buffer, &QueryMessageResponseData.ContiguousBuffer, MaxLength);
375
376         return HOST_SENDCONTROL_Successful;
377 }
378
379 bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
380 {
381         bool PacketWaiting;
382
383         if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
384           return false;
385
386         Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipe.Address);
387
388         Pipe_Unfreeze();
389         PacketWaiting = Pipe_IsINReceived();
390         Pipe_Freeze();
391
392         return PacketWaiting;
393 }
394
395 uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
396                               void* Buffer,
397                               uint16_t* const PacketLength)
398 {
399         uint8_t ErrorCode;
400
401         if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
402           return PIPE_READYWAIT_DeviceDisconnected;
403
404         Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipe.Address);
405         Pipe_Unfreeze();
406
407         if (!(Pipe_IsReadWriteAllowed()))
408         {
409                 if (Pipe_IsINReceived())
410                   Pipe_ClearIN();
411
412                 *PacketLength = 0;
413                 Pipe_Freeze();
414                 return PIPE_RWSTREAM_NoError;
415         }
416
417         RNDIS_Packet_Message_t DeviceMessage;
418
419         if ((ErrorCode = Pipe_Read_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t),
420                                              NULL)) != PIPE_RWSTREAM_NoError)
421         {
422                 return ErrorCode;
423         }
424
425         *PacketLength = (uint16_t)le32_to_cpu(DeviceMessage.DataLength);
426
427         Pipe_Discard_Stream(le32_to_cpu(DeviceMessage.DataOffset) -
428                             (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)),
429                             NULL);
430
431         Pipe_Read_Stream_LE(Buffer, *PacketLength, NULL);
432
433         if (!(Pipe_BytesInPipe()))
434           Pipe_ClearIN();
435
436         Pipe_Freeze();
437
438         return PIPE_RWSTREAM_NoError;
439 }
440
441 uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
442                               void* Buffer,
443                               const uint16_t PacketLength)
444 {
445         uint8_t ErrorCode;
446
447         if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
448           return PIPE_READYWAIT_DeviceDisconnected;
449
450         RNDIS_Packet_Message_t DeviceMessage;
451
452         memset(&DeviceMessage, 0, sizeof(RNDIS_Packet_Message_t));
453         DeviceMessage.MessageType   = CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG);
454         DeviceMessage.MessageLength = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) + PacketLength);
455         DeviceMessage.DataOffset    = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
456         DeviceMessage.DataLength    = cpu_to_le32(PacketLength);
457
458         Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataOUTPipe.Address);
459         Pipe_Unfreeze();
460
461         if ((ErrorCode = Pipe_Write_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t),
462                                               NULL)) != PIPE_RWSTREAM_NoError)
463         {
464                 return ErrorCode;
465         }
466
467         Pipe_Write_Stream_LE(Buffer, PacketLength, NULL);
468         Pipe_ClearOUT();
469
470         Pipe_Freeze();
471
472         return PIPE_RWSTREAM_NoError;
473 }
474
475 #endif
476