Move unfinished SideShow source files to nested Lib directory for clarity.
[pub/lufa.git] / Demos / Device / Incomplete / Sideshow / Lib / SideshowCommands.c
diff --git a/Demos/Device/Incomplete/Sideshow/Lib/SideshowCommands.c b/Demos/Device/Incomplete/Sideshow/Lib/SideshowCommands.c
new file mode 100644 (file)
index 0000000..2726d50
--- /dev/null
@@ -0,0 +1,490 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  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 (memcmp(&ProtocolGUID, (uint32_t[])STANDARD_PROTOCOL_GUID, sizeof(GUID_t)) != 0)\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 (memcmp(&Property.PropertyGUID, (uint32_t[])SIDESHOW_PROPERTY_GUID, sizeof(GUID_t)) == 0)\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 (memcmp(&Property.PropertyGUID, (uint32_t[])DEVICE_PROPERTY_GUID, sizeof(GUID_t)) == 0)\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 TotalInstalledApplications = SideShow_GetTotalApplications();\r
+       uint16_t GadgetGUIDBytes           = (TotalInstalledApplications * sizeof(GUID_t));\r
+\r
+       Endpoint_ClearOUT();\r
+\r
+       PacketHeader->Length = sizeof(SideShow_PacketHeader_t) +\r
+                              sizeof(uint32_t) + GadgetGUIDBytes;\r
+       \r
+       Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);\r
+       Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t));\r
+       Endpoint_Write_DWord_LE(TotalInstalledApplications);\r
+       \r
+       for (uint8_t App = 0; App < MAX_APPLICATIONS; App++)\r
+       {\r
+               if (InstalledApplications[App].InUse == true)\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
+       {\r
+               AppToDelete->InUse = false;\r
+       }\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