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