diff -r 000000000000 -r d0791faffa3f mtpfws/mtpfw/dataproviders/devdp/src/cmtpdevicedatastore.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mtpfws/mtpfw/dataproviders/devdp/src/cmtpdevicedatastore.cpp Tue Feb 02 01:11:40 2010 +0200 @@ -0,0 +1,1214 @@ +// Copyright (c) 2006-2009 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: +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cmtpdataprovider.h" +#include "cmtpdataprovidercontroller.h" +#include "cmtpdevicedatastore.h" +#include "cmtpframeworkconfig.h" +#include "mmtpenumerationcallback.h" +#include "mtpdevdppanic.h" +#include "mtpdevicedpconst.h" + +// Class constants. +__FLOG_STMT(_LIT8(KComponent,"DeviceDataStore");) + +#ifdef __WINS__ +_LIT( KFileName, "c:\\private\\102827a2\\mtpdevice.ico"); +#else +_LIT( KFileName, "z:\\private\\102827a2\\mtpdevice.ico"); +#endif + + +// Device property datastore constants. +_LIT(KMTPNoBackupFolder, "nobackup\\"); +_LIT(KMTPDevicePropertyStoreFileName, "mtpdevicepropertystore.dat"); +_LIT(KMTPDevicePropertyStoreDrive, "c:"); +_LIT(KMTPVendorExtensionSetDelimiter, "; "); + +//Default Session Initiator Version Information +_LIT(KDefaultSessionInitiatorVersionInfo,"None"); +//Default Perceived DeviceType information +static const TUint32 DefaultPerceivedDeviceType = 0; + +/*In order to ensure a reasonable RunL() duration, 8 dps at maximum are + queried in one RunL() invocation. +*/ +static const TUint KExtensionSetIterationRunLength = 8; + +// The maximum number of extensions each dp support. +static const TUint KExtensionSetGranularity = 4; + +//#define for PERCIVED_DEVICETYPE +static const TUint KPercivedDeviceType = 3; +//maximum length for date time string +static const TUint KMaxDateTimeLength = 28; +//minimum length for date time string +static const TUint KMinDateTimeLength = 15; +//position of date and time seperator 'T' +static const TUint KPosDelemT = 8; +//buffer size for reading iconfile +static const TUint KBufferSize = 1024; + +//enum for time zone +enum TDevDPTypeTimeOffset + { + EDEVDPTypeZero = 0, + EDEVDPTypeMinus , + EDEVDPTypePlus, + EDEVDPTypeNotDefined, + }; + + +/** +MTP device information data store factory method. +@return A pointer to an MTP device information data store. Ownership IS +transfered. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +CMTPDeviceDataStore* CMTPDeviceDataStore::NewL() + { + CMTPDeviceDataStore* self = new (ELeave) CMTPDeviceDataStore(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** +Destructor. +*/ +CMTPDeviceDataStore::~CMTPDeviceDataStore() + { + __FLOG(_L8("~CMTPDeviceDataStore - Entry")); + Cancel(); + delete iDeviceFriendlyNameDefault; + delete iSyncPartnerNameDefault; + delete iDeviceFriendlyName; + delete iSynchronisationPartner; + delete iTelephony; + delete iSessionInitiatorVersionInfo; + delete iDeviceIcon; + delete iSupportedDevProArray; + delete iDateTime; + iDeviceVersion.Close(); + iSerialNumber.Close(); + iSingletons.Close(); + iMTPExtensions.Close(); + __FLOG(_L8("~CMTPDeviceDataStore - Exit")); + __FLOG_CLOSE; + } + +/** +Check to see if a request such as BatteryLevel is currently +pending for processing. If so it's not advisable to make another +request. + +@return ETrue if a request is pending EFalse otherwise. +*/ + +TBool CMTPDeviceDataStore::RequestPending() const + { + return IsActive(); + } + +void CMTPDeviceDataStore::BatteryLevelL(TRequestStatus& aStatus, TUint& aBatteryLevel) + { + __FLOG(_L8("BatteryLevel - Entry")); + + if (RequestPending()) + { + // We are already reading battery level + // leave so we don't set ourselves active twice + User::Leave(KErrInUse); + } + + iPendingStatus = &aStatus; + SetRequestPending(*iPendingStatus); + + if (iTelephony) + { + iPendingBatteryLevel = &aBatteryLevel; + iTelephony->GetBatteryInfo(iStatus, iBatteryInfoV1Pckg); + SetState(EEnumeratingBatteryLevel); + SetActive(); + } + else + { + aBatteryLevel = KMTPDefaultBatteryLevel; + SetRequestComplete(*iPendingStatus, KErrNone); + } + __FLOG(_L8("BatteryLevel - Exit")); + } + +/** +Provides the MTP device friendly name. +@return The MTP device friendly name. +*/ +const TDesC& CMTPDeviceDataStore::DeviceFriendlyName() const + { + __FLOG(_L8("DeviceFriendlyName - Entry")); + __FLOG(_L8("DeviceFriendlyName - Exit")); + return iDeviceFriendlyName->StringChars(); + } + +/** +Provides the default MTP device friendly name. +@return The default MTP device friendly name. +*/ +const TDesC& CMTPDeviceDataStore::DeviceFriendlyNameDefault() const + { + __FLOG(_L8("DeviceFriendlyNameDefault - Entry")); + __FLOG(_L8("DeviceFriendlyNameDefault - Exit")); + return *iDeviceFriendlyNameDefault; + } + +/** +Provides the device firmware version identifier +@return The device firmware version identifier . +*/ +const TDesC& CMTPDeviceDataStore::DeviceVersion() const + { + __FLOG(_L8("DeviceVersion - Entry")); + __FLOG(_L8("DeviceVersion - Exit")); + return iDeviceVersion; + } + +/** +Provides the device manufacturer name. +@return The device manufacturer name. +*/ +const TDesC& CMTPDeviceDataStore::Manufacturer() const + { + __FLOG(_L8("Manufacturer - Entry")); + __ASSERT_DEBUG(Enumerated(), Panic(EMTPDevDpInvalidState)); + __FLOG(_L8("Manufacturer - Exit")); + return iPhoneIdV1.iManufacturer; + } + +/** +Provides the device model identifier. +@return The device model identifier. +*/ +const TDesC& CMTPDeviceDataStore::Model() const + { + __FLOG(_L8("Model - Entry")); + __ASSERT_DEBUG(Enumerated(), Panic(EMTPDevDpInvalidState)); + __FLOG(_L8("Model - Exit")); + return iPhoneIdV1.iModel; + } + +/** +Provides the MTP Vendor Extension string. +@return The MTP Vendor Extension string. +*/ +const TDesC& CMTPDeviceDataStore::MTPExtensions() const + { + __FLOG(_L8("MTPExtensions - Entry")); + __FLOG(_L8("MTPExtensions - Exit")); + return iMTPExtensions; + } + +/** +Provides the device serial number. +@return The device serial number. +*/ +const TDesC& CMTPDeviceDataStore::SerialNumber() const + { + __FLOG(_L8("SerialNumber - Entry")); + __ASSERT_DEBUG(Enumerated(), Panic(EMTPDevDpInvalidState)); + __FLOG(_L8("SerialNumber - Exit")); + return iPhoneIdV1.iSerialNumber; + } + +/** +Provides the MTP synchronisation partner name. +@return The MTP synchronisation partner name. +*/ +const TDesC& CMTPDeviceDataStore::SynchronisationPartner() const + { + __FLOG(_L8("SynchronisationPartner - Entry")); + __FLOG(_L8("SynchronisationPartner - Exit")); + return iSynchronisationPartner->StringChars(); + } + +/** +Provides the default MTP synchronisation partner name. +@return The default MTP synchronisation partner name. +*/ +const TDesC& CMTPDeviceDataStore::SynchronisationPartnerDefault() const + { + __FLOG(_L8("SynchronisationPartnerDefault - Entry")); + __FLOG(_L8("SynchronisationPartnerDefault - Exit")); + return *iSyncPartnerNameDefault; + } + +/** +Sets the MTP device friendly name. +@param aName The new MTP device friendly name. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPDeviceDataStore::SetDeviceFriendlyNameL(const TDesC& aName) + { + __FLOG(_L8("SetDeviceFriendlyNameL - Entry")); + iDeviceFriendlyName->SetL(aName); + StoreL(); + __FLOG(_L8("SetDeviceFriendlyNameL - Exit")); + } + +/** +Sets the synchronisation partner name. +@param aName The new MTP synchronisation partner name. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPDeviceDataStore::SetSynchronisationPartnerL(const TDesC& aName) + { + __FLOG(_L8("SetSynchronisationPartnerL - Entry")); + iSynchronisationPartner->SetL(aName); + StoreL(); + __FLOG(_L8("SetSynchronisationPartnerL - Exit")); + } + +/** +Initiates the MTP device data provider's device information data store +enumeration sequence. The sequence is concluded when ObjectEnumerationCompleteL +is signalled to the MTP data provider framework layer. +@param aStorageId The MTP StorageId to be enumerated. +@param aCallback Callback to be called when enumeration completes. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPDeviceDataStore::StartEnumerationL(TUint32 aStorageId, MMTPEnumerationCallback& aCallback) + { + __FLOG(_L8("StartEnumerationL - Entry")); + if (State() != EUndefined) + { + aCallback.NotifyEnumerationCompleteL(aStorageId, KErrNone); + } + else + { + iStorageId = aStorageId; + iCallback = &aCallback; + Schedule(EEnumeratingDevicePropertyStore); + } + __FLOG(_L8("StartEnumerationL - Exit")); + } + +void CMTPDeviceDataStore::DoCancel() + { + __FLOG(_L8("DoCancel - Entry")); + if (iTelephony) + { + switch (State()) + { + case EEnumeratingPhoneId: + iTelephony->CancelAsync(CTelephony::EGetPhoneIdCancel); + break; + + case EEnumeratingBatteryLevel: + iTelephony->CancelAsync(CTelephony::EGetBatteryInfoCancel); + break; + + default: + // Nothing to do. + break; + } + } + __FLOG(_L8("DoCancel - Exit")); + } + +/** +Handles leaves occurring in RunL. +@param aError leave error code +@return KErrNone +*/ +TInt CMTPDeviceDataStore::RunError(TInt aError) + { + __FLOG(_L8("RunError - Entry")); + __FLOG_VA((_L8("Error = %d, State = %d"), aError, State())); + aError = aError; // suppress compiler warning + + switch (State()) + { + case EEnumeratingDevicePropertyStore: + // Error restoring device properties; use defaults. + Schedule(EEnumeratingDeviceVersion); + break; + + case EEnumeratingDeviceVersion: + // Error enumerating software build information; use default. + Schedule(EEnumeratingPhoneId); + break; + + case EEnumeratingPhoneId: + // Error enumerating telephony device ID information; use defaults. + Schedule(EEnumeratingVendorExtensions); + break; + + case EEnumeratingVendorExtensions: + Schedule(EEnumerated); + break; + + case EEnumeratingBatteryLevel: + // This case will never occur + case EUndefined: + default: + __DEBUG_ONLY(Panic(EMTPDevDpInvalidState)); + break; + } + + __FLOG(_L8("RunError - Exit")); + return KErrNone; + } + +void CMTPDeviceDataStore::RunL() + { + __FLOG(_L8("RunL - Entry")); + switch (State()) + { + case EEnumeratingDevicePropertyStore: + RestoreL(); + Schedule(EEnumeratingDeviceVersion); + break; + + case EEnumeratingDeviceVersion: + { + TInt buildNo(0); + User::LeaveIfError(HAL::Get(HALData::EManufacturerSoftwareBuild, buildNo)); + __FLOG_VA((_L8("EManufacturerSoftwareBuild = %d "), buildNo)); + iDeviceVersion.Format(_L("%d"), buildNo); + Schedule(EEnumeratingPhoneId); + } + break; + + case EEnumeratingPhoneId: + if (!iTelephony) + { + iTelephony = CTelephony::NewL(); + iTelephony->GetPhoneId(iStatus, iPhoneIdV1Pckg); + SetActive(); + } + else + { + StoreFormattedSerialNumber(iPhoneIdV1.iSerialNumber); + Schedule(EEnumeratingVendorExtensions); + } + break; + + case EEnumeratingVendorExtensions: + { + TBool isCompleted = EFalse; + AppendMTPExtensionSetsL(isCompleted); + if (isCompleted) + { + Schedule(EEnumerated); + } + else + { + Schedule(EEnumeratingVendorExtensions); + } + } + break; + + case EEnumeratingBatteryLevel: + *iPendingBatteryLevel = iBatteryInfoV1.iChargeLevel; + SetRequestComplete(*iPendingStatus, KErrNone); + SetState(EEnumerated); + break; + + case EEnumerated: + if (iCallback) + { + iCallback->NotifyEnumerationCompleteL(iStorageId, KErrNone); + iCallback = NULL; + iStorageId = KMTPNotSpecified32; + } + break; + +case EEnumeratedBatteryLevel : + *iPendingBatteryLevel = iBatteryInfoV1.iChargeLevel; + SetRequestComplete(*iPendingStatus, KErrNone); + SetState(EEnumerated); + break; + + case EUndefined: + default: + __DEBUG_ONLY(Panic(EMTPDevDpInvalidState)); + break; + } + __FLOG(_L8("RunL - Exit")); + } + +/** +Constructor. +@param aConnectionMgr The MTP connection manager interface. +*/ +CMTPDeviceDataStore::CMTPDeviceDataStore() : + CActive(EPriorityStandard), + iBatteryInfoV1Pckg(iBatteryInfoV1), + iPhoneIdV1Pckg(iPhoneIdV1) + { + CActiveScheduler::Add(this); + } + +/** +Second phase constructor. +*/ +void CMTPDeviceDataStore::ConstructL() + { + __FLOG_OPEN(KMTPSubsystem, KComponent); + __FLOG(_L8("ConstructL - Entry")); + iSingletons.OpenL(); + + /* + Set the default values. + + 1. Device friendly name. + */ + iDeviceFriendlyNameDefault = iSingletons.FrameworkConfig().ValueL(CMTPFrameworkConfig::EDeviceFriendlyName); + iDeviceFriendlyName = CMTPTypeString::NewL(*iDeviceFriendlyNameDefault); + + // 2. Synchronization partner name. + iSyncPartnerNameDefault = iSingletons.FrameworkConfig().ValueL(CMTPFrameworkConfig::ESynchronizationPartnerName); + iSynchronisationPartner = CMTPTypeString::NewL(*iSyncPartnerNameDefault); + + // 3. Device Version. + iDeviceVersion.CreateL(KMTPDefaultDeviceVersion); + + // 4. Manufacturer. + iPhoneIdV1.iManufacturer = KMTPDefaultManufacturer; + + // 5. Model. + iPhoneIdV1.iModel = KMTPDefaultModel; + + // 6. Serial Number. + StoreFormattedSerialNumber(KMTPDefaultSerialNumber); + + // 7. Vendor Extensions + iMTPExtensions.CreateL(KMTPMaxStringCharactersLength); + + // 8. Session Initiator version Info + iSessionInitiatorVersionInfo = CMTPTypeString::NewL(KDefaultSessionInitiatorVersionInfo); + + //9. Percived device type property. + //value for mobile handset is 0x00000003 + iPerceivedDeviceType.Set(KPercivedDeviceType); + + //10 date time property. no need to creat the string right now, create the + //date time string whe it is requested. + TBuf<30> dateTimeString; + iDateTime = CMTPTypeString::NewL(dateTimeString); + + //11 Device Icon property, Load the icon into Auint Atrray + LoadDeviceIconL(); + + __FLOG(_L8("ConstructL - Exit")); + } + +/** +Indicates if the device information data store is in the EEnumerated state. +@return ETrue if the device data store state is enumerated, otherwiese EFalse. +*/ +TBool CMTPDeviceDataStore::Enumerated() const + { + __FLOG(_L8("Enumerated - Entry")); + TInt32 state(State()); + __FLOG(_L8("Enumerated - Exit")); + return (state & EEnumerated); + } + +/** +Externalizes device properties to the device property store. +@param aWriteStream the stream to externalize the device properties +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPDeviceDataStore::ExternalizeL(RWriteStream& aWriteStream) const + { + __FLOG(_L8("ExternalizeL - Entry")); + aWriteStream.WriteInt32L(KMTPDevicePropertyStoreVersion); + aWriteStream << DeviceFriendlyName(); + aWriteStream << SynchronisationPartner(); + __FLOG(_L8("ExternalizeL - Exit")); + } + +/** +Internalises device properties from the device property store. +@param aReadStream The device property store input data stream. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPDeviceDataStore::InternalizeL(RReadStream& aReadStream) + { + __FLOG(_L8("InternalizeL - Entry")); + RBuf buf; + buf.CleanupClosePushL(); + + /* + Read the device property store version. This is present for future + expansion but is currently ignored. + */ + TInt32 version(aReadStream.ReadInt32L()); + + // Read the device friendly name. + buf.CreateL(aReadStream, KMTPMaxStringCharactersLength); + iDeviceFriendlyName->SetL(buf); + buf.Close(); + + // Read the synchronisation partner name. + buf.CreateL(aReadStream, KMTPMaxStringCharactersLength); + iSynchronisationPartner->SetL(buf); + buf.Close(); + + CleanupStack::Pop(); //buf + __FLOG(_L8("InternalizeL - Exit")); + } + +/** +Provides the full pathname of the device property store. +@return The full pathname of the device property store. +*/ +const TDesC& CMTPDeviceDataStore::PropertyStoreName() + { + __FLOG(_L8("PropertyStoreName - Entry")); + if (iPropertyStoreName.Length() == 0) + { + iSingletons.Fs().PrivatePath(iPropertyStoreName); + iPropertyStoreName.Insert(0, KMTPDevicePropertyStoreDrive); + iPropertyStoreName.Append(KMTPNoBackupFolder); + iPropertyStoreName.Append(KMTPDevicePropertyStoreFileName); + } + + __FLOG(_L8("PropertyStoreName - Exit")); + return iPropertyStoreName; + } + +/** +Query all dps for the MTP Vendor extensions set. +@return ETrue if finished querying all the dps, otherwise EFalse. +*/ +void CMTPDeviceDataStore::AppendMTPExtensionSetsL(TBool& aCompleted) + { + __FLOG(_L8("AppendMTPExtensionSetsL - Entry")); + CMTPDataProviderController& dps(iSingletons.DpController()); + const TInt count = Min(iCurrentDpIndex + KExtensionSetIterationRunLength, dps.Count()); + aCompleted = EFalse; + CDesCArraySeg* extensions = new (ELeave) CDesCArraySeg(KExtensionSetGranularity); + CleanupStack::PushL(extensions); + while (!aCompleted && (iCurrentDpIndex < count)) + { + CMTPDataProvider& dp(dps.DataProviderByIndexL(iCurrentDpIndex)); + dp.Plugin().SupportedL(EVendorExtensionSets, *extensions); + //append the mtp extension string. + TInt n = extensions->Count(); + TInt len = iMTPExtensions.Length(); + for (TInt i = 0; i < n; i++) + { + len += (*extensions)[i].Length() + KMTPVendorExtensionSetDelimiter().Length(); + if (len > KMTPMaxStringCharactersLength) + { + __FLOG(_L8("MTP Extensions set exceeded the maximum MTP String length")); + // End querying dps when the extension set exceeds the maximum mtp string length. + aCompleted = ETrue; + break; + } + else + { + if ( KErrNotFound == iMTPExtensions.Find((*extensions)[i]) ) + { + iMTPExtensions.Append((*extensions)[i]); + iMTPExtensions.Append(KMTPVendorExtensionSetDelimiter); + } + } + } + extensions->Reset(); + iCurrentDpIndex++; + } + CleanupStack::PopAndDestroy(extensions); + + if(!aCompleted && iCurrentDpIndex >= dps.Count()) + { + aCompleted = ETrue; + } + + __FLOG(_L8("AppendMTPExtensionSetsL - Exit")); + } + +/** +Loads device properties from the device property store. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPDeviceDataStore::RestoreL() + { + __FLOG(_L8("RestoreL - Entry")); + RFs& fs(iSingletons.Fs()); + if(BaflUtils::FileExists(fs, PropertyStoreName())) + { + CFileStore* store(CDirectFileStore::OpenLC(fs, PropertyStoreName(), EFileRead)); + RStoreReadStream instream; + instream.OpenLC(*store, store->Root()); + InternalizeL(instream); + CleanupStack::PopAndDestroy(2, store); // instream, store + } + __FLOG(_L8("RestoreL - Exit")); + } + +/** +Schedules the device information data store to transition to the specified state. +@param aState The new data stream state. +*/ +void CMTPDeviceDataStore::Schedule(TInt32 aState) + { + __FLOG(_L8("Schedule - Entry")); + SetState(aState); + SetRequestPending(iStatus); + SetActive(); + SetRequestComplete(iStatus,KErrNone); + __FLOG(_L8("Schedule - Exit")); + } + +/** +Completes the supplied asynchronous request completion status. +*/ +void CMTPDeviceDataStore::SetRequestComplete(TRequestStatus& aRequest, TUint aErr) + { + __FLOG(_L8("CompleteRequest - Entry")); + TRequestStatus* status(&aRequest); + User::RequestComplete(status, aErr); + __FLOG(_L8("CompleteRequest - Exit")); + } + + +/** +Initialises the supplied asynchronous request completion status. +*/ +void CMTPDeviceDataStore::SetRequestPending(TRequestStatus& aRequest) + { + __FLOG(_L8("SetRequestPending - Entry")); + aRequest = KRequestPending; + __FLOG(_L8("SetRequestPending - Exit")); + } + +/** +Sets the device information data store state variable. +@param aState The new data stream state. +*/ +void CMTPDeviceDataStore::SetState(TInt32 aState) + { + __FLOG(_L8("SetState - Entry")); + iState = ((EEnumerated & iState) | aState); + __FLOG_VA((_L8("State set to 0x%08X"), iState)); + __FLOG(_L8("SetState - Exit")); + } + +/** +Provides the device information data store state variable value. +@return The device information data store state variable value. +*/ +TInt32 CMTPDeviceDataStore::State() const + { + __FLOG(_L8("State - Entry")); + __FLOG_VA((_L8("State = 0x%08X"), iState)); + __FLOG(_L8("State - Exit")); + return iState; + } + +/** +Stores device properties in the device property store. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPDeviceDataStore::StoreL() + { + __FLOG(_L8("StoreL - Entry")); + CFileStore* store(CDirectFileStore::ReplaceLC(iSingletons.Fs(), PropertyStoreName(), EFileWrite)); + store->SetTypeL(KDirectFileStoreLayoutUid); + RStoreWriteStream outstream; + TStreamId id = outstream.CreateLC(*store); + ExternalizeL(outstream); + outstream.CommitL(); + CleanupStack::PopAndDestroy(&outstream); + store->SetRootL(id); + store->CommitL(); + CleanupStack::PopAndDestroy(store); + __FLOG(_L8("StoreL - Exit")); + } + +/** +Formats the specified serial number as a valid MTP Serial Number string. The +MTP specification recommends that the serial number always be represented as +exactly 32 characters, with leading zeros as required. +*/ +void CMTPDeviceDataStore::StoreFormattedSerialNumber(const TDesC& aSerialNo) + { + __FLOG(_L8("FormatSerialNumber - Entry")); + TBuf formatted; + if (aSerialNo.Length() < KMTPSerialNumberLength) + { + formatted = aSerialNo; + } + else + { + /* + Supplied serial number data is greater than or equal to the required + 32 characters. Extract the least significant 32 characters. + */ + formatted = aSerialNo.Right(KMTPSerialNumberLength); + } + + // Store the formatted serial number. + iPhoneIdV1.iSerialNumber = formatted; + + __FLOG(_L8("FormatSerialNumber - Exit")); + } + +/** +* Get method for Session initiator version info(0xD406). +* +* @return TDesC& : session initiator version info +*/ +const TDesC& CMTPDeviceDataStore::SessionInitiatorVersionInfo() const + { + __FLOG(_L8("SessionInitiatorVersionInfo - Entry:Exit")); + return iSessionInitiatorVersionInfo->StringChars(); + } + +/** +* Get method for Session initiator version info Default value. +* +* @return TDesC& : session initiator version info default. +*/ +const TDesC& CMTPDeviceDataStore::SessionInitiatorVersionInfoDefault() const + { + __FLOG(_L8("SessionInitiatorVersionInfoDefault - Entry:Exit")); + return KDefaultSessionInitiatorVersionInfo; + } + +/** +* Set method for Session initiator version info(0xD406). +* +* @Param TDesC& : session initiator version info from the initiator +*/ +void CMTPDeviceDataStore::SetSessionInitiatorVersionInfoL(const TDesC& aVerInfo) + { + __FLOG(_L8("SetDeviceFriendlyNameL - Entry")); + iSessionInitiatorVersionInfo->SetL(aVerInfo); + StoreL(); + __FLOG(_L8("SetDeviceFriendlyNameL - Exit")); + } + +/** +* Get method for PerceivedDeviceTypeDefault(0x00000000 Generic). +* +* @return TUint32: return value for PerceivedDeviceTypeDefault +*/ +TUint32 CMTPDeviceDataStore::PerceivedDeviceTypeDefault() const + { + __FLOG(_L8("SessionInitiatorVersionInfoDefault - Entry:Exit")); + return DefaultPerceivedDeviceType; + } + +/** +* Get method for PerceivedDeviceType(0x00000003 Mobile Handset). +* possible values for PerceivedDeviceType are +* 0x00000000 Generic. +* 0x00000001 Still Image/Video Camera. +* 0x00000002 Media (Audio/Video) Player. +* 0x00000003 Mobile Handset. +* 0x00000004 Digital Video Camera. +* 0x00000005 Personal Information Manager/Personal Digital Assistant. +* 0x00000006 Audio Recorder. +* @return TUint32: return value for PerceivedDeviceType. +*/ +TUint32 CMTPDeviceDataStore::PerceivedDeviceType() const + { + __FLOG(_L8("SessionInitiatorVersionInfo - Entry:Exit")); + return iPerceivedDeviceType.Value(); + } + +/** +* Get method for Date time. +* @return TDesC: const date time string YYYYMMDDThhmmss.s +**/ +const TDesC& CMTPDeviceDataStore::DateTimeL() + { + __FLOG(_L8("DateTime - Entry:Exit")); + TBuf<30> dateTimeString; + DateTimeToStringL(dateTimeString); + iDateTime->SetL(dateTimeString); + __FLOG(_L8("DateTime -Exit")); + return iDateTime->StringChars(); + } + +/** +* This method to set the date time on MTP device +* incoming date time string will be having a format YYYYMMDDThhmmss.s +* it need to modify accordingly to set the time. +* +*@Param aDateTime : Date time string. +* Some modification need to be done on this method(minor change). +**/ +TInt CMTPDeviceDataStore::SetDateTimeL(const TDesC& aDateTime ) + { + __FLOG(_L8("SetDateTime - Entry")); + TBuf<30> dateTime; + TInt offset = User::UTCOffset().Int(); + //get actul time to set, offset + ,- or UTC and offset from UTC in seconds. + TInt errorCode = ValidateString(aDateTime, dateTime, offset); + if(KErrNone == errorCode) + { + StringToDateTime(dateTime); + iDateTime->SetL(dateTime); + StoreL(); + //now set the system time by calling user SetUTCTime + TTime tt; + errorCode = tt.Set(dateTime); + // tt is currently in an unknown time zone -- now adjust to UTC. + if(KErrNone == errorCode) + { + //if date time is YYYYMMDDTHHMMSS.S or append with 'Z' then + TTimeIntervalSeconds utcOffset(offset); + // Subtract seconds ahead, to get to UTC timezone + tt -= utcOffset; + __FLOG(_L8("Setting UTC time")); + errorCode = User::SetUTCTime(tt); + __FLOG_STMT(TBuf<30> readable;) + __FLOG_STMT(tt.FormatL(readable, _L("%F%Y%M%DT%H%T%SZ"));) + __FLOG_1(_L("Time now: %S"), &readable); + } + } + __FLOG_1(_L8("SetDateTime - Exit %d"), errorCode); + + return errorCode; + } + + +/** +*This method will create a string that is compatible for MTP datet time . +* Format("YYYYMMDDThhmmss.s") microsecond part is not implemented +* yet but that can be done easly. one more function can be implemented +* for appending 0s +**/ +void CMTPDeviceDataStore::DateTimeToStringL(TDes& aDateTime) + { + __FLOG(_L8("DateTimeToString - Entry")); + //get home time and convert it to string + TTime tt; + tt.UniversalTime(); + _LIT(KFormat,"%F%Y%M%DT%H%T%SZ"); + tt.FormatL(aDateTime, KFormat); + __FLOG(_L8("DateTimeToString - Exit")); + } + +/** +*This method will convert MTP date time format ("YYYYMMDDThhmmss.s")to +*TTime time format YYYYMMDD:hhmmss.ssssss. Right now microsecond part is +* not implemented. +**/ +void CMTPDeviceDataStore::StringToDateTime(TDes& aDateTime ) + { + __FLOG(_L8("StringToDateTime - Entry")); + TBuf<30> newTime; + _LIT(KDlemMTP,"T"); + _LIT(KDlemTTime,":"); + TInt pos = aDateTime.Find(KDlemMTP) ; + if((KErrNotFound != pos) && (KPosDelemT == pos)) + { + const TInt KYearDigits = 4; + const TInt KMonthDigits = 2; + const TInt KDayDigits = 2; + + TInt month = 0; + TLex monthLex(aDateTime.Mid(KYearDigits, KMonthDigits)); + //coverity[unchecked_value] + monthLex.Val(month); + + TInt day = 0; + TLex dayLex(aDateTime.Mid(KYearDigits+KMonthDigits, KDayDigits)); + //coverity[unchecked_value] + dayLex.Val(day); + + _LIT(KDateFormat, "%S%02d%02d"); + TPtrC year(aDateTime.Left(KYearDigits)); + newTime.AppendFormat(KDateFormat, &year, month - 1, day - 1); + + newTime.Append(KDlemTTime); + newTime.Append(aDateTime.Mid(pos + 1)); + aDateTime.Copy(newTime); + } + else + { + _LIT(KPanic, "date time "); + User::Panic(KPanic, 3); + } + __FLOG_1(_L("Processed DateTime: %S"), &aDateTime); + __FLOG(_L8("StringToDateTime - Exit")); + } + +/** +*This method to validate the incoming date time string +*Any incoming string from intiator supposed to be either YYYYMMDDThhmmss.s +* or YYYYMMDDT(Z/+/-)hhmmss.s form +*1.validation is done based on minimum length of the string +*2.based on the carector and its position. +*char allowded are 'Z', 'T', '.','+' and '-' +*/ +TInt CMTPDeviceDataStore::ValidateString(const TDesC& aDateTimeStr, TDes& aDateTime, TInt &aOffsetVal) + { + __FLOG(_L8("ValidateString - Entry")); + __FLOG_1(_L("Supplied date: %S"), &aDateTimeStr); + _LIT(KDlemMTP,"T"); + TInt errCode = KErrNone; + TInt pos = aDateTimeStr.Find(KDlemMTP); + TInt nullCharPos = aDateTimeStr.Locate('\0'); + if ( KErrNotFound != nullCharPos ) + { + aDateTime.Copy( aDateTimeStr.Left(nullCharPos)); + } + else + { + aDateTime.Copy(aDateTimeStr); + } + + //1.validation is done based on minimum length of the string and pos + if((KErrNotFound == pos ) || (aDateTimeStr.Length() > KMaxDateTimeLength) || + (aDateTimeStr.Length() < KMinDateTimeLength) || pos != KPosDelemT) + { + __FLOG_2(_L8("Invalid. pos: %d, len: %d"), pos, aDateTimeStr.Length()); + errCode = KErrGeneral; + } + else + { + //validation based on the carector and its position. + for(TInt i =0 ; i< aDateTimeStr.Length(); i ++) + { + //any other string other than 'Z', 'T', '.','+' and '-' or positon is wrong return + if(('0' > aDateTimeStr[i]) || ('9' < aDateTimeStr[i])) + { + switch(aDateTimeStr[i]) + { + case 'T': + case 't': + if(i != pos) + { + __FLOG_1(_L8("Invalid. 'T' encountered at offset %d"), i); + //error char at rong position + errCode = KErrGeneral; + }//else fine + break; + case 'Z': + case 'z': + aOffsetVal = 0; + aDateTime.Copy(aDateTimeStr.Mid(0, i)); + //error char at wrong position + if(i 23) || (minuteOffset > 59)) + { + errCode = KErrGeneral; + __FLOG_2(_L8("Invalid. Hour(%d) or Minute(%d) offset out of range."), hourOffset, minuteOffset); + break; + } + + + aOffsetVal = (hourOffset * KSecondsPerHour) + (minuteOffset * KSecondsPerMinute); + if ('-' == aDateTimeStr[i]) + { + aOffsetVal = -aOffsetVal; + } + __FLOG_1(_L8("Info: Timezone offset %d seconds"), aOffsetVal); + } + + break; + case '.': + case '\0': + if(i < KMinDateTimeLength) + { + //error char at wrong position + errCode = KErrGeneral; + __FLOG_1(_L8("Invalid. '.' or NULL at offset %d"), i); + } + break; + default : + //wrong char + errCode = KErrGeneral; + __FLOG_2(_L8("Invalid. Character %04x at offset %d"), aDateTimeStr[i], i); + break; + } + } + if(KErrNone != errCode) + { + __FLOG_2(_L("Processed date: %S, TimeZone: %ds ahead"), &aDateTimeStr, aOffsetVal); + __FLOG_1(_L8("ValidateString - Exit %d"), errCode); + return errCode; + } + } + } + __FLOG_2(_L("Processed date: %S, TimeZone: %ds ahead"), &aDateTimeStr, aOffsetVal); + __FLOG_1(_L8("ValidateString - Exit %d"), errCode); + return errCode; + } + +/** +*This method is to load/Store the deviceIcon to the CMTPTypeArray iDeviceIcon +* some improvment is possible here. +*/ +void CMTPDeviceDataStore::LoadDeviceIconL() + { + RFile rFile; + RFs rFs; + //device icon should be stored in an array of type uint8 + iDeviceIcon = CMTPTypeArray::NewL(EMTPTypeAUINT8); + TInt error = rFs.Connect(); + if(error == KErrNone ) + { + error = rFile.Open(rFs, KFileName, EFileRead); + //for buffer size we could have used VolumeIOParam() + //metho to get optimal cluseter size, it could be(1, 2, 4 kb) + //but it is not make much difference in performance if we use 1kb buffer + TBuf8 buffer; + if(error == KErrNone ) + { + TUint length =0; + while(ETrue) + { + error = rFile.Read(buffer, KBufferSize); + length = buffer.Length(); + if((0 != length) && ( KErrNone == error)) + { + for(TUint index = 0; index < length; index++ ) + { + iDeviceIcon->AppendUintL(buffer[index]); + } + } + else + { + break; + } + } + } + rFile.Close(); + } + rFs.Close(); + } + +/** +*Get method fro DeviceIcon, return value is a type unint array. +* +*@return iDeviceIcon: array of uint +*/ +const CMTPTypeArray& CMTPDeviceDataStore::DeviceIcon() + { + return *iDeviceIcon; + } + +/** +*This method is to store the supported device properties +*/ +void CMTPDeviceDataStore::SetSupportedDevicePropertiesL(RArray& aSupportedDevProps) + { + CheckDeviceIconProperties(aSupportedDevProps); + delete iSupportedDevProArray; + iSupportedDevProArray = NULL; + iSupportedDevProArray = CMTPTypeArray::NewL(EMTPTypeAUINT16, aSupportedDevProps); + } +/** +*This method is to store the devicedp reference +*/ +void CMTPDeviceDataStore::SetExtnDevicePropDp(MExtnDevicePropDp* aExtnDevicePropDp) + { + iExtnDevicePropDp = aExtnDevicePropDp; + }; + +/** +*This method returns the devicedp reference +*/ +MExtnDevicePropDp* CMTPDeviceDataStore::ExtnDevicePropDp() +{ + return iExtnDevicePropDp; +}; + + +/** +*This method to get supported device properties +**/ +const CMTPTypeArray& CMTPDeviceDataStore::GetSupportedDeviceProperties() + { + return *iSupportedDevProArray; + } + +/** +This method will remove the property that is not supported +As of now, will check the device icon property support +*/ +void CMTPDeviceDataStore::CheckDeviceIconProperties( RArray &aSupportedDeviceProperties) + { + //store the index value if device property. + TUint index = aSupportedDeviceProperties.Find(EMTPDevicePropCodeDeviceIcon); + if(KErrNotFound != (TInt)index) + { + RFs rFs; + RFile rFile; + TInt error = rFs.Connect(); + if(KErrNone == error) + { + error = rFile.Open(rFs, KFileName, EFileRead); + }//else do nothing. + if(KErrNone != error) + { + //control reach here only when there is no file exists or any other error situation + //so remove the property from the list + aSupportedDeviceProperties.Remove(index); + }//else do nothing + rFile.Close(); + rFs.Close(); + }//else nothing to do. + } +