3      Copyright (C) Dean Camera, 2009. 
   5   dean [at] fourwalledcubicle [dot] com 
   6       www.fourwalledcubicle.com 
  10   Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com) 
  12   Permission to use, copy, modify, and distribute this software 
  13   and its documentation for any purpose and without fee is hereby 
  14   granted, provided that the above copyright notice appear in all 
  15   copies and that both that the copyright notice and this 
  16   permission notice and warranty disclaimer appear in supporting 
  17   documentation, and that the name of the author not be used in 
  18   advertising or publicity pertaining to distribution of the 
  19   software without specific, written prior permission. 
  21   The author disclaim all warranties with regard to this 
  22   software, including all implied warranties of merchantability 
  23   and fitness.  In no event shall the author be liable for any 
  24   special, indirect or consequential damages or any damages 
  25   whatsoever resulting from loss of use, data or profits, whether 
  26   in an action of contract, negligence or other tortious action, 
  27   arising out of or in connection with the use or performance of 
  31 #define  INCLUDE_FROM_SIDESHOWCOMMANDS_H 
  32 #include "SideshowCommands.h" 
  34 UNICODE_STRING_t(80) UserSID       
= {LengthInBytes
: sizeof(SECURITY_INTERACTIVE_RID_SID
), 
  35                                       UnicodeString
: SECURITY_INTERACTIVE_RID_SID
}; 
  37 Unicode_String_t DeviceName        
= {LengthInBytes
: sizeof(L
"LUFA Sideshow Device"), 
  38                                       UnicodeString
: L
"LUFA Sideshow Device"}; 
  40 Unicode_String_t Manufacturer      
= {LengthInBytes
: sizeof(L
"Dean Camera"), 
  41                                       UnicodeString
: L
"Dean Camera"}; 
  43 Unicode_String_t SupportedLanguage 
= {LengthInBytes
: sizeof(L
"en-US:1"), 
  44                                       UnicodeString
: L
"en-US:1"}; 
  46 void Sideshow_ProcessCommandPacket(void) 
  48         SideShow_PacketHeader_t PacketHeader
; 
  50         Endpoint_SelectEndpoint(SIDESHOW_OUT_EPNUM
);     
  51         Endpoint_Read_Stream_LE(&PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
  53         PacketHeader
.Type
.Response 
= true; 
  55         printf("\r\nCmd: %lX", (PacketHeader
.Type
.TypeLong 
& 0x00FFFFFF)); 
  57         switch (PacketHeader
.Type
.TypeLong 
& 0x00FFFFFF) 
  59                 case SIDESHOW_CMD_PING
: 
  60                         SideShow_Ping(&PacketHeader
); 
  62                 case SIDESHOW_CMD_SYNC
: 
  63                         SideShow_Sync(&PacketHeader
); 
  65                 case SIDESHOW_CMD_GET_CURRENT_USER
: 
  66                         SideShow_GetCurrentUser(&PacketHeader
); 
  68                 case SIDESHOW_CMD_SET_CURRENT_USER
: 
  69                         SideShow_SetCurrentUser(&PacketHeader
); 
  71                 case SIDESHOW_CMD_GET_CAPABILITIES
: 
  72                         SideShow_GetCapabilities(&PacketHeader
); 
  74                 case SIDESHOW_CMD_GET_DEVICE_NAME
: 
  75                         SideShow_GetString(&PacketHeader
, &DeviceName
); 
  77                 case SIDESHOW_CMD_GET_MANUFACTURER
: 
  78                         SideShow_GetString(&PacketHeader
, &Manufacturer
); 
  80                 case SIDESHOW_CMD_GET_APPLICATION_ORDER
: 
  81                         SideShow_GetApplicationOrder(&PacketHeader
); 
  83                 case SIDESHOW_CMD_GET_SUPPORTED_ENDPOINTS
: 
  84                         SideShow_GetSupportedEndpoints(&PacketHeader
); 
  86                 case SIDESHOW_CMD_ADD_APPLICATION
: 
  87                         SideShow_AddApplication(&PacketHeader
); 
  89                 case SIDESHOW_CMD_ADD_CONTENT
: 
  90                         SideShow_AddContent(&PacketHeader
); 
  92                 case SIDESHOW_CMD_DELETE_CONTENT
: 
  93                         SideShow_DeleteContent(&PacketHeader
); 
  95                 case SIDESHOW_CMD_DELETE_ALL_CONTENT
: 
  96                         SideShow_DeleteAllContent(&PacketHeader
); 
  98                 case SIDESHOW_CMD_DELETE_APPLICATION
: 
  99                         SideShow_DeleteApplication(&PacketHeader
); 
 101                 case SIDESHOW_CMD_DELETE_ALL_APPLICATIONS
: 
 102                         SideShow_DeleteAllApplications(&PacketHeader
); 
 105                         PacketHeader
.Length 
-= sizeof(SideShow_PacketHeader_t
); 
 107                         Endpoint_Discard_Stream(PacketHeader
.Length
); 
 110                         PacketHeader
.Length   
= sizeof(SideShow_PacketHeader_t
); 
 111                         PacketHeader
.Type
.NAK 
= true; 
 113                         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);      
 114                         Endpoint_Write_Stream_LE(&PacketHeader
, sizeof(SideShow_PacketHeader_t
));                
 121 static void SideShow_Ping(SideShow_PacketHeader_t
* PacketHeader
) 
 125         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
);      
 126         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));                 
 130 static void SideShow_Sync(SideShow_PacketHeader_t
* PacketHeader
) 
 134         Endpoint_Read_Stream_LE(&ProtocolGUID
, sizeof(GUID_t
)); 
 137         if (!(GUID_COMPARE(&ProtocolGUID
, (uint32_t[])STANDARD_PROTOCOL_GUID
))) 
 138           PacketHeader
->Type
.NAK 
= true; 
 140         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 141         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));                 
 142         Endpoint_Write_Stream_LE(&ProtocolGUID
, sizeof(GUID_t
)); 
 146 static void SideShow_GetCurrentUser(SideShow_PacketHeader_t
* PacketHeader
) 
 150         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
) + sizeof(uint32_t) + UserSID
.LengthInBytes
; 
 152         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 153         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 154         SideShow_Write_Unicode_String(&UserSID
); 
 158 static void SideShow_SetCurrentUser(SideShow_PacketHeader_t
* PacketHeader
) 
 160         SideShow_Read_Unicode_String(&UserSID
, sizeof(UserSID
.UnicodeString
)); 
 163         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 165         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 166         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 170 static void SideShow_GetCapabilities(SideShow_PacketHeader_t
* PacketHeader
) 
 172         SideShow_PropertyKey_t  Property
; 
 173         SideShow_PropertyData_t PropertyData
; 
 175         Endpoint_Read_Stream_LE(&Property
, sizeof(SideShow_PropertyKey_t
)); 
 178         printf(" ID: %lu", Property
.PropertyID
); 
 180         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 182         if (GUID_COMPARE(&Property
.PropertyGUID
, (uint32_t[])SIDESHOW_PROPERTY_GUID
)) 
 184                 switch (Property
.PropertyID
) 
 186                         case PROPERTY_SIDESHOW_SCREENTYPE
: 
 187                                 PropertyData
.DataType    
= VT_I4
; 
 188                                 PropertyData
.Data
.Data32 
= ScreenText
; 
 189                                 PacketHeader
->Length 
+= sizeof(uint32_t); 
 192                         case PROPERTY_SIDESHOW_SCREENWIDTH
: 
 193                         case PROPERTY_SIDESHOW_CLIENTWIDTH
: 
 194                                 PropertyData
.DataType    
= VT_UI2
; 
 195                                 PropertyData
.Data
.Data16 
= 16; 
 196                                 PacketHeader
->Length 
+= sizeof(uint16_t); 
 199                         case PROPERTY_SIDESHOW_SCREENHEIGHT
: 
 200                         case PROPERTY_SIDESHOW_CLIENTHEIGHT
: 
 201                                 PropertyData
.DataType    
= VT_UI2
; 
 202                                 PropertyData
.Data
.Data16 
= 2; 
 203                                 PacketHeader
->Length 
+= sizeof(uint16_t); 
 206                         case PROPERTY_SIDESHOW_COLORDEPTH
: 
 207                                 PropertyData
.DataType    
= VT_UI2
; 
 208                                 PropertyData
.Data
.Data16 
= 1; 
 209                                 PacketHeader
->Length 
+= sizeof(uint16_t); 
 212                         case PROPERTY_SIDESHOW_COLORTYPE
: 
 213                                 PropertyData
.DataType    
= VT_UI2
; 
 214                                 PropertyData
.Data
.Data16 
= BlackAndWhiteDisplay
; 
 215                                 PacketHeader
->Length 
+= sizeof(uint16_t); 
 218                         case PROPERTY_SIDESHOW_DATACACHE
: 
 219                                 PropertyData
.DataType    
= VT_BOOL
; 
 220                                 PropertyData
.Data
.Data16 
= false; 
 221                                 PacketHeader
->Length 
+= sizeof(uint16_t); 
 224                         case PROPERTY_SIDESHOW_SUPPORTEDLANGS
: 
 225                         case PROPERTY_SIDESHOW_CURRENTLANG
: 
 226                                 PropertyData
.DataType    
= VT_LPWSTR
; 
 227                                 PropertyData
.Data
.DataPointer 
= &SupportedLanguage
; 
 228                                 PacketHeader
->Length 
+= SupportedLanguage
.LengthInBytes
; 
 232                                 PropertyData
.DataType    
= VT_EMPTY
; 
 236         else if (GUID_COMPARE(&Property
.PropertyGUID
, (uint32_t[])DEVICE_PROPERTY_GUID
)) 
 238                 switch (Property
.PropertyID
) 
 240                         case PROPERTY_DEVICE_DEVICETYPE
: 
 241                                 PropertyData
.DataType    
= VT_UI4
; 
 242                                 PropertyData
.Data
.Data32 
= GenericDevice
; 
 243                                 PacketHeader
->Length 
+= sizeof(uint32_t); 
 250                 PacketHeader
->Type
.NAK 
= true;           
 252                 printf(" WRONG GUID"); 
 253                 printf(" %lX %lX %lX %lX", Property
.PropertyGUID
.Chunks
[0], Property
.PropertyGUID
.Chunks
[1], 
 254                                            Property
.PropertyGUID
.Chunks
[2],  Property
.PropertyGUID
.Chunks
[3]);           
 257         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 258         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 260         if (!(PacketHeader
->Type
.NAK
)) 
 262                 switch (PropertyData
.DataType
) 
 266                                 Endpoint_Write_Stream_LE(&PropertyData
.Data
.Data32
, sizeof(uint32_t)); 
 271                                 Endpoint_Write_Stream_LE(&PropertyData
.Data
.Data16
, sizeof(uint16_t)); 
 274                                 SideShow_Write_Unicode_String((Unicode_String_t
*)PropertyData
.Data
.Data16
); 
 283 static void SideShow_GetString(SideShow_PacketHeader_t
* PacketHeader
, void* UnicodeStruct
) 
 287         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
) + 
 288                                sizeof(uint32_t) + ((Unicode_String_t
*)UnicodeStruct
)->LengthInBytes
; 
 290         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 291         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 292         SideShow_Write_Unicode_String(UnicodeStruct
); 
 296 static void SideShow_GetApplicationOrder(SideShow_PacketHeader_t
* PacketHeader
) 
 298         uint8_t TotalInstalledApplications 
= SideShow_GetTotalApplications(); 
 299         uint16_t GadgetGUIDBytes           
= (TotalInstalledApplications 
* sizeof(GUID_t
)); 
 303         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
) + 
 304                                sizeof(uint32_t) + GadgetGUIDBytes
; 
 306         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 307         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 308         Endpoint_Write_DWord_LE(TotalInstalledApplications
); 
 310         for (uint8_t App 
= 0; App 
< MAX_APPLICATIONS
; App
++) 
 312                 if (InstalledApplications
[App
].InUse 
== true) 
 313                   Endpoint_Write_Stream_LE(&InstalledApplications
[App
].ApplicationID
, sizeof(GUID_t
)); 
 319 static void SideShow_GetSupportedEndpoints(SideShow_PacketHeader_t
* PacketHeader
) 
 321         GUID_t SupportedEndpointGUID 
= (GUID_t
){Chunks
: SIMPLE_CONTENT_FORMAT_GUID
}; 
 325         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
) + sizeof(uint32_t) + sizeof(GUID_t
); 
 327         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 328         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 329         Endpoint_Write_DWord_LE(1); 
 330         Endpoint_Write_Stream_LE(&SupportedEndpointGUID
, sizeof(GUID_t
)); 
 334 static void SideShow_AddApplication(SideShow_PacketHeader_t
* PacketHeader
) 
 336         SideShow_Application_t
* CurrApp
; 
 337         GUID_t                  ApplicationID
; 
 339         Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
)); 
 341         CurrApp 
= SideShow_GetApplicationFromGUID(&ApplicationID
); 
 344           CurrApp 
= SideShow_GetFreeApplication(); 
 348                 PacketHeader
->Length 
-= sizeof(SideShow_PacketHeader_t
) + sizeof(GUID_t
); 
 350                 Endpoint_Discard_Stream(PacketHeader
->Length
); 
 353                 PacketHeader
->Type
.NAK 
= true; 
 357                 CurrApp
->ApplicationID 
= ApplicationID
; 
 358                 Endpoint_Read_Stream_LE(&CurrApp
->EndpointID
, sizeof(GUID_t
)); 
 359                 SideShow_Read_Unicode_String(&CurrApp
->ApplicationName
, sizeof(CurrApp
->ApplicationName
.UnicodeString
)); 
 360                 Endpoint_Read_Stream_LE(&CurrApp
->CachePolicy
, sizeof(uint32_t)); 
 361                 Endpoint_Read_Stream_LE(&CurrApp
->OnlineOnly
, sizeof(uint32_t)); 
 362                 SideShow_Discard_Byte_Stream(); 
 363                 SideShow_Discard_Byte_Stream(); 
 364                 SideShow_Discard_Byte_Stream(); 
 367                 CurrApp
->InUse 
= true; 
 368                 CurrApp
->HaveContent 
= false; 
 369                 CurrApp
->CurrentContentID 
= 1; 
 372         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 374         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 375         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 379 static void SideShow_DeleteApplication(SideShow_PacketHeader_t
* PacketHeader
) 
 381         GUID_t ApplicationGUID
; 
 383         Endpoint_Read_Stream_LE(&ApplicationGUID
, sizeof(GUID_t
));       
 386         SideShow_Application_t
* AppToDelete 
= SideShow_GetApplicationFromGUID(&ApplicationGUID
); 
 388         if (AppToDelete 
!= NULL
) 
 390                 AppToDelete
->InUse 
= false; 
 393           PacketHeader
->Type
.NAK 
= true; 
 395         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 397         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 398         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 402 static void SideShow_DeleteAllApplications(SideShow_PacketHeader_t
* PacketHeader
) 
 406         for (uint8_t App 
= 0; App 
< MAX_APPLICATIONS
; App
++) 
 407           InstalledApplications
[App
].InUse 
= false; 
 409         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 410         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 414 static void SideShow_AddContent(SideShow_PacketHeader_t
* PacketHeader
) 
 416         GUID_t ApplicationID
; 
 418         SideShow_Application_t
* Application
; 
 420         Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
)); 
 421         Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
)); 
 423         Application 
= SideShow_GetApplicationFromGUID(&ApplicationID
); 
 425         if (Application 
== NULL
) 
 427                 SideShow_Discard_Byte_Stream(); 
 428                 PacketHeader
->Type
.NAK 
= true; 
 430         else if (!(SideShow_AddSimpleContent(PacketHeader
, Application
))) 
 432                 PacketHeader
->Type
.NAK 
= true; 
 437         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 439         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 440         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 444 static void SideShow_DeleteContent(SideShow_PacketHeader_t
* PacketHeader
) 
 446         GUID_t   ApplicationID
; 
 450         Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
)); 
 451         Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
)); 
 452         Endpoint_Read_Stream_LE(&ContentID
, sizeof(uint32_t)); 
 455         SideShow_Application_t
* Application 
= SideShow_GetApplicationFromGUID(&ApplicationID
); 
 457         if ((Application 
!= NULL
) && (Application
->CurrentContentID 
== ContentID
)) 
 458           Application
->HaveContent 
= false; 
 460           PacketHeader
->Type
.NAK 
= true; 
 462         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 464         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 465         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 469 static void SideShow_DeleteAllContent(SideShow_PacketHeader_t
* PacketHeader
) 
 471         GUID_t ApplicationID
; 
 474         Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
)); 
 475         Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
)); 
 478         SideShow_Application_t
* Application 
= SideShow_GetApplicationFromGUID(&ApplicationID
); 
 480         if (Application 
!= NULL
) 
 481           Application
->HaveContent 
= false; 
 483           PacketHeader
->Type
.NAK 
= true;           
 485         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 487         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 488         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));