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  TotalApplications 
= 0; 
 302         for (uint8_t App 
= 0; App 
< MAX_APPLICATIONS
; App
++) 
 304                 if (InstalledApplications
[App
].InUse
) 
 308         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
) + 
 309                                sizeof(uint32_t) + (TotalApplications 
* sizeof(GUID_t
)); 
 311         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 312         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 313         Endpoint_Write_DWord_LE(TotalApplications
); 
 315         for (uint8_t App 
= 0; App 
< MAX_APPLICATIONS
; App
++) 
 317                 if (InstalledApplications
[App
].InUse
) 
 318                   Endpoint_Write_Stream_LE(&InstalledApplications
[App
].ApplicationID
, sizeof(GUID_t
)); 
 324 static void SideShow_GetSupportedEndpoints(SideShow_PacketHeader_t
* PacketHeader
) 
 326         GUID_t SupportedEndpointGUID 
= (GUID_t
){Chunks
: SIMPLE_CONTENT_FORMAT_GUID
}; 
 330         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
) + sizeof(uint32_t) + sizeof(GUID_t
); 
 332         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 333         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 334         Endpoint_Write_DWord_LE(1); 
 335         Endpoint_Write_Stream_LE(&SupportedEndpointGUID
, sizeof(GUID_t
)); 
 339 static void SideShow_AddApplication(SideShow_PacketHeader_t
* PacketHeader
) 
 341         SideShow_Application_t
* CurrApp
; 
 342         GUID_t                  ApplicationID
; 
 344         Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
)); 
 346         CurrApp 
= SideShow_GetApplicationFromGUID(&ApplicationID
); 
 349           CurrApp 
= SideShow_GetFreeApplication(); 
 353                 PacketHeader
->Length 
-= sizeof(SideShow_PacketHeader_t
) + sizeof(GUID_t
); 
 355                 Endpoint_Discard_Stream(PacketHeader
->Length
); 
 358                 PacketHeader
->Type
.NAK 
= true; 
 362                 CurrApp
->ApplicationID 
= ApplicationID
; 
 363                 Endpoint_Read_Stream_LE(&CurrApp
->EndpointID
, sizeof(GUID_t
)); 
 364                 SideShow_Read_Unicode_String(&CurrApp
->ApplicationName
, sizeof(CurrApp
->ApplicationName
.UnicodeString
)); 
 365                 Endpoint_Read_Stream_LE(&CurrApp
->CachePolicy
, sizeof(uint32_t)); 
 366                 Endpoint_Read_Stream_LE(&CurrApp
->OnlineOnly
, sizeof(uint32_t)); 
 367                 SideShow_Discard_Byte_Stream(); 
 368                 SideShow_Discard_Byte_Stream(); 
 369                 SideShow_Discard_Byte_Stream(); 
 372                 CurrApp
->InUse 
= true; 
 373                 CurrApp
->HaveContent 
= false; 
 374                 CurrApp
->CurrentContentID 
= 1; 
 377         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 379         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 380         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 384 static void SideShow_DeleteApplication(SideShow_PacketHeader_t
* PacketHeader
) 
 386         GUID_t ApplicationGUID
; 
 388         Endpoint_Read_Stream_LE(&ApplicationGUID
, sizeof(GUID_t
));       
 391         SideShow_Application_t
* AppToDelete 
= SideShow_GetApplicationFromGUID(&ApplicationGUID
); 
 393         if (AppToDelete 
!= NULL
) 
 394           AppToDelete
->InUse 
= false; 
 396           PacketHeader
->Type
.NAK 
= true; 
 398         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 400         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 401         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 405 static void SideShow_DeleteAllApplications(SideShow_PacketHeader_t
* PacketHeader
) 
 409         for (uint8_t App 
= 0; App 
< MAX_APPLICATIONS
; App
++) 
 410           InstalledApplications
[App
].InUse 
= false; 
 412         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 413         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 417 static void SideShow_AddContent(SideShow_PacketHeader_t
* PacketHeader
) 
 419         GUID_t ApplicationID
; 
 421         SideShow_Application_t
* Application
; 
 423         Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
)); 
 424         Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
)); 
 426         Application 
= SideShow_GetApplicationFromGUID(&ApplicationID
); 
 428         if (Application 
== NULL
) 
 430                 SideShow_Discard_Byte_Stream(); 
 431                 PacketHeader
->Type
.NAK 
= true; 
 433         else if (!(SideShow_AddSimpleContent(PacketHeader
, Application
))) 
 435                 PacketHeader
->Type
.NAK 
= true; 
 440         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 442         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 443         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 447 static void SideShow_DeleteContent(SideShow_PacketHeader_t
* PacketHeader
) 
 449         GUID_t   ApplicationID
; 
 453         Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
)); 
 454         Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
)); 
 455         Endpoint_Read_Stream_LE(&ContentID
, sizeof(uint32_t)); 
 458         SideShow_Application_t
* Application 
= SideShow_GetApplicationFromGUID(&ApplicationID
); 
 460         if ((Application 
!= NULL
) && (Application
->CurrentContentID 
== ContentID
)) 
 461           Application
->HaveContent 
= false; 
 463           PacketHeader
->Type
.NAK 
= true; 
 465         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 467         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 468         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
)); 
 472 static void SideShow_DeleteAllContent(SideShow_PacketHeader_t
* PacketHeader
) 
 474         GUID_t ApplicationID
; 
 477         Endpoint_Read_Stream_LE(&ApplicationID
, sizeof(GUID_t
)); 
 478         Endpoint_Read_Stream_LE(&EndpointID
, sizeof(GUID_t
)); 
 481         SideShow_Application_t
* Application 
= SideShow_GetApplicationFromGUID(&ApplicationID
); 
 483         if (Application 
!= NULL
) 
 484           Application
->HaveContent 
= false; 
 486           PacketHeader
->Type
.NAK 
= true;           
 488         PacketHeader
->Length 
= sizeof(SideShow_PacketHeader_t
); 
 490         Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM
); 
 491         Endpoint_Write_Stream_LE(PacketHeader
, sizeof(SideShow_PacketHeader_t
));