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