diff -r 000000000000 -r 1e05558e2206 usbengines/usbremotepersonality/src/cremotepersonalityhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbengines/usbremotepersonality/src/cremotepersonalityhandler.cpp Thu Dec 17 09:14:30 2009 +0200 @@ -0,0 +1,507 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Handles Remote personalities change +* +*/ + + +#include +#include +#include +#include +#include +#include + +#include "cremotepersonalityhandler.h" +#include "csetpersonality.h" +#include "debug.h" + +const TUint KValueLoByte = 2; +const TUint KValueHiByte = 3; +const TUint KIndexLoByte = 4; +const TUint KIndexHiByte = 5; +const TUint KLengthLoByte = 6; +const TUint KLengthHiByte = 7; + +const TUint KOneByte = 8; // for shifting data to one byte + +const TUint KGetPersonalitiesHeaderLen = 4; +const TUint KItemsPerPersonality = 2; + +const TUint8 KStringDescriptorsBase = 0xED; // string descriptors will be written starting from this index, descendingly; 0xEE is used for OS string descriptor + +const TUint KAllPersonalitiesDescriptorType = 0x12; // All Personalities Descriptor type + +const TUint KSetupPacketLength = 8; // 8 bytes + +const TUint KS6032MajorNumber = 3; // 3.2 major number is 3 + +const TInt K32DevicePCSuite = 113; +const TInt K32DeviceMS = 114; +const TInt K32DevicePTP = 115; + +const TInt KHostPCSuite = 1; +const TInt KHostMS = 2; +const TInt KHostPTP = 3; + +// --------------------------------------------------------------------------- +// Decoding EP0 buffer +// --------------------------------------------------------------------------- +// +void TSetupPacket::Decode(const RBuf8& aSetupPacket) + { + + if (aSetupPacket.Length() < KSetupPacketLength) + { + iRequest = CRemotePersonalityHandler::EUnknown; + return; + } + + iType = aSetupPacket[0]; + iRequest = static_cast(aSetupPacket[1]); + iValue = static_cast(aSetupPacket[KValueLoByte] | + (aSetupPacket[KValueHiByte] << KOneByte) ); + iIndex = static_cast(aSetupPacket[KIndexLoByte] | + (aSetupPacket[KIndexHiByte] << KOneByte) ); + iLength = static_cast(aSetupPacket[KLengthLoByte] | + (aSetupPacket[KLengthHiByte] << KOneByte) ); + } + +// --------------------------------------------------------------------------- +// Two-phase construction +// --------------------------------------------------------------------------- +// +CRemotePersonalityHandler* CRemotePersonalityHandler::NewL() + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::NewL" ) ); + + CRemotePersonalityHandler* self = new (ELeave) CRemotePersonalityHandler(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// Default construction +// --------------------------------------------------------------------------- +// +CRemotePersonalityHandler::CRemotePersonalityHandler() : + iLastResult(EUndefinedError) + { + iSetupPacket.iRequest = CRemotePersonalityHandler::EUnknown; + } + +// --------------------------------------------------------------------------- +// Two-phase construction +// --------------------------------------------------------------------------- +// +void CRemotePersonalityHandler::ConstructL() + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::ConstructL" ) ); + iSetPersonalityHandler = CSetPersonality::NewL(*this); + + iMappingIsNeeded = IsMappingNeededL(); + } + +// --------------------------------------------------------------------------- +// Destruction +// --------------------------------------------------------------------------- +// +CRemotePersonalityHandler::~CRemotePersonalityHandler() + { + FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::~CRemotePersonalityHandler" ) ); + + delete iSetPersonalityHandler; + + iPersonalities.Close(); // T-classes' objects in RArray do not require to be "destroyed" + + } + +// --------------------------------------------------------------------------- +// SetPersonality request has been completed +// --------------------------------------------------------------------------- +// +void CRemotePersonalityHandler::SetPersonalityCallBack(TLastResult aResult) + { + + FTRACE(FPrint( + _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::SetPersonalityCallBack aResult = %d" ), aResult)); + + iLastResult = aResult; + iSetupPacket.iRequest = CRemotePersonalityHandler::EUnknown; + + } + +// --------------------------------------------------------------------------- +// Personality-related requests handler +// --------------------------------------------------------------------------- +// +TInt CRemotePersonalityHandler::Handle(const RBuf8& aSetupBuffer, RBuf8& aData) + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::Handle" ) ); + + TRAPD(err, DoHandleL(aSetupBuffer, aData)); + + return static_cast(err); + + } + +// --------------------------------------------------------------------------- +// Personality-related requests internal handler +// --------------------------------------------------------------------------- +// +void CRemotePersonalityHandler::DoHandleL(const RBuf8& aSetupBuffer, RBuf8& aData) + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::DoHandleL" ) ); + + iSetupPacket.Decode(aSetupBuffer); + + FTRACE(FPrint( + _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::DoHandleL: Request = %d" ), iSetupPacket.iRequest)); + + switch(iSetupPacket.iRequest) + { + + case EGetAllPersonalities : + { + iLastResult = EUndefinedError; // will be updated after completing the request + + GetPersonalitiesL(aData); + + iLastResult = ESuccess; //static_cast(err); + + break; + } + + case EGetLastResult : + { + GetLastResultL(aData); + break; + } + + case ESetPersonality : + { + + iLastResult = EUndefinedError; // will be updated after copmleting the request + + SetPersonalityL(); + + iLastResult = EDataTransferInProgress; + + break; + + } + + case EGetPersonalityDescriptor : + case EGetPersonality : + case EGetLockState : + case ESetLockState : + + default: + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::Handle ***Request Is Not Supported***" ) ); + + User::Leave(KErrNotSupported); + + } + } + + } + +// --------------------------------------------------------------------------- +// Set links to needed services +// --------------------------------------------------------------------------- +// +void CRemotePersonalityHandler::Initialize( RDevUsbcClient& aLdd, + RUsbWatcher& aUsbWatcher, + RUsb& aUsbManager) + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::Initialize" ) ); + + iUsbWatcher = &aUsbWatcher; + iUsbManager = &aUsbManager; + iLdd = &aLdd; + + iSetPersonalityHandler->SetUsbWatcher(iUsbWatcher); + + // Read personalities + TRAPD(err, ReadPersonalitiesL()); + + FTRACE(FPrint( + _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::Initialize: ReadPersonalities err = %d" ), err)); + + // Save personalities descriptions, to enable read of them by standard GetDescriptor request + TRAP(err, SavePersonalitiesStringsL()); + + FTRACE(FPrint( + _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::Initialize: SavePersString err = %d" ), err)); + + } + +// --------------------------------------------------------------------------- +// Process GetAllPersonalities request +// --------------------------------------------------------------------------- +// +void CRemotePersonalityHandler::GetPersonalitiesL(RBuf8& aPersonalities) + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::GetPersonalities" ) ); + + // check the request + if((iSetupPacket.iValue != 0) || (iSetupPacket.iIndex != 0)) + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\t**** CRemotePersonalityHandler::GetPersonalities SetupPacket has wrong data *****" ) ); + User::Leave(EInvalidRequest); + + } + + TInt8 responseLength(KGetPersonalitiesHeaderLen+iPersonalities.Count()*KItemsPerPersonality); // 4 mandatory bytes for header + 2 bytes per personality + + FTRACE(FPrint( + _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::GetPersonalities Response length is %d bytes" ), responseLength)); + + aPersonalities.Close(); + aPersonalities.Create(responseLength); + + // Panic on Append never can be rised in this method, due to aPersonalities length exactly equal the appending data length. + aPersonalities.Append(responseLength); + aPersonalities.Append(KAllPersonalitiesDescriptorType); // All Personalities Descriptor type + + TInt err(ESuccess); + TInt currentPersonalityId; + + err = iUsbManager->GetCurrentPersonalityId(currentPersonalityId); + if(ESuccess != err) + { + User::Leave(EUndefinedError); + } + + FTRACE(FPrint( + _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::GetPersonalities Current personality Id is %d" ), currentPersonalityId)); + + // in S60 3.2 or older, map some personality ids into newer set + if(iMappingIsNeeded) + { + currentPersonalityId = MapPersonalityIdFromDeviceToHostL(currentPersonalityId); + } + + aPersonalities.Append(static_cast(currentPersonalityId)); + aPersonalities.Append(static_cast(iPersonalities.Count())); + + TUint counter(KGetPersonalitiesHeaderLen); // counter for aPersonalities descriptor, 4 bytes already written + + for(TUint i(0); i < iPersonalities.Count(); ++i, counter = counter + KItemsPerPersonality) + { + + TPersonality personality; + + if(iMappingIsNeeded) + { + personality.iId = MapPersonalityIdFromDeviceToHostL(iPersonalities[i].iId); + } + else + { + personality.iId = iPersonalities[i].iId; + } + + aPersonalities.Append(static_cast(personality.iId)); + aPersonalities.Append(static_cast(iPersonalities[i].iIndex)); + + FTRACE(FPrint( + _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::GetPersonalities Added personality id %d Index %d" ), aPersonalities[counter], aPersonalities[counter + 1])); + + } + + } + +// --------------------------------------------------------------------------- +// Reads personalities +// --------------------------------------------------------------------------- +// +void CRemotePersonalityHandler::ReadPersonalitiesL() + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::ReadPersonalitiesL" ) ); + + RArray personalityIds; + CleanupClosePushL(personalityIds); + + User::LeaveIfError(iUsbManager->GetPersonalityIds(personalityIds)); + + FTRACE(FPrint( + _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::ReadPersonalities There are %d personalities supported" ), personalityIds.Count())); + + // save ids to iPersonalities + iPersonalities.Reset(); + TPersonality p; + + for(TUint i(0); i < personalityIds.Count(); ++i) + { + + p.iId = personalityIds[i]; + p.iIndex = KStringDescriptorsBase - i; + + // iPersonalities is a dynamic array, no error handling is needed on Append + iPersonalities.Append(p); + + FTRACE(FPrint( + _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::ReadPersonalities Personality id = %d Index = %d" ), iPersonalities[i].iId, iPersonalities[i].iIndex)); + + } + + CleanupStack::PopAndDestroy(&personalityIds); // personalityIds + + } + +// --------------------------------------------------------------------------- +// Saves personalities descriptions as standard usb string descriptors +// --------------------------------------------------------------------------- +// +void CRemotePersonalityHandler::SavePersonalitiesStringsL() + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::SavePersonalitiesStringsL" ) ); + + HBufC* description; // personality description + for(TUint i(0); iGetDescription(iPersonalities[i].iId, description)); + + FTRACE(FPrint( + _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::SavePersonalitiesStrings Personality Id = %d Description length = %d" ), iPersonalities[i].iId, description->Length())); + + // save string to repository + User::LeaveIfError(iLdd->SetStringDescriptor(iPersonalities[i].iIndex, *description)); + + FTRACE(FPrint( + _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::SavePersonalitiesStrings Personality description saved with index %d" ), iPersonalities[i].iIndex)); + + delete description; + description = 0; + } + + } + +// --------------------------------------------------------------------------- +// Process SetPersonality request +// --------------------------------------------------------------------------- +// +void CRemotePersonalityHandler::SetPersonalityL() + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::SetPersonality" ) ); + + // check the request + if((iSetupPacket.iLength != 0) || (iSetupPacket.iIndex != 0)) + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\t**** CRemotePersonalityHandler::SetPersonality SetupPacket has wrong data *****" ) ); + User::Leave(EInvalidRequest); + + } + + if(iMappingIsNeeded) + { + iSetupPacket.iValue = MapPersonalityIdFromHostToDeviceL(iSetupPacket.iValue); + } + + // due to watcher process SetPersonality somehow strange, here is check for valid id + for(TUint i(0); i < iPersonalities.Count(); ++i) + { + if(iSetupPacket.iValue == iPersonalities[i].iId) + { + // set personality + iSetPersonalityHandler->SetPersonality(iSetupPacket.iValue); + return; + } + } + + // did not find personality id in list of supported personalities + iLastResult = ENonExistingPersonality; + iSetupPacket.iRequest = CRemotePersonalityHandler::EUnknown; + User::Leave(ENonExistingPersonality); + + } + +// --------------------------------------------------------------------------- +// Process GetLastResult request +// --------------------------------------------------------------------------- +// +void CRemotePersonalityHandler::GetLastResultL(RBuf8& aLastResult) + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::GetLastResult" ) ); + + // check the request + if((iSetupPacket.iValue != 0) || (iSetupPacket.iIndex != 0)) + { + + FLOG( _L( "[USBREMOTEPERSONALITY]\t**** CRemotePersonalityHandler::GetLastResult SetupPacket has wrong data *****" ) ); + User::Leave(EInvalidRequest); + + } + + aLastResult.Close(); + aLastResult.Create(1); // Length of response to GetLastResult request is 1 byte always. + + // Panic on Append never can be rised here, due to aPersonalities length exactly equal the appending data length. + aLastResult.Append(static_cast(iLastResult)); + +} + +TBool CRemotePersonalityHandler::IsMappingNeededL() +{ + VersionInfo::TPlatformVersion platformVersion; + User::LeaveIfError( VersionInfo::GetVersion( platformVersion ) ); + + if(platformVersion.iMajorVersion > KS6032MajorNumber) return EFalse; + + return ETrue; +} + +TInt CRemotePersonalityHandler::MapPersonalityIdFromDeviceToHostL(TInt aPersonality) +{ + switch(aPersonality) + { + case K32DevicePCSuite: return KHostPCSuite; + case K32DeviceMS: return KHostMS; + case K32DevicePTP: return KHostPTP; + + default: return aPersonality; + } +} + +TInt CRemotePersonalityHandler::MapPersonalityIdFromHostToDeviceL(TInt aPersonality) +{ + switch(aPersonality) + { + case KHostPCSuite: return K32DevicePCSuite; + case KHostMS: return K32DeviceMS; + case KHostPTP: return K32DevicePTP; + + default: return aPersonality; + } + +} + +