3 Copyright (C) Dean Camera, 2010.
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
10 Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
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.
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
);
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
));
121 static void SideShow_Ping(SideShow_PacketHeader_t
* const PacketHeader
)
125 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
126 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
130 static void SideShow_Sync(SideShow_PacketHeader_t
* const PacketHeader
)
134 Endpoint_Read_Stream_LE(&ProtocolGUID
, sizeof(GUID_t
));
137 if (!(GUID_COMPARE(&ProtocolGUID
, (uint32_t[])STANDARD_PROTOCOL_GUID
)))
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
));
146 static void SideShow_GetCurrentUser(SideShow_PacketHeader_t
* const PacketHeader
)
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
);
158 static void SideShow_SetCurrentUser(SideShow_PacketHeader_t
* const PacketHeader
)
160 SideShow_Read_Unicode_String(&UserSID
, sizeof(UserSID
.UnicodeString
));
163 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
165 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
166 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
170 static void SideShow_GetCapabilities(SideShow_PacketHeader_t
* const PacketHeader
)
172 SideShow_PropertyKey_t Property
;
173 SideShow_PropertyData_t PropertyData
;
175 Endpoint_Read_Stream_LE(&Property
, sizeof(SideShow_PropertyKey_t
));
178 printf(" ID: %lu", Property
.PropertyID
);
180 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
182 if (GUID_COMPARE(&Property
.PropertyGUID
, (uint32_t[])SIDESHOW_PROPERTY_GUID
))
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 (GUID_COMPARE(&Property
.PropertyGUID
, (uint32_t[])DEVICE_PROPERTY_GUID
))
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
);
283 static void SideShow_GetString(SideShow_PacketHeader_t
* const PacketHeader
, void* const UnicodeStruct
)
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
);
296 static void SideShow_GetApplicationOrder(SideShow_PacketHeader_t
* const PacketHeader
)
298 uint8_t TotalApplications
= 0;
302 for (uint8_t App
= 0; App
< MAX_APPLICATIONS
; App
++)
304 if (InstalledApplications
[App
].InUse
)
308 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
) +
309 sizeof(uint32_t) + (TotalApplications
* sizeof(GUID_t
));
311 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
312 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
313 Endpoint_Write_DWord_LE(TotalApplications
);
315 for (uint8_t App
= 0; App
< MAX_APPLICATIONS
; App
++)
317 if (InstalledApplications
[App
].InUse
)
318 Endpoint_Write_Stream_LE(&InstalledApplications
[App
].ApplicationID
, sizeof(GUID_t
));
324 static void SideShow_GetSupportedEndpoints(SideShow_PacketHeader_t
* const PacketHeader
)
326 GUID_t SupportedEndpointGUID
= (GUID_t
){Chunks
: SIMPLE_CONTENT_FORMAT_GUID
};
330 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
) + sizeof(uint32_t) + sizeof(GUID_t
);
332 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
333 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
334 Endpoint_Write_DWord_LE(1);
335 Endpoint_Write_Stream_LE(&SupportedEndpointGUID
, sizeof(GUID_t
));
339 static void SideShow_AddApplication(SideShow_PacketHeader_t
* const PacketHeader
)
341 SideShow_Application_t
* CurrApp
;
342 GUID_t ApplicationID
;
344 Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
));
346 CurrApp
= SideShow_GetApplicationFromGUID(&ApplicationID
);
349 CurrApp
= SideShow_GetFreeApplication();
353 PacketHeader
->Length
-= sizeof(SideShow_PacketHeader_t
) + sizeof(GUID_t
);
355 Endpoint_Discard_Stream(PacketHeader
->Length
);
358 PacketHeader
->Type
.NAK
= true;
362 CurrApp
->ApplicationID
= ApplicationID
;
363 Endpoint_Read_Stream_LE(&CurrApp
->EndpointID
, sizeof(GUID_t
));
364 SideShow_Read_Unicode_String(&CurrApp
->ApplicationName
, sizeof(CurrApp
->ApplicationName
.UnicodeString
));
365 Endpoint_Read_Stream_LE(&CurrApp
->CachePolicy
, sizeof(uint32_t));
366 Endpoint_Read_Stream_LE(&CurrApp
->OnlineOnly
, sizeof(uint32_t));
367 SideShow_Discard_Byte_Stream();
368 SideShow_Discard_Byte_Stream();
369 SideShow_Discard_Byte_Stream();
372 CurrApp
->InUse
= true;
373 CurrApp
->HaveContent
= false;
374 CurrApp
->CurrentContentID
= 1;
377 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
379 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
380 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
384 static void SideShow_DeleteApplication(SideShow_PacketHeader_t
* const PacketHeader
)
386 GUID_t ApplicationGUID
;
388 Endpoint_Read_Stream_LE(&ApplicationGUID
, sizeof(GUID_t
));
391 SideShow_Application_t
* AppToDelete
= SideShow_GetApplicationFromGUID(&ApplicationGUID
);
393 if (AppToDelete
!= NULL
)
394 AppToDelete
->InUse
= false;
396 PacketHeader
->Type
.NAK
= true;
398 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
400 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
401 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
405 static void SideShow_DeleteAllApplications(SideShow_PacketHeader_t
* const PacketHeader
)
409 for (uint8_t App
= 0; App
< MAX_APPLICATIONS
; App
++)
410 InstalledApplications
[App
].InUse
= false;
412 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
413 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
417 static void SideShow_AddContent(SideShow_PacketHeader_t
* const PacketHeader
)
419 GUID_t ApplicationID
;
421 SideShow_Application_t
* Application
;
423 Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
));
424 Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
));
426 Application
= SideShow_GetApplicationFromGUID(&ApplicationID
);
428 if (Application
== NULL
)
430 SideShow_Discard_Byte_Stream();
431 PacketHeader
->Type
.NAK
= true;
433 else if (!(SideShow_AddSimpleContent(PacketHeader
, Application
)))
435 PacketHeader
->Type
.NAK
= true;
440 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
442 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
443 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
447 static void SideShow_DeleteContent(SideShow_PacketHeader_t
* const PacketHeader
)
449 GUID_t ApplicationID
;
453 Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
));
454 Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
));
455 Endpoint_Read_Stream_LE(&ContentID
, sizeof(uint32_t));
458 SideShow_Application_t
* Application
= SideShow_GetApplicationFromGUID(&ApplicationID
);
460 if ((Application
!= NULL
) && (Application
->CurrentContentID
== ContentID
))
461 Application
->HaveContent
= false;
463 PacketHeader
->Type
.NAK
= true;
465 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
467 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
468 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));
472 static void SideShow_DeleteAllContent(SideShow_PacketHeader_t
* const PacketHeader
)
474 GUID_t ApplicationID
;
477 Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
));
478 Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
));
481 SideShow_Application_t
* Application
= SideShow_GetApplicationFromGUID(&ApplicationID
);
483 if (Application
!= NULL
)
484 Application
->HaveContent
= false;
486 PacketHeader
->Type
.NAK
= true;
488 PacketHeader
->Length
= sizeof(SideShow_PacketHeader_t
);
490 Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);
491 Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));