/*
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 \n Cmd: %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 ( ) ;
}