3      Copyright (C) Dean Camera, 2011. 
   5   dean [at] fourwalledcubicle [dot] com 
  10   Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com) 
  12   Permission to use, copy, modify, distribute, and sell this 
  13   software and its documentation for any purpose is hereby granted 
  14   without fee, provided that the above copyright notice appear in 
  15   all copies and that both that the copyright notice and this 
  16   permission notice and warranty disclaimer appear in supporting 
  17   documentation, and that the name of the author not be used in 
  18   advertising or publicity pertaining to distribution of the 
  19   software without specific, written prior permission. 
  21   The author disclaim all warranties with regard to this 
  22   software, including all implied warranties of merchantability 
  23   and fitness.  In no event shall the author be liable for any 
  24   special, indirect or consequential damages or any damages 
  25   whatsoever resulting from loss of use, data or profits, whether 
  26   in an action of contract, negligence or other tortious action, 
  27   arising out of or in connection with the use or performance of 
  31 #define  INCLUDE_FROM_SIDESHOWCOMMANDS_H 
  32 #include "SideshowCommands.h" 
  34 UNICODE_STRING_t(80) UserSID       
= {LengthInBytes
: sizeof(SECURITY_INTERACTIVE_RID_SID
), 
  35                                       UnicodeString
: SECURITY_INTERACTIVE_RID_SID
}; 
  37 Unicode_String_t DeviceName        
= {LengthInBytes
: sizeof(L
"LUFA Sideshow Device"), 
  38                                       UnicodeString
: L
"LUFA Sideshow Device"}; 
  40 Unicode_String_t Manufacturer      
= {LengthInBytes
: sizeof(L
"Dean Camera"), 
  41                                       UnicodeString
: L
"Dean Camera"}; 
  43 Unicode_String_t SupportedLanguage 
= {LengthInBytes
: sizeof(L
"en-US:1"), 
  44                                       UnicodeString
: L
"en-US:1"}; 
  46 void Sideshow_ProcessCommandPacket(void) 
  48         SideShow_PacketHeader_t PacketHeader
; 
  50         Endpoint_SelectEndpoint(SIDESHOW_OUT_EPNUM
); 
  51         Endpoint_Read_Stream_LE(&PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
  53         PacketHeader
.Type
.TypeFields
.Response 
= true; 
  55         printf("\r\nCmd: %lX", (PacketHeader
.Type
.TypeLong 
& 0x00FFFFFF)); 
  57         switch (PacketHeader
.Type
.TypeLong 
& 0x00FFFFFF) 
  59                 case SIDESHOW_CMD_PING
: 
  60                         SideShow_Ping(&PacketHeader
); 
  62                 case SIDESHOW_CMD_SYNC
: 
  63                         SideShow_Sync(&PacketHeader
); 
  65                 case SIDESHOW_CMD_GET_CURRENT_USER
: 
  66                         SideShow_GetCurrentUser(&PacketHeader
); 
  68                 case SIDESHOW_CMD_SET_CURRENT_USER
: 
  69                         SideShow_SetCurrentUser(&PacketHeader
); 
  71                 case SIDESHOW_CMD_GET_CAPABILITIES
: 
  72                         SideShow_GetCapabilities(&PacketHeader
); 
  74                 case SIDESHOW_CMD_GET_DEVICE_NAME
: 
  75                         SideShow_GetString(&PacketHeader
, &DeviceName
); 
  77                 case SIDESHOW_CMD_GET_MANUFACTURER
: 
  78                         SideShow_GetString(&PacketHeader
, &Manufacturer
); 
  80                 case SIDESHOW_CMD_GET_APPLICATION_ORDER
: 
  81                         SideShow_GetApplicationOrder(&PacketHeader
); 
  83                 case SIDESHOW_CMD_GET_SUPPORTED_ENDPOINTS
: 
  84                         SideShow_GetSupportedEndpoints(&PacketHeader
); 
  86                 case SIDESHOW_CMD_ADD_APPLICATION
: 
  87                         SideShow_AddApplication(&PacketHeader
); 
  89                 case SIDESHOW_CMD_ADD_CONTENT
: 
  90                         SideShow_AddContent(&PacketHeader
); 
  92                 case SIDESHOW_CMD_DELETE_CONTENT
: 
  93                         SideShow_DeleteContent(&PacketHeader
); 
  95                 case SIDESHOW_CMD_DELETE_ALL_CONTENT
: 
  96                         SideShow_DeleteAllContent(&PacketHeader
); 
  98                 case SIDESHOW_CMD_DELETE_APPLICATION
: 
  99                         SideShow_DeleteApplication(&PacketHeader
); 
 101                 case SIDESHOW_CMD_DELETE_ALL_APPLICATIONS
: 
 102                         SideShow_DeleteAllApplications(&PacketHeader
); 
 105                         PacketHeader
.Length 
-= sizeof(SideShow_PacketHeader_t
); 
 107                         Endpoint_Discard_Stream(PacketHeader
.Length
, NULL
); 
 110                         PacketHeader
.Length   
= sizeof(SideShow_PacketHeader_t
); 
 111                         PacketHeader
.Type
.TypeFields
.NAK 
= true; 
 113                         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 114                         Endpoint_Write_Stream_LE(&PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 121 static void SideShow_Ping(SideShow_PacketHeader_t
* const PacketHeader
) 
 125         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 126         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 130 static void SideShow_Sync(SideShow_PacketHeader_t
* const PacketHeader
) 
 134         Endpoint_Read_Stream_LE(&ProtocolGUID
, sizeof(GUID_t
), NULL
); 
 137         if (!(GUID_COMPARE(&ProtocolGUID
, (uint32_t[])STANDARD_PROTOCOL_GUID
))) 
 138           PacketHeader
->Type
.TypeFields
.NAK 
= true; 
 140         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 141         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 142         Endpoint_Write_Stream_LE(&ProtocolGUID
, sizeof(GUID_t
), NULL
); 
 146 static void SideShow_GetCurrentUser(SideShow_PacketHeader_t
* const PacketHeader
) 
 150         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
) + sizeof(uint32_t) + UserSID
.LengthInBytes
; 
 152         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 153         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 154         SideShow_Write_Unicode_String(&UserSID
); 
 158 static void SideShow_SetCurrentUser(SideShow_PacketHeader_t
* const PacketHeader
) 
 160         SideShow_Read_Unicode_String(&UserSID
, sizeof(UserSID
.UnicodeString
)); 
 163         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 165         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 166         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 170 static void SideShow_GetCapabilities(SideShow_PacketHeader_t
* const PacketHeader
) 
 172         SideShow_PropertyKey_t  Property
; 
 173         SideShow_PropertyData_t PropertyData
; 
 175         Endpoint_Read_Stream_LE(&Property
, sizeof(SideShow_PropertyKey_t
), NULL
); 
 178         printf(" ID: %lu", Property
.PropertyID
); 
 180         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 182         if (GUID_COMPARE(&Property
.PropertyGUID
, (uint32_t[])SIDESHOW_PROPERTY_GUID
)) 
 184                 switch (Property
.PropertyID
) 
 186                         case PROPERTY_SIDESHOW_SCREENTYPE
: 
 187                                 PropertyData
.DataType    
= VT_I4
; 
 188                                 PropertyData
.Data
.Data32 
= ScreenText
; 
 189                                 PacketHeader
->Length 
+= sizeof(uint32_t); 
 192                         case PROPERTY_SIDESHOW_SCREENWIDTH
: 
 193                         case PROPERTY_SIDESHOW_CLIENTWIDTH
: 
 194                                 PropertyData
.DataType    
= VT_UI2
; 
 195                                 PropertyData
.Data
.Data16 
= 16; 
 196                                 PacketHeader
->Length 
+= sizeof(uint16_t); 
 199                         case PROPERTY_SIDESHOW_SCREENHEIGHT
: 
 200                         case PROPERTY_SIDESHOW_CLIENTHEIGHT
: 
 201                                 PropertyData
.DataType    
= VT_UI2
; 
 202                                 PropertyData
.Data
.Data16 
= 2; 
 203                                 PacketHeader
->Length 
+= sizeof(uint16_t); 
 206                         case PROPERTY_SIDESHOW_COLORDEPTH
: 
 207                                 PropertyData
.DataType    
= VT_UI2
; 
 208                                 PropertyData
.Data
.Data16 
= 1; 
 209                                 PacketHeader
->Length 
+= sizeof(uint16_t); 
 212                         case PROPERTY_SIDESHOW_COLORTYPE
: 
 213                                 PropertyData
.DataType    
= VT_UI2
; 
 214                                 PropertyData
.Data
.Data16 
= BlackAndWhiteDisplay
; 
 215                                 PacketHeader
->Length 
+= sizeof(uint16_t); 
 218                         case PROPERTY_SIDESHOW_DATACACHE
: 
 219                                 PropertyData
.DataType    
= VT_BOOL
; 
 220                                 PropertyData
.Data
.Data16 
= false; 
 221                                 PacketHeader
->Length 
+= sizeof(uint16_t); 
 224                         case PROPERTY_SIDESHOW_SUPPORTEDLANGS
: 
 225                         case PROPERTY_SIDESHOW_CURRENTLANG
: 
 226                                 PropertyData
.DataType    
= VT_LPWSTR
; 
 227                                 PropertyData
.Data
.DataPointer 
= &SupportedLanguage
; 
 228                                 PacketHeader
->Length 
+= SupportedLanguage
.LengthInBytes
; 
 232                                 PropertyData
.DataType    
= VT_EMPTY
; 
 236         else if (GUID_COMPARE(&Property
.PropertyGUID
, (uint32_t[])DEVICE_PROPERTY_GUID
)) 
 238                 switch (Property
.PropertyID
) 
 240                         case PROPERTY_DEVICE_DEVICETYPE
: 
 241                                 PropertyData
.DataType    
= VT_UI4
; 
 242                                 PropertyData
.Data
.Data32 
= GenericDevice
; 
 243                                 PacketHeader
->Length 
+= sizeof(uint32_t); 
 250                 PacketHeader
->Type
.TypeFields
.NAK 
= true; 
 252                 printf(" WRONG GUID"); 
 253                 printf(" %lX %lX %lX %lX", Property
.PropertyGUID
.Chunks
[0], Property
.PropertyGUID
.Chunks
[1], 
 254                                            Property
.PropertyGUID
.Chunks
[2],  Property
.PropertyGUID
.Chunks
[3]); 
 257         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 258         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 260         if (!(PacketHeader
->Type
.TypeFields
.NAK
)) 
 262                 switch (PropertyData
.DataType
) 
 266                                 Endpoint_Write_Stream_LE(&PropertyData
.Data
.Data32
, sizeof(uint32_t), NULL
); 
 271                                 Endpoint_Write_Stream_LE(&PropertyData
.Data
.Data16
, sizeof(uint16_t), NULL
); 
 274                                 SideShow_Write_Unicode_String((Unicode_String_t
*)PropertyData
.Data
.Data16
); 
 283 static void SideShow_GetString(SideShow_PacketHeader_t
* const PacketHeader
, 
 284                                void* const UnicodeStruct
) 
 288         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
) + 
 289                                sizeof(uint32_t) + ((Unicode_String_t
*)UnicodeStruct
)->LengthInBytes
; 
 291         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 292         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 293         SideShow_Write_Unicode_String(UnicodeStruct
); 
 297 static void SideShow_GetApplicationOrder(SideShow_PacketHeader_t
* const PacketHeader
) 
 299         uint8_t  TotalApplications 
= 0; 
 303         for (uint8_t App 
= 0; App 
< MAX_APPLICATIONS
; App
++) 
 305                 if (InstalledApplications
[App
].InUse
) 
 309         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
) + 
 310                                sizeof(uint32_t) + (TotalApplications 
* sizeof(GUID_t
)); 
 312         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 313         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 314         Endpoint_Write_DWord_LE(TotalApplications
); 
 316         for (uint8_t App 
= 0; App 
< MAX_APPLICATIONS
; App
++) 
 318                 if (InstalledApplications
[App
].InUse
) 
 319                   Endpoint_Write_Stream_LE(&InstalledApplications
[App
].ApplicationID
, sizeof(GUID_t
), NULL
); 
 325 static void SideShow_GetSupportedEndpoints(SideShow_PacketHeader_t
* const PacketHeader
) 
 327         GUID_t SupportedEndpointGUID 
= (GUID_t
){Chunks
: SIMPLE_CONTENT_FORMAT_GUID
}; 
 331         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
) + sizeof(uint32_t) + sizeof(GUID_t
); 
 333         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 334         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 335         Endpoint_Write_DWord_LE(1); 
 336         Endpoint_Write_Stream_LE(&SupportedEndpointGUID
, sizeof(GUID_t
), NULL
); 
 340 static void SideShow_AddApplication(SideShow_PacketHeader_t
* const PacketHeader
) 
 342         SideShow_Application_t
* CurrApp
; 
 343         GUID_t                  ApplicationID
; 
 345         Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
), NULL
); 
 347         CurrApp 
= SideShow_GetApplicationFromGUID(&ApplicationID
); 
 350           CurrApp 
= SideShow_GetFreeApplication(); 
 354                 PacketHeader
->Length 
-= sizeof(SideShow_PacketHeader_t
) + sizeof(GUID_t
); 
 356                 Endpoint_Discard_Stream(PacketHeader
->Length
, NULL
); 
 359                 PacketHeader
->Type
.TypeFields
.NAK 
= true; 
 363                 CurrApp
->ApplicationID 
= ApplicationID
; 
 364                 Endpoint_Read_Stream_LE(&CurrApp
->EndpointID
, sizeof(GUID_t
), NULL
); 
 365                 SideShow_Read_Unicode_String(&CurrApp
->ApplicationName
, sizeof(CurrApp
->ApplicationName
.UnicodeString
)); 
 366                 Endpoint_Read_Stream_LE(&CurrApp
->CachePolicy
, sizeof(uint32_t), NULL
); 
 367                 Endpoint_Read_Stream_LE(&CurrApp
->OnlineOnly
, sizeof(uint32_t), NULL
); 
 368                 SideShow_Discard_Byte_Stream(); 
 369                 SideShow_Discard_Byte_Stream(); 
 370                 SideShow_Discard_Byte_Stream(); 
 373                 CurrApp
->InUse 
= true; 
 374                 CurrApp
->HaveContent 
= false; 
 375                 CurrApp
->CurrentContentID 
= 1; 
 378         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 380         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 381         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 385 static void SideShow_DeleteApplication(SideShow_PacketHeader_t
* const PacketHeader
) 
 387         GUID_t ApplicationGUID
; 
 389         Endpoint_Read_Stream_LE(&ApplicationGUID
, sizeof(GUID_t
), NULL
); 
 392         SideShow_Application_t
* AppToDelete 
= SideShow_GetApplicationFromGUID(&ApplicationGUID
); 
 394         if (AppToDelete 
!= NULL
) 
 395           AppToDelete
->InUse 
= false; 
 397           PacketHeader
->Type
.TypeFields
.NAK 
= true; 
 399         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 401         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 402         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 406 static void SideShow_DeleteAllApplications(SideShow_PacketHeader_t
* const PacketHeader
) 
 410         for (uint8_t App 
= 0; App 
< MAX_APPLICATIONS
; App
++) 
 411           InstalledApplications
[App
].InUse 
= false; 
 413         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 414         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 418 static void SideShow_AddContent(SideShow_PacketHeader_t
* const PacketHeader
) 
 420         GUID_t ApplicationID
; 
 422         SideShow_Application_t
* Application
; 
 424         Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
), NULL
); 
 425         Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
), NULL
); 
 427         Application 
= SideShow_GetApplicationFromGUID(&ApplicationID
); 
 429         if (Application 
== NULL
) 
 431                 SideShow_Discard_Byte_Stream(); 
 432                 PacketHeader
->Type
.TypeFields
.NAK 
= true; 
 434         else if (!(SideShow_AddSimpleContent(PacketHeader
, Application
))) 
 436                 PacketHeader
->Type
.TypeFields
.NAK 
= true; 
 441         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 443         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 444         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 448 static void SideShow_DeleteContent(SideShow_PacketHeader_t
* const PacketHeader
) 
 450         GUID_t   ApplicationID
; 
 454         Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
), NULL
); 
 455         Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
), NULL
); 
 456         Endpoint_Read_Stream_LE(&ContentID
, sizeof(uint32_t), NULL
); 
 459         SideShow_Application_t
* Application 
= SideShow_GetApplicationFromGUID(&ApplicationID
); 
 461         if ((Application 
!= NULL
) && (Application
->CurrentContentID 
== ContentID
)) 
 462           Application
->HaveContent 
= false; 
 464           PacketHeader
->Type
.TypeFields
.NAK 
= true; 
 466         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 468         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 469         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
); 
 473 static void SideShow_DeleteAllContent(SideShow_PacketHeader_t
* const PacketHeader
) 
 475         GUID_t ApplicationID
; 
 478         Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
), NULL
); 
 479         Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
), NULL
); 
 482         SideShow_Application_t
* Application 
= SideShow_GetApplicationFromGUID(&ApplicationID
); 
 484         if (Application 
!= NULL
) 
 485           Application
->HaveContent 
= false; 
 487           PacketHeader
->Type
.TypeFields
.NAK 
= true; 
 489         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 491         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 492         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
), NULL
);