Renamed all low level Endpoint_Read_*, Endpoint_Write_* and Endpoint_Discard_* functi...
[pub/USBasp.git] / Demos / Device / Incomplete / Sideshow / Lib / SideshowCommands.c
index 0353af4..d1aea1e 100644 (file)
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2010.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, distribute, and sell this \r
-  software and its documentation for any purpose is hereby granted\r
-  without fee, provided that the above copyright notice appear in \r
-  all copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting \r
-  documentation, and that the name of the author not be used in \r
-  advertising or publicity pertaining to distribution of the \r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-#define  INCLUDE_FROM_SIDESHOWCOMMANDS_H\r
-#include "SideshowCommands.h"\r
-\r
-UNICODE_STRING_t(80) UserSID       = {LengthInBytes: sizeof(SECURITY_INTERACTIVE_RID_SID),\r
-                                      UnicodeString: SECURITY_INTERACTIVE_RID_SID};\r
-\r
-Unicode_String_t DeviceName        = {LengthInBytes: sizeof(L"LUFA Sideshow Device"),\r
-                                      UnicodeString: L"LUFA Sideshow Device"};\r
-\r
-Unicode_String_t Manufacturer      = {LengthInBytes: sizeof(L"Dean Camera"),\r
-                                      UnicodeString: L"Dean Camera"};\r
-\r
-Unicode_String_t SupportedLanguage = {LengthInBytes: sizeof(L"en-US:1"),\r
-                                      UnicodeString: L"en-US:1"};\r
-                                                                         \r
-void Sideshow_ProcessCommandPacket(void)\r
-{\r
-       SideShow_PacketHeader_t PacketHeader;\r
-       \r
-       Endpoint_SelectEndpoint(SIDESHOW_OUT_EPNUM);    \r
-       Endpoint_Read_Stream_LE(&PacketHeader, sizeof(SideShow_PacketHeader_t));\r
-       \r
-       PacketHeader.Type.Response = true;\r
-\r
-       printf("\r\nCmd: %lX", (PacketHeader.Type.TypeLong & 0x00FFFFFF));\r
-\r
-       switch (PacketHeader.Type.TypeLong & 0x00FFFFFF)\r
-       {\r
-               case SIDESHOW_CMD_PING:\r
-                       SideShow_Ping(&PacketHeader);\r
-                       break;\r
-               case SIDESHOW_CMD_SYNC:\r
-                       SideShow_Sync(&PacketHeader);\r
-                       break;\r
-               case SIDESHOW_CMD_GET_CURRENT_USER:\r
-                       SideShow_GetCurrentUser(&PacketHeader);\r
-                       break;\r
-               case SIDESHOW_CMD_SET_CURRENT_USER:\r
-                       SideShow_SetCurrentUser(&PacketHeader);\r
-                       break;\r
-               case SIDESHOW_CMD_GET_CAPABILITIES:\r
-                       SideShow_GetCapabilities(&PacketHeader);\r
-                       break;                  \r
-               case SIDESHOW_CMD_GET_DEVICE_NAME:\r
-                       SideShow_GetString(&PacketHeader, &DeviceName);\r
-                       break;\r
-               case SIDESHOW_CMD_GET_MANUFACTURER:\r
-                       SideShow_GetString(&PacketHeader, &Manufacturer);\r
-                       break;\r
-               case SIDESHOW_CMD_GET_APPLICATION_ORDER:\r
-                       SideShow_GetApplicationOrder(&PacketHeader);\r
-                       break;\r
-               case SIDESHOW_CMD_GET_SUPPORTED_ENDPOINTS:\r
-                       SideShow_GetSupportedEndpoints(&PacketHeader);\r
-                       break;\r
-               case SIDESHOW_CMD_ADD_APPLICATION:\r
-                       SideShow_AddApplication(&PacketHeader);\r
-                       break;\r
-               case SIDESHOW_CMD_ADD_CONTENT:\r
-                       SideShow_AddContent(&PacketHeader);\r
-                       break;\r
-               case SIDESHOW_CMD_DELETE_CONTENT:\r
-                       SideShow_DeleteContent(&PacketHeader);\r
-                       break;\r
-               case SIDESHOW_CMD_DELETE_ALL_CONTENT:\r
-                       SideShow_DeleteAllContent(&PacketHeader);\r
-                       break;          \r
-               case SIDESHOW_CMD_DELETE_APPLICATION:\r
-                       SideShow_DeleteApplication(&PacketHeader);\r
-                       break;\r
-               case SIDESHOW_CMD_DELETE_ALL_APPLICATIONS:\r
-                       SideShow_DeleteAllApplications(&PacketHeader);\r
-                       break;\r
-               default:\r
-                       PacketHeader.Length -= sizeof(SideShow_PacketHeader_t);\r
-\r
-                       Endpoint_Discard_Stream(PacketHeader.Length);\r
-                       Endpoint_ClearOUT();\r
-\r
-                       PacketHeader.Length   = sizeof(SideShow_PacketHeader_t);\r
-                       PacketHeader.Type.NAK = true;\r
-                       \r
-                       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);     \r
-                       Endpoint_Write_Stream_LE(&PacketHeader, sizeof(SideShow_PacketHeader_t));               \r
-                       Endpoint_ClearIN();\r
-                       \r
-                       printf(" UNK");\r
-       }\r
-}\r
-\r
-static void SideShow_Ping(SideShow_PacketHeader_t* PacketHeader)\r
-{\r
-       Endpoint_ClearOUT();\r
-\r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);     \r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));                \r
-       Endpoint_ClearIN();\r
-}\r
-\r
-static void SideShow_Sync(SideShow_PacketHeader_t* PacketHeader)\r
-{\r
-       GUID_t ProtocolGUID;\r
-\r
-       Endpoint_Read_Stream_LE(&ProtocolGUID, sizeof(GUID_t));\r
-       Endpoint_ClearOUT();\r
-       \r
-       if (!(GUID_COMPARE(&ProtocolGUID, (uint32_t[])STANDARD_PROTOCOL_GUID)))\r
-         PacketHeader->Type.NAK = true;\r
-       \r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));                \r
-       Endpoint_Write_Stream_LE(&ProtocolGUID, sizeof(GUID_t));\r
-       Endpoint_ClearIN();\r
-}\r
-\r
-static void SideShow_GetCurrentUser(SideShow_PacketHeader_t* PacketHeader)\r
-{\r
-       Endpoint_ClearOUT();\r
-\r
-       PacketHeader->Length = sizeof(SideShow_PacketHeader_t) + sizeof(uint32_t) + UserSID.LengthInBytes;\r
-\r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));\r
-       SideShow_Write_Unicode_String(&UserSID);\r
-       Endpoint_ClearIN();\r
-}\r
-\r
-static void SideShow_SetCurrentUser(SideShow_PacketHeader_t* PacketHeader)\r
-{\r
-       SideShow_Read_Unicode_String(&UserSID, sizeof(UserSID.UnicodeString));\r
-       Endpoint_ClearOUT();\r
-       \r
-       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);\r
-\r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));\r
-       Endpoint_ClearIN();\r
-}\r
-\r
-static void SideShow_GetCapabilities(SideShow_PacketHeader_t* PacketHeader)\r
-{\r
-       SideShow_PropertyKey_t  Property;\r
-       SideShow_PropertyData_t PropertyData;\r
-\r
-       Endpoint_Read_Stream_LE(&Property, sizeof(SideShow_PropertyKey_t));\r
-       Endpoint_ClearOUT();\r
-       \r
-       printf(" ID: %lu", Property.PropertyID);\r
-\r
-       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);\r
-\r
-       if (GUID_COMPARE(&Property.PropertyGUID, (uint32_t[])SIDESHOW_PROPERTY_GUID))\r
-       {\r
-               switch (Property.PropertyID)\r
-               {\r
-                       case PROPERTY_SIDESHOW_SCREENTYPE:\r
-                               PropertyData.DataType    = VT_I4;\r
-                               PropertyData.Data.Data32 = ScreenText;\r
-                               PacketHeader->Length += sizeof(uint32_t);\r
-                               \r
-                               break;\r
-                       case PROPERTY_SIDESHOW_SCREENWIDTH:\r
-                       case PROPERTY_SIDESHOW_CLIENTWIDTH:\r
-                               PropertyData.DataType    = VT_UI2;\r
-                               PropertyData.Data.Data16 = 16;\r
-                               PacketHeader->Length += sizeof(uint16_t);\r
-                       \r
-                               break;\r
-                       case PROPERTY_SIDESHOW_SCREENHEIGHT:\r
-                       case PROPERTY_SIDESHOW_CLIENTHEIGHT:\r
-                               PropertyData.DataType    = VT_UI2;\r
-                               PropertyData.Data.Data16 = 2;\r
-                               PacketHeader->Length += sizeof(uint16_t);\r
-                       \r
-                               break;\r
-                       case PROPERTY_SIDESHOW_COLORDEPTH:\r
-                               PropertyData.DataType    = VT_UI2;\r
-                               PropertyData.Data.Data16 = 1;\r
-                               PacketHeader->Length += sizeof(uint16_t);\r
-                       \r
-                               break;\r
-                       case PROPERTY_SIDESHOW_COLORTYPE:\r
-                               PropertyData.DataType    = VT_UI2;\r
-                               PropertyData.Data.Data16 = BlackAndWhiteDisplay;\r
-                               PacketHeader->Length += sizeof(uint16_t);\r
-                       \r
-                               break;\r
-                       case PROPERTY_SIDESHOW_DATACACHE:\r
-                               PropertyData.DataType    = VT_BOOL;\r
-                               PropertyData.Data.Data16 = false;\r
-                               PacketHeader->Length += sizeof(uint16_t);\r
-                       \r
-                               break;\r
-                       case PROPERTY_SIDESHOW_SUPPORTEDLANGS:\r
-                       case PROPERTY_SIDESHOW_CURRENTLANG:\r
-                               PropertyData.DataType    = VT_LPWSTR;\r
-                               PropertyData.Data.DataPointer = &SupportedLanguage;\r
-                               PacketHeader->Length += SupportedLanguage.LengthInBytes;\r
-                       \r
-                               break;\r
-                       default:\r
-                               PropertyData.DataType    = VT_EMPTY;\r
-                               break;\r
-               }\r
-       }\r
-       else if (GUID_COMPARE(&Property.PropertyGUID, (uint32_t[])DEVICE_PROPERTY_GUID))\r
-       {\r
-               switch (Property.PropertyID)\r
-               {\r
-                       case PROPERTY_DEVICE_DEVICETYPE:\r
-                               PropertyData.DataType    = VT_UI4;\r
-                               PropertyData.Data.Data32 = GenericDevice;\r
-                               PacketHeader->Length += sizeof(uint32_t);\r
-                               \r
-                               break;\r
-               }\r
-       }       \r
-       else\r
-       {\r
-               PacketHeader->Type.NAK = true;          \r
-               \r
-               printf(" WRONG GUID");\r
-               printf(" %lX %lX %lX %lX", Property.PropertyGUID.Chunks[0], Property.PropertyGUID.Chunks[1],\r
-                                          Property.PropertyGUID.Chunks[2],  Property.PropertyGUID.Chunks[3]);          \r
-       }\r
-\r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));\r
-       \r
-       if (!(PacketHeader->Type.NAK))\r
-       {\r
-               switch (PropertyData.DataType)\r
-               {\r
-                       case VT_UI4:\r
-                       case VT_I4:\r
-                               Endpoint_Write_Stream_LE(&PropertyData.Data.Data32, sizeof(uint32_t));\r
-                               break;\r
-                       case VT_UI2:\r
-                       case VT_I2:\r
-                       case VT_BOOL:\r
-                               Endpoint_Write_Stream_LE(&PropertyData.Data.Data16, sizeof(uint16_t));\r
-                               break;\r
-                       case VT_LPWSTR:\r
-                               SideShow_Write_Unicode_String((Unicode_String_t*)PropertyData.Data.Data16);\r
-                               break;\r
-               }\r
-       }\r
-       \r
-       Endpoint_ClearIN();\r
-       return;\r
-}\r
-\r
-static void SideShow_GetString(SideShow_PacketHeader_t* PacketHeader, void* UnicodeStruct)\r
-{\r
-       Endpoint_ClearOUT();\r
-\r
-       PacketHeader->Length = sizeof(SideShow_PacketHeader_t) +\r
-                              sizeof(uint32_t) + ((Unicode_String_t*)UnicodeStruct)->LengthInBytes;\r
-       \r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));\r
-       SideShow_Write_Unicode_String(UnicodeStruct);\r
-       Endpoint_ClearIN();\r
-}\r
-\r
-static void SideShow_GetApplicationOrder(SideShow_PacketHeader_t* PacketHeader)\r
-{\r
-       uint8_t  TotalApplications = 0;\r
-                  \r
-       Endpoint_ClearOUT();\r
-\r
-       for (uint8_t App = 0; App < MAX_APPLICATIONS; App++)\r
-       {\r
-               if (InstalledApplications[App].InUse)\r
-                 TotalApplications++;\r
-       }\r
-\r
-       PacketHeader->Length = sizeof(SideShow_PacketHeader_t) +\r
-                              sizeof(uint32_t) + (TotalApplications * sizeof(GUID_t));\r
-       \r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));\r
-       Endpoint_Write_DWord_LE(TotalApplications);\r
-       \r
-       for (uint8_t App = 0; App < MAX_APPLICATIONS; App++)\r
-       {\r
-               if (InstalledApplications[App].InUse)\r
-                 Endpoint_Write_Stream_LE(&InstalledApplications[App].ApplicationID, sizeof(GUID_t));\r
-       }\r
-\r
-       Endpoint_ClearIN();\r
-}\r
-\r
-static void SideShow_GetSupportedEndpoints(SideShow_PacketHeader_t* PacketHeader)\r
-{\r
-       GUID_t SupportedEndpointGUID = (GUID_t){Chunks: SIMPLE_CONTENT_FORMAT_GUID};\r
-\r
-       Endpoint_ClearOUT();\r
-\r
-       PacketHeader->Length = sizeof(SideShow_PacketHeader_t) + sizeof(uint32_t) + sizeof(GUID_t);\r
-       \r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));\r
-       Endpoint_Write_DWord_LE(1);\r
-       Endpoint_Write_Stream_LE(&SupportedEndpointGUID, sizeof(GUID_t));\r
-       Endpoint_ClearIN();\r
-}\r
-\r
-static void SideShow_AddApplication(SideShow_PacketHeader_t* PacketHeader)\r
-{\r
-       SideShow_Application_t* CurrApp;\r
-       GUID_t                  ApplicationID;\r
-\r
-       Endpoint_Read_Stream_LE(&ApplicationID, sizeof(GUID_t));\r
-\r
-       CurrApp = SideShow_GetApplicationFromGUID(&ApplicationID);\r
-\r
-       if (CurrApp == NULL)\r
-         CurrApp = SideShow_GetFreeApplication();\r
-\r
-       if (CurrApp == NULL)\r
-       {\r
-               PacketHeader->Length -= sizeof(SideShow_PacketHeader_t) + sizeof(GUID_t);\r
-\r
-               Endpoint_Discard_Stream(PacketHeader->Length);\r
-               Endpoint_ClearOUT();\r
-\r
-               PacketHeader->Type.NAK = true;\r
-       }\r
-       else\r
-       {\r
-               CurrApp->ApplicationID = ApplicationID;\r
-               Endpoint_Read_Stream_LE(&CurrApp->EndpointID, sizeof(GUID_t));\r
-               SideShow_Read_Unicode_String(&CurrApp->ApplicationName, sizeof(CurrApp->ApplicationName.UnicodeString));\r
-               Endpoint_Read_Stream_LE(&CurrApp->CachePolicy, sizeof(uint32_t));\r
-               Endpoint_Read_Stream_LE(&CurrApp->OnlineOnly, sizeof(uint32_t));\r
-               SideShow_Discard_Byte_Stream();\r
-               SideShow_Discard_Byte_Stream();\r
-               SideShow_Discard_Byte_Stream();\r
-               Endpoint_ClearOUT();\r
-               \r
-               CurrApp->InUse = true;\r
-               CurrApp->HaveContent = false;\r
-               CurrApp->CurrentContentID = 1;\r
-       }\r
-\r
-       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);\r
-\r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));\r
-       Endpoint_ClearIN();\r
-}\r
-\r
-static void SideShow_DeleteApplication(SideShow_PacketHeader_t* PacketHeader)\r
-{\r
-       GUID_t ApplicationGUID;\r
-       \r
-       Endpoint_Read_Stream_LE(&ApplicationGUID, sizeof(GUID_t));      \r
-       Endpoint_ClearOUT();\r
-\r
-       SideShow_Application_t* AppToDelete = SideShow_GetApplicationFromGUID(&ApplicationGUID);\r
-\r
-       if (AppToDelete != NULL)\r
-         AppToDelete->InUse = false;\r
-       else\r
-         PacketHeader->Type.NAK = true;\r
-\r
-       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);\r
-\r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));\r
-       Endpoint_ClearIN();\r
-}\r
-\r
-static void SideShow_DeleteAllApplications(SideShow_PacketHeader_t* PacketHeader)\r
-{\r
-       Endpoint_ClearOUT();\r
-       \r
-       for (uint8_t App = 0; App < MAX_APPLICATIONS; App++)\r
-         InstalledApplications[App].InUse = false;\r
-\r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));\r
-       Endpoint_ClearIN();\r
-}\r
-\r
-static void SideShow_AddContent(SideShow_PacketHeader_t* PacketHeader)\r
-{\r
-       GUID_t ApplicationID;\r
-       GUID_t EndpointID;\r
-       SideShow_Application_t* Application;\r
-       \r
-       Endpoint_Read_Stream_LE(&ApplicationID, sizeof(GUID_t));\r
-       Endpoint_Read_Stream_LE(&EndpointID, sizeof(GUID_t));\r
-       \r
-       Application = SideShow_GetApplicationFromGUID(&ApplicationID);\r
-       \r
-       if (Application == NULL)\r
-       {\r
-               SideShow_Discard_Byte_Stream();\r
-               PacketHeader->Type.NAK = true;\r
-       }\r
-       else if (!(SideShow_AddSimpleContent(PacketHeader, Application)))\r
-       {\r
-               PacketHeader->Type.NAK = true;\r
-       }\r
-       \r
-       Endpoint_ClearOUT();\r
-\r
-       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);\r
-\r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));\r
-       Endpoint_ClearIN();\r
-}\r
-\r
-static void SideShow_DeleteContent(SideShow_PacketHeader_t* PacketHeader)\r
-{\r
-       GUID_t   ApplicationID;\r
-       GUID_t   EndpointID;\r
-       uint32_t ContentID;\r
-\r
-       Endpoint_Read_Stream_LE(&ApplicationID, sizeof(GUID_t));\r
-       Endpoint_Read_Stream_LE(&EndpointID, sizeof(GUID_t));\r
-       Endpoint_Read_Stream_LE(&ContentID, sizeof(uint32_t));\r
-       Endpoint_ClearOUT();\r
-       \r
-       SideShow_Application_t* Application = SideShow_GetApplicationFromGUID(&ApplicationID);\r
-       \r
-       if ((Application != NULL) && (Application->CurrentContentID == ContentID))\r
-         Application->HaveContent = false;\r
-       else\r
-         PacketHeader->Type.NAK = true;\r
-         \r
-       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);\r
-\r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));\r
-       Endpoint_ClearIN();\r
-}\r
-\r
-static void SideShow_DeleteAllContent(SideShow_PacketHeader_t* PacketHeader)\r
-{\r
-       GUID_t ApplicationID;\r
-       GUID_t EndpointID;\r
-\r
-       Endpoint_Read_Stream_LE(&ApplicationID, sizeof(GUID_t));\r
-       Endpoint_Read_Stream_LE(&EndpointID, sizeof(GUID_t));\r
-       Endpoint_ClearOUT();\r
-\r
-       SideShow_Application_t* Application = SideShow_GetApplicationFromGUID(&ApplicationID);\r
-       \r
-       if (Application != NULL)\r
-         Application->HaveContent = false;\r
-       else\r
-         PacketHeader->Type.NAK = true;          \r
-\r
-       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);\r
-\r
-       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
-       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));\r
-       Endpoint_ClearIN();  \r
-}\r
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2011.
+
+  dean [at] fourwalledcubicle [dot] com
+           www.lufa-lib.org
+*/
+
+/*
+  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, distribute, and sell this
+  software and its documentation for any purpose is hereby granted
+  without fee, provided that the above copyright notice appear in
+  all copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+#define  INCLUDE_FROM_SIDESHOWCOMMANDS_H
+#include "SideshowCommands.h"
+
+UNICODE_STRING_t(80) UserSID       = {LengthInBytes: sizeof(SECURITY_INTERACTIVE_RID_SID),
+                                      UnicodeString: SECURITY_INTERACTIVE_RID_SID};
+
+Unicode_String_t DeviceName        = {LengthInBytes: sizeof(L"LUFA Sideshow Device"),
+                                      UnicodeString: L"LUFA Sideshow Device"};
+
+Unicode_String_t Manufacturer      = {LengthInBytes: sizeof(L"Dean Camera"),
+                                      UnicodeString: L"Dean Camera"};
+
+Unicode_String_t SupportedLanguage = {LengthInBytes: sizeof(L"en-US:1"),
+                                      UnicodeString: L"en-US:1"};
+
+void Sideshow_ProcessCommandPacket(void)
+{
+       SideShow_PacketHeader_t PacketHeader;
+
+       Endpoint_SelectEndpoint(SIDESHOW_OUT_EPNUM);
+       Endpoint_Read_Stream_LE(&PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+
+       PacketHeader.Type.TypeFields.Response = true;
+
+       printf("\r\nCmd: %lX", (PacketHeader.Type.TypeLong & 0x00FFFFFF));
+
+       switch (PacketHeader.Type.TypeLong & 0x00FFFFFF)
+       {
+               case SIDESHOW_CMD_PING:
+                       SideShow_Ping(&PacketHeader);
+                       break;
+               case SIDESHOW_CMD_SYNC:
+                       SideShow_Sync(&PacketHeader);
+                       break;
+               case SIDESHOW_CMD_GET_CURRENT_USER:
+                       SideShow_GetCurrentUser(&PacketHeader);
+                       break;
+               case SIDESHOW_CMD_SET_CURRENT_USER:
+                       SideShow_SetCurrentUser(&PacketHeader);
+                       break;
+               case SIDESHOW_CMD_GET_CAPABILITIES:
+                       SideShow_GetCapabilities(&PacketHeader);
+                       break;
+               case SIDESHOW_CMD_GET_DEVICE_NAME:
+                       SideShow_GetString(&PacketHeader, &DeviceName);
+                       break;
+               case SIDESHOW_CMD_GET_MANUFACTURER:
+                       SideShow_GetString(&PacketHeader, &Manufacturer);
+                       break;
+               case SIDESHOW_CMD_GET_APPLICATION_ORDER:
+                       SideShow_GetApplicationOrder(&PacketHeader);
+                       break;
+               case SIDESHOW_CMD_GET_SUPPORTED_ENDPOINTS:
+                       SideShow_GetSupportedEndpoints(&PacketHeader);
+                       break;
+               case SIDESHOW_CMD_ADD_APPLICATION:
+                       SideShow_AddApplication(&PacketHeader);
+                       break;
+               case SIDESHOW_CMD_ADD_CONTENT:
+                       SideShow_AddContent(&PacketHeader);
+                       break;
+               case SIDESHOW_CMD_DELETE_CONTENT:
+                       SideShow_DeleteContent(&PacketHeader);
+                       break;
+               case SIDESHOW_CMD_DELETE_ALL_CONTENT:
+                       SideShow_DeleteAllContent(&PacketHeader);
+                       break;
+               case SIDESHOW_CMD_DELETE_APPLICATION:
+                       SideShow_DeleteApplication(&PacketHeader);
+                       break;
+               case SIDESHOW_CMD_DELETE_ALL_APPLICATIONS:
+                       SideShow_DeleteAllApplications(&PacketHeader);
+                       break;
+               default:
+                       PacketHeader.Length -= sizeof(SideShow_PacketHeader_t);
+
+                       Endpoint_Discard_Stream(PacketHeader.Length, NULL);
+                       Endpoint_ClearOUT();
+
+                       PacketHeader.Length   = sizeof(SideShow_PacketHeader_t);
+                       PacketHeader.Type.TypeFields.NAK = true;
+
+                       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+                       Endpoint_Write_Stream_LE(&PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+                       Endpoint_ClearIN();
+
+                       printf(" UNK");
+       }
+}
+
+static void SideShow_Ping(SideShow_PacketHeader_t* const PacketHeader)
+{
+       Endpoint_ClearOUT();
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+       Endpoint_ClearIN();
+}
+
+static void SideShow_Sync(SideShow_PacketHeader_t* const PacketHeader)
+{
+       GUID_t ProtocolGUID;
+
+       Endpoint_Read_Stream_LE(&ProtocolGUID, sizeof(GUID_t), NULL);
+       Endpoint_ClearOUT();
+
+       if (!(GUID_COMPARE(&ProtocolGUID, (uint32_t[])STANDARD_PROTOCOL_GUID)))
+         PacketHeader->Type.TypeFields.NAK = true;
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+       Endpoint_Write_Stream_LE(&ProtocolGUID, sizeof(GUID_t), NULL);
+       Endpoint_ClearIN();
+}
+
+static void SideShow_GetCurrentUser(SideShow_PacketHeader_t* const PacketHeader)
+{
+       Endpoint_ClearOUT();
+
+       PacketHeader->Length = sizeof(SideShow_PacketHeader_t) + sizeof(uint32_t) + UserSID.LengthInBytes;
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+       SideShow_Write_Unicode_String(&UserSID);
+       Endpoint_ClearIN();
+}
+
+static void SideShow_SetCurrentUser(SideShow_PacketHeader_t* const PacketHeader)
+{
+       SideShow_Read_Unicode_String(&UserSID, sizeof(UserSID.UnicodeString));
+       Endpoint_ClearOUT();
+
+       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+       Endpoint_ClearIN();
+}
+
+static void SideShow_GetCapabilities(SideShow_PacketHeader_t* const PacketHeader)
+{
+       SideShow_PropertyKey_t  Property;
+       SideShow_PropertyData_t PropertyData;
+
+       Endpoint_Read_Stream_LE(&Property, sizeof(SideShow_PropertyKey_t), NULL);
+       Endpoint_ClearOUT();
+
+       printf(" ID: %lu", Property.PropertyID);
+
+       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);
+
+       if (GUID_COMPARE(&Property.PropertyGUID, (uint32_t[])SIDESHOW_PROPERTY_GUID))
+       {
+               switch (Property.PropertyID)
+               {
+                       case PROPERTY_SIDESHOW_SCREENTYPE:
+                               PropertyData.DataType    = VT_I4;
+                               PropertyData.Data.Data32 = ScreenText;
+                               PacketHeader->Length += sizeof(uint32_t);
+
+                               break;
+                       case PROPERTY_SIDESHOW_SCREENWIDTH:
+                       case PROPERTY_SIDESHOW_CLIENTWIDTH:
+                               PropertyData.DataType    = VT_UI2;
+                               PropertyData.Data.Data16 = 16;
+                               PacketHeader->Length += sizeof(uint16_t);
+
+                               break;
+                       case PROPERTY_SIDESHOW_SCREENHEIGHT:
+                       case PROPERTY_SIDESHOW_CLIENTHEIGHT:
+                               PropertyData.DataType    = VT_UI2;
+                               PropertyData.Data.Data16 = 2;
+                               PacketHeader->Length += sizeof(uint16_t);
+
+                               break;
+                       case PROPERTY_SIDESHOW_COLORDEPTH:
+                               PropertyData.DataType    = VT_UI2;
+                               PropertyData.Data.Data16 = 1;
+                               PacketHeader->Length += sizeof(uint16_t);
+
+                               break;
+                       case PROPERTY_SIDESHOW_COLORTYPE:
+                               PropertyData.DataType    = VT_UI2;
+                               PropertyData.Data.Data16 = BlackAndWhiteDisplay;
+                               PacketHeader->Length += sizeof(uint16_t);
+
+                               break;
+                       case PROPERTY_SIDESHOW_DATACACHE:
+                               PropertyData.DataType    = VT_BOOL;
+                               PropertyData.Data.Data16 = false;
+                               PacketHeader->Length += sizeof(uint16_t);
+
+                               break;
+                       case PROPERTY_SIDESHOW_SUPPORTEDLANGS:
+                       case PROPERTY_SIDESHOW_CURRENTLANG:
+                               PropertyData.DataType    = VT_LPWSTR;
+                               PropertyData.Data.DataPointer = &SupportedLanguage;
+                               PacketHeader->Length += SupportedLanguage.LengthInBytes;
+
+                               break;
+                       default:
+                               PropertyData.DataType    = VT_EMPTY;
+                               break;
+               }
+       }
+       else if (GUID_COMPARE(&Property.PropertyGUID, (uint32_t[])DEVICE_PROPERTY_GUID))
+       {
+               switch (Property.PropertyID)
+               {
+                       case PROPERTY_DEVICE_DEVICETYPE:
+                               PropertyData.DataType    = VT_UI4;
+                               PropertyData.Data.Data32 = GenericDevice;
+                               PacketHeader->Length += sizeof(uint32_t);
+
+                               break;
+               }
+       }
+       else
+       {
+               PacketHeader->Type.TypeFields.NAK = true;
+
+               printf(" WRONG GUID");
+               printf(" %lX %lX %lX %lX", Property.PropertyGUID.Chunks[0], Property.PropertyGUID.Chunks[1],
+                                          Property.PropertyGUID.Chunks[2],  Property.PropertyGUID.Chunks[3]);
+       }
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+
+       if (!(PacketHeader->Type.TypeFields.NAK))
+       {
+               switch (PropertyData.DataType)
+               {
+                       case VT_UI4:
+                       case VT_I4:
+                               Endpoint_Write_Stream_LE(&PropertyData.Data.Data32, sizeof(uint32_t), NULL);
+                               break;
+                       case VT_UI2:
+                       case VT_I2:
+                       case VT_BOOL:
+                               Endpoint_Write_Stream_LE(&PropertyData.Data.Data16, sizeof(uint16_t), NULL);
+                               break;
+                       case VT_LPWSTR:
+                               SideShow_Write_Unicode_String((Unicode_String_t*)PropertyData.Data.Data16);
+                               break;
+               }
+       }
+
+       Endpoint_ClearIN();
+       return;
+}
+
+static void SideShow_GetString(SideShow_PacketHeader_t* const PacketHeader,
+                               void* const UnicodeStruct)
+{
+       Endpoint_ClearOUT();
+
+       PacketHeader->Length = sizeof(SideShow_PacketHeader_t) +
+                              sizeof(uint32_t) + ((Unicode_String_t*)UnicodeStruct)->LengthInBytes;
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+       SideShow_Write_Unicode_String(UnicodeStruct);
+       Endpoint_ClearIN();
+}
+
+static void SideShow_GetApplicationOrder(SideShow_PacketHeader_t* const PacketHeader)
+{
+       uint8_t  TotalApplications = 0;
+
+       Endpoint_ClearOUT();
+
+       for (uint8_t App = 0; App < MAX_APPLICATIONS; App++)
+       {
+               if (InstalledApplications[App].InUse)
+                 TotalApplications++;
+       }
+
+       PacketHeader->Length = sizeof(SideShow_PacketHeader_t) +
+                              sizeof(uint32_t) + (TotalApplications * sizeof(GUID_t));
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+       Endpoint_Write_32_LE(TotalApplications);
+
+       for (uint8_t App = 0; App < MAX_APPLICATIONS; App++)
+       {
+               if (InstalledApplications[App].InUse)
+                 Endpoint_Write_Stream_LE(&InstalledApplications[App].ApplicationID, sizeof(GUID_t), NULL);
+       }
+
+       Endpoint_ClearIN();
+}
+
+static void SideShow_GetSupportedEndpoints(SideShow_PacketHeader_t* const PacketHeader)
+{
+       GUID_t SupportedEndpointGUID = (GUID_t){Chunks: SIMPLE_CONTENT_FORMAT_GUID};
+
+       Endpoint_ClearOUT();
+
+       PacketHeader->Length = sizeof(SideShow_PacketHeader_t) + sizeof(uint32_t) + sizeof(GUID_t);
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+       Endpoint_Write_32_LE(1);
+       Endpoint_Write_Stream_LE(&SupportedEndpointGUID, sizeof(GUID_t), NULL);
+       Endpoint_ClearIN();
+}
+
+static void SideShow_AddApplication(SideShow_PacketHeader_t* const PacketHeader)
+{
+       SideShow_Application_t* CurrApp;
+       GUID_t                  ApplicationID;
+
+       Endpoint_Read_Stream_LE(&ApplicationID, sizeof(GUID_t), NULL);
+
+       CurrApp = SideShow_GetApplicationFromGUID(&ApplicationID);
+
+       if (CurrApp == NULL)
+         CurrApp = SideShow_GetFreeApplication();
+
+       if (CurrApp == NULL)
+       {
+               PacketHeader->Length -= sizeof(SideShow_PacketHeader_t) + sizeof(GUID_t);
+
+               Endpoint_Discard_Stream(PacketHeader->Length, NULL);
+               Endpoint_ClearOUT();
+
+               PacketHeader->Type.TypeFields.NAK = true;
+       }
+       else
+       {
+               CurrApp->ApplicationID = ApplicationID;
+               Endpoint_Read_Stream_LE(&CurrApp->EndpointID, sizeof(GUID_t), NULL);
+               SideShow_Read_Unicode_String(&CurrApp->ApplicationName, sizeof(CurrApp->ApplicationName.UnicodeString));
+               Endpoint_Read_Stream_LE(&CurrApp->CachePolicy, sizeof(uint32_t), NULL);
+               Endpoint_Read_Stream_LE(&CurrApp->OnlineOnly, sizeof(uint32_t), NULL);
+               SideShow_Discard_Byte_Stream();
+               SideShow_Discard_Byte_Stream();
+               SideShow_Discard_Byte_Stream();
+               Endpoint_ClearOUT();
+
+               CurrApp->InUse = true;
+               CurrApp->HaveContent = false;
+               CurrApp->CurrentContentID = 1;
+       }
+
+       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+       Endpoint_ClearIN();
+}
+
+static void SideShow_DeleteApplication(SideShow_PacketHeader_t* const PacketHeader)
+{
+       GUID_t ApplicationGUID;
+
+       Endpoint_Read_Stream_LE(&ApplicationGUID, sizeof(GUID_t), NULL);
+       Endpoint_ClearOUT();
+
+       SideShow_Application_t* AppToDelete = SideShow_GetApplicationFromGUID(&ApplicationGUID);
+
+       if (AppToDelete != NULL)
+         AppToDelete->InUse = false;
+       else
+         PacketHeader->Type.TypeFields.NAK = true;
+
+       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+       Endpoint_ClearIN();
+}
+
+static void SideShow_DeleteAllApplications(SideShow_PacketHeader_t* const PacketHeader)
+{
+       Endpoint_ClearOUT();
+
+       for (uint8_t App = 0; App < MAX_APPLICATIONS; App++)
+         InstalledApplications[App].InUse = false;
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+       Endpoint_ClearIN();
+}
+
+static void SideShow_AddContent(SideShow_PacketHeader_t* const PacketHeader)
+{
+       GUID_t ApplicationID;
+       GUID_t EndpointID;
+       SideShow_Application_t* Application;
+
+       Endpoint_Read_Stream_LE(&ApplicationID, sizeof(GUID_t), NULL);
+       Endpoint_Read_Stream_LE(&EndpointID, sizeof(GUID_t), NULL);
+
+       Application = SideShow_GetApplicationFromGUID(&ApplicationID);
+
+       if (Application == NULL)
+       {
+               SideShow_Discard_Byte_Stream();
+               PacketHeader->Type.TypeFields.NAK = true;
+       }
+       else if (!(SideShow_AddSimpleContent(PacketHeader, Application)))
+       {
+               PacketHeader->Type.TypeFields.NAK = true;
+       }
+
+       Endpoint_ClearOUT();
+
+       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+       Endpoint_ClearIN();
+}
+
+static void SideShow_DeleteContent(SideShow_PacketHeader_t* const PacketHeader)
+{
+       GUID_t   ApplicationID;
+       GUID_t   EndpointID;
+       uint32_t ContentID;
+
+       Endpoint_Read_Stream_LE(&ApplicationID, sizeof(GUID_t), NULL);
+       Endpoint_Read_Stream_LE(&EndpointID, sizeof(GUID_t), NULL);
+       Endpoint_Read_Stream_LE(&ContentID, sizeof(uint32_t), NULL);
+       Endpoint_ClearOUT();
+
+       SideShow_Application_t* Application = SideShow_GetApplicationFromGUID(&ApplicationID);
+
+       if ((Application != NULL) && (Application->CurrentContentID == ContentID))
+         Application->HaveContent = false;
+       else
+         PacketHeader->Type.TypeFields.NAK = true;
+
+       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+       Endpoint_ClearIN();
+}
+
+static void SideShow_DeleteAllContent(SideShow_PacketHeader_t* const PacketHeader)
+{
+       GUID_t ApplicationID;
+       GUID_t EndpointID;
+
+       Endpoint_Read_Stream_LE(&ApplicationID, sizeof(GUID_t), NULL);
+       Endpoint_Read_Stream_LE(&EndpointID, sizeof(GUID_t), NULL);
+       Endpoint_ClearOUT();
+
+       SideShow_Application_t* Application = SideShow_GetApplicationFromGUID(&ApplicationID);
+
+       if (Application != NULL)
+         Application->HaveContent = false;
+       else
+         PacketHeader->Type.TypeFields.NAK = true;
+
+       PacketHeader->Length = sizeof(SideShow_PacketHeader_t);
+
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
+       Endpoint_ClearIN();
+}
+