3 Copyright (C) Dean Camera, 2009.
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
10 Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
12 Permission to use, copy, modify, and distribute this software
13 and its documentation for any purpose and without fee is hereby
14 granted, provided that the above copyright notice appear in all
15 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.
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
31 #define INCLUDE_FROM_SIDESHOWCOMMANDS_H
32 #include "SideshowCommands.h"
34 UNICODE_STRING_t(80) UserSID
= {LengthInBytes
: sizeof(SECURITY_INTERACTIVE_RID_SID
),
35 UnicodeString
: SECURITY_INTERACTIVE_RID_SID
};
37 Unicode_String_t DeviceName
= {LengthInBytes
: sizeof(L
"LUFA Sideshow Device"),
38 UnicodeString
: L
"LUFA Sideshow Device"};
40 Unicode_String_t Manufacturer
= {LengthInBytes
: sizeof(L
"Dean Camera"),
41 UnicodeString
: L
"Dean Camera"};
43 Unicode_String_t SupportedLanguage
= {LengthInBytes
: sizeof(L
"en-US:1"),
44 UnicodeString
: L
"en-US:1"};
46 void Sideshow_ProcessCommandPacket(void)
48 SideShow_PacketHeader_t PacketHeader
;
50 Endpoint_SelectEndpoint(SIDESHOW_OUT_EPNUM
);
51 Endpoint_Read_Stream_LE(&PacketHeader
, sizeof(SideShow_PacketHeader_t
));
53 PacketHeader
.Type
.Response
= true;
55 printf("\r\nCmd: %lX", (PacketHeader
.Type
.TypeLong
& 0x00FFFFFF));
57 switch (PacketHeader
.Type
.TypeLong
& 0x00FFFFFF)
59 case SIDESHOW_CMD_PING
:
60 SideShow_Ping(&PacketHeader
);
62 case SIDESHOW_CMD_SYNC
:
63 SideShow_Sync(&PacketHeader
);
65 case SIDESHOW_CMD_GET_CURRENT_USER
:
66 SideShow_GetCurrentUser(&PacketHeader
);
68 case SIDESHOW_CMD_SET_CURRENT_USER
:
69 SideShow_SetCurrentUser(&PacketHeader
);
71 case SIDESHOW_CMD_GET_CAPABILITIES
:
72 SideShow_GetCapabilities(&PacketHeader
);
74 case SIDESHOW_CMD_GET_DEVICE_NAME
:
75 SideShow_GetString(&PacketHeader
, &DeviceName
);
77 case SIDESHOW_CMD_GET_MANUFACTURER
:
78 SideShow_GetString(&PacketHeader
, &Manufacturer
);
80 case SIDESHOW_CMD_GET_APPLICATION_ORDER
:
81 SideShow_GetApplicationOrder(&PacketHeader
);
83 case SIDESHOW_CMD_GET_SUPPORTED_ENDPOINTS
:
84 SideShow_GetSupportedEndpoints(&PacketHeader
);
86 case SIDESHOW_CMD_ADD_APPLICATION
:
87 SideShow_AddApplication(&PacketHeader
);
89 case SIDESHOW_CMD_ADD_CONTENT
:
90 SideShow_AddContent(&PacketHeader
);
92 case SIDESHOW_CMD_DELETE_CONTENT
:
93 SideShow_DeleteContent(&PacketHeader
);
95 case SIDESHOW_CMD_DELETE_ALL_CONTENT
:
96 SideShow_DeleteAllContent(&PacketHeader
);
98 case SIDESHOW_CMD_DELETE_APPLICATION
:
99 SideShow_DeleteApplication(&PacketHeader
);
101 case SIDESHOW_CMD_DELETE_ALL_APPLICATIONS
:
102 SideShow_DeleteAllApplications(&PacketHeader
);
105 PacketHeader
.Length
-= sizeof(SideShow_PacketHeader_t
);
107 Endpoint_Discard_Stream(PacketHeader
.Length
);
108 Endpoint_ClearCurrentBank();
110 PacketHeader
.Length
= sizeof(SideShow_PacketHeader_t
);
111 PacketHeader
.Type
.NAK
= true;
113 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
114 Endpoint_Write_Stream_LE(&PacketHeader
, sizeof(SideShow_PacketHeader_t
));
115 Endpoint_ClearCurrentBank();
121 static void SideShow_Ping(SideShow_PacketHeader_t
* PacketHeader
)
123 Endpoint_ClearCurrentBank();
125 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
126 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
127 Endpoint_ClearCurrentBank();
130 static void SideShow_Sync(SideShow_PacketHeader_t
* PacketHeader
)
134 Endpoint_Read_Stream_LE(&ProtocolGUID
, sizeof(GUID_t
));
135 Endpoint_ClearCurrentBank();
137 if (memcmp(&ProtocolGUID
, (uint32_t[])STANDARD_PROTOCOL_GUID
, sizeof(GUID_t
)) != 0)
138 PacketHeader
->Type
.NAK
= true;
140 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
141 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
142 Endpoint_Write_Stream_LE(&ProtocolGUID
, sizeof(GUID_t
));
143 Endpoint_ClearCurrentBank();
146 static void SideShow_GetCurrentUser(SideShow_PacketHeader_t
* PacketHeader
)
148 Endpoint_ClearCurrentBank();
150 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
) + sizeof(uint32_t) + UserSID
.LengthInBytes
;
152 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
153 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
154 SideShow_Write_Unicode_String(&UserSID
);
155 Endpoint_ClearCurrentBank();
158 static void SideShow_SetCurrentUser(SideShow_PacketHeader_t
* PacketHeader
)
160 SideShow_Read_Unicode_String(&UserSID
, sizeof(UserSID
.UnicodeString
));
161 Endpoint_ClearCurrentBank();
163 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
165 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
166 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
167 Endpoint_ClearCurrentBank();
170 static void SideShow_GetCapabilities(SideShow_PacketHeader_t
* PacketHeader
)
172 SideShow_PropertyKey_t Property
;
173 SideShow_PropertyData_t PropertyData
;
175 Endpoint_Read_Stream_LE(&Property
, sizeof(SideShow_PropertyKey_t
));
176 Endpoint_ClearCurrentBank();
178 printf(" ID: %lu", Property
.PropertyID
);
180 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
182 if (memcmp(&Property
.PropertyGUID
, (uint32_t[])SIDESHOW_PROPERTY_GUID
, sizeof(GUID_t
)) == 0)
184 switch (Property
.PropertyID
)
186 case PROPERTY_SIDESHOW_SCREENTYPE
:
187 PropertyData
.DataType
= VT_I4
;
188 PropertyData
.Data
.Data32
= ScreenText
;
189 PacketHeader
->Length
+= sizeof(uint32_t);
192 case PROPERTY_SIDESHOW_SCREENWIDTH
:
193 case PROPERTY_SIDESHOW_CLIENTWIDTH
:
194 PropertyData
.DataType
= VT_UI2
;
195 PropertyData
.Data
.Data16
= 16;
196 PacketHeader
->Length
+= sizeof(uint16_t);
199 case PROPERTY_SIDESHOW_SCREENHEIGHT
:
200 case PROPERTY_SIDESHOW_CLIENTHEIGHT
:
201 PropertyData
.DataType
= VT_UI2
;
202 PropertyData
.Data
.Data16
= 2;
203 PacketHeader
->Length
+= sizeof(uint16_t);
206 case PROPERTY_SIDESHOW_COLORDEPTH
:
207 PropertyData
.DataType
= VT_UI2
;
208 PropertyData
.Data
.Data16
= 1;
209 PacketHeader
->Length
+= sizeof(uint16_t);
212 case PROPERTY_SIDESHOW_COLORTYPE
:
213 PropertyData
.DataType
= VT_UI2
;
214 PropertyData
.Data
.Data16
= BlackAndWhiteDisplay
;
215 PacketHeader
->Length
+= sizeof(uint16_t);
218 case PROPERTY_SIDESHOW_DATACACHE
:
219 PropertyData
.DataType
= VT_BOOL
;
220 PropertyData
.Data
.Data16
= false;
221 PacketHeader
->Length
+= sizeof(uint16_t);
224 case PROPERTY_SIDESHOW_SUPPORTEDLANGS
:
225 case PROPERTY_SIDESHOW_CURRENTLANG
:
226 PropertyData
.DataType
= VT_LPWSTR
;
227 PropertyData
.Data
.DataPointer
= &SupportedLanguage
;
228 PacketHeader
->Length
+= SupportedLanguage
.LengthInBytes
;
232 PropertyData
.DataType
= VT_EMPTY
;
236 else if (memcmp(&Property
.PropertyGUID
, (uint32_t[])DEVICE_PROPERTY_GUID
, sizeof(GUID_t
)) == 0)
238 switch (Property
.PropertyID
)
240 case PROPERTY_DEVICE_DEVICETYPE
:
241 PropertyData
.DataType
= VT_UI4
;
242 PropertyData
.Data
.Data32
= GenericDevice
;
243 PacketHeader
->Length
+= sizeof(uint32_t);
250 PacketHeader
->Type
.NAK
= true;
252 printf(" WRONG GUID");
253 printf(" %lX %lX %lX %lX", Property
.PropertyGUID
.Chunks
[0], Property
.PropertyGUID
.Chunks
[1],
254 Property
.PropertyGUID
.Chunks
[2], Property
.PropertyGUID
.Chunks
[3]);
257 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
258 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
260 if (!(PacketHeader
->Type
.NAK
))
262 switch (PropertyData
.DataType
)
266 Endpoint_Write_Stream_LE(&PropertyData
.Data
.Data32
, sizeof(uint32_t));
271 Endpoint_Write_Stream_LE(&PropertyData
.Data
.Data16
, sizeof(uint16_t));
274 SideShow_Write_Unicode_String((Unicode_String_t
*)PropertyData
.Data
.Data16
);
279 Endpoint_ClearCurrentBank();
283 static void SideShow_GetString(SideShow_PacketHeader_t
* PacketHeader
, void* UnicodeStruct
)
285 Endpoint_ClearCurrentBank();
287 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
) +
288 sizeof(uint32_t) + ((Unicode_String_t
*)UnicodeStruct
)->LengthInBytes
;
290 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
291 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
292 SideShow_Write_Unicode_String(UnicodeStruct
);
293 Endpoint_ClearCurrentBank();
296 static void SideShow_GetApplicationOrder(SideShow_PacketHeader_t
* PacketHeader
)
298 uint8_t TotalInstalledApplications
= SideShow_GetTotalApplications();
299 uint16_t GadgetGUIDBytes
= (TotalInstalledApplications
* sizeof(GUID_t
));
301 Endpoint_ClearCurrentBank();
303 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
) +
304 sizeof(uint32_t) + GadgetGUIDBytes
;
306 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
307 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
308 Endpoint_Write_DWord_LE(TotalInstalledApplications
);
310 for (uint8_t App
= 0; App
< MAX_APPLICATIONS
; App
++)
312 if (InstalledApplications
[App
].InUse
== true)
313 Endpoint_Write_Stream_LE(&InstalledApplications
[App
].ApplicationID
, sizeof(GUID_t
));
316 Endpoint_ClearCurrentBank();
319 static void SideShow_GetSupportedEndpoints(SideShow_PacketHeader_t
* PacketHeader
)
321 GUID_t SupportedEndpointGUID
= (GUID_t
){Chunks
: SIMPLE_CONTENT_FORMAT_GUID
};
323 Endpoint_ClearCurrentBank();
325 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
) + sizeof(uint32_t) + sizeof(GUID_t
);
327 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
328 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
329 Endpoint_Write_DWord_LE(1);
330 Endpoint_Write_Stream_LE(&SupportedEndpointGUID
, sizeof(GUID_t
));
331 Endpoint_ClearCurrentBank();
334 static void SideShow_AddApplication(SideShow_PacketHeader_t
* PacketHeader
)
336 SideShow_Application_t
* CurrApp
;
337 GUID_t ApplicationID
;
339 Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
));
341 CurrApp
= SideShow_GetApplicationFromGUID(&ApplicationID
);
344 CurrApp
= SideShow_GetFreeApplication();
348 PacketHeader
->Length
-= sizeof(SideShow_PacketHeader_t
) + sizeof(GUID_t
);
350 Endpoint_Discard_Stream(PacketHeader
->Length
);
351 Endpoint_ClearCurrentBank();
353 PacketHeader
->Type
.NAK
= true;
357 CurrApp
->ApplicationID
= ApplicationID
;
358 Endpoint_Read_Stream_LE(&CurrApp
->EndpointID
, sizeof(GUID_t
));
359 SideShow_Read_Unicode_String(&CurrApp
->ApplicationName
, sizeof(CurrApp
->ApplicationName
.UnicodeString
));
360 Endpoint_Read_Stream_LE(&CurrApp
->CachePolicy
, sizeof(uint32_t));
361 Endpoint_Read_Stream_LE(&CurrApp
->OnlineOnly
, sizeof(uint32_t));
362 SideShow_Discard_Byte_Stream();
363 SideShow_Discard_Byte_Stream();
364 SideShow_Discard_Byte_Stream();
365 Endpoint_ClearCurrentBank();
367 CurrApp
->InUse
= true;
368 CurrApp
->HaveContent
= false;
369 CurrApp
->CurrentContentID
= 1;
372 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
374 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
375 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
376 Endpoint_ClearCurrentBank();
379 static void SideShow_DeleteApplication(SideShow_PacketHeader_t
* PacketHeader
)
381 GUID_t ApplicationGUID
;
383 Endpoint_Read_Stream_LE(&ApplicationGUID
, sizeof(GUID_t
));
384 Endpoint_ClearCurrentBank();
386 SideShow_Application_t
* AppToDelete
= SideShow_GetApplicationFromGUID(&ApplicationGUID
);
388 if (AppToDelete
!= NULL
)
390 AppToDelete
->InUse
= false;
393 PacketHeader
->Type
.NAK
= true;
395 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
397 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
398 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
399 Endpoint_ClearCurrentBank();
402 static void SideShow_DeleteAllApplications(SideShow_PacketHeader_t
* PacketHeader
)
404 Endpoint_ClearCurrentBank();
406 for (uint8_t App
= 0; App
< MAX_APPLICATIONS
; App
++)
407 InstalledApplications
[App
].InUse
= false;
409 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
410 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
411 Endpoint_ClearCurrentBank();
414 static void SideShow_AddContent(SideShow_PacketHeader_t
* PacketHeader
)
416 GUID_t ApplicationID
;
418 SideShow_Application_t
* Application
;
420 Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
));
421 Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
));
423 Application
= SideShow_GetApplicationFromGUID(&ApplicationID
);
425 if (Application
== NULL
)
427 SideShow_Discard_Byte_Stream();
428 PacketHeader
->Type
.NAK
= true;
430 else if (!(SideShow_AddSimpleContent(PacketHeader
, Application
)))
432 PacketHeader
->Type
.NAK
= true;
435 Endpoint_ClearCurrentBank();
437 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
439 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
440 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
441 Endpoint_ClearCurrentBank();
444 static void SideShow_DeleteContent(SideShow_PacketHeader_t
* PacketHeader
)
446 GUID_t ApplicationID
;
450 Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
));
451 Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
));
452 Endpoint_Read_Stream_LE(&ContentID
, sizeof(uint32_t));
453 Endpoint_ClearCurrentBank();
455 SideShow_Application_t
* Application
= SideShow_GetApplicationFromGUID(&ApplicationID
);
457 if ((Application
!= NULL
) && (Application
->CurrentContentID
== ContentID
))
458 Application
->HaveContent
= false;
460 PacketHeader
->Type
.NAK
= true;
462 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
464 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
465 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
466 Endpoint_ClearCurrentBank();
469 static void SideShow_DeleteAllContent(SideShow_PacketHeader_t
* PacketHeader
)
471 GUID_t ApplicationID
;
474 Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
));
475 Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
));
476 Endpoint_ClearCurrentBank();
478 SideShow_Application_t
* Application
= SideShow_GetApplicationFromGUID(&ApplicationID
);
480 if (Application
!= NULL
)
481 Application
->HaveContent
= false;
483 PacketHeader
->Type
.NAK
= true;
485 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
487 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
488 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
489 Endpoint_ClearCurrentBank();