-/*\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();
+}
+