--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmserv/radioutility/presetutility/src/cenrephandler.cpp Mon May 03 12:59:52 2010 +0300
@@ -0,0 +1,390 @@
+/*
+* Copyright (c) 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:
+*
+*
+*/
+
+
+// System includes
+#include <centralrepository.h>
+#include <s32mem.h>
+
+// User includes
+#include "cenrephandler.h"
+#include "presetcrkeys.h"
+#include <preset.h>
+#include "cenrepbookkeeping.h"
+#include "trace.h"
+
+
+class TChannelIndexList
+ {
+public:
+ TInt iChannelIndex;
+ TInt iNameIndex;
+ TInt iFrequencyIndex;
+ TInt iUrlIndex;
+ TInt iRestOfParametersIndex;
+ };
+
+// ============= STATIC FUNCTIONS ==============
+
+static TInt CalculateChannelIndexes( const TInt aChannelIndex, TChannelIndexList& aChannelIndexList)
+ {
+ FUNC_LOG;
+ TInt err( KErrNone );
+ if ( ( KMaxNumberOfPresetStations <= aChannelIndex ) ||
+ ( 0 > aChannelIndex ) )
+ {
+ err = KErrArgument;
+ }
+ else
+ {
+ aChannelIndexList.iChannelIndex =
+ KRadioPresetChannel1 + ( KNbrOfParametersPerChannelSequence * aChannelIndex );
+ aChannelIndexList.iNameIndex =
+ aChannelIndexList.iChannelIndex + KChannelNameOffset;
+ aChannelIndexList.iFrequencyIndex =
+ aChannelIndexList.iChannelIndex + KFrequencyOffset;
+ aChannelIndexList.iUrlIndex =
+ aChannelIndexList.iChannelIndex + KUrlOffset;
+ aChannelIndexList.iRestOfParametersIndex =
+ aChannelIndexList.iChannelIndex + KRestOfParametersOffset;
+ }
+ return err;
+ }
+
+// ============= MEMBER FUNCTIONS ==============
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CCenrepHandler::CCenrepHandler()
+ {
+ FUNC_LOG;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CCenrepHandler::ConstructL()
+ {
+ FUNC_LOG;
+ iCentralRepository = CRepository::NewL( KCRUidPresetUtility );
+ iBookKeeping = new (ELeave) CCenrepBookKeeping;
+ ReadBookKeepingL();
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CCenrepHandler* CCenrepHandler::NewL()
+ {
+ FUNC_LOG;
+ CCenrepHandler* self = new (ELeave) CCenrepHandler();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CCenrepHandler::~CCenrepHandler()
+ {
+ FUNC_LOG;
+ delete iCentralRepository;
+ delete iBookKeeping;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TInt CCenrepHandler::MaxPresetCount() const
+ {
+ FUNC_LOG;
+ return KMaxNumberOfPresetStations;
+ }
+
+// -----------------------------------------------------------------------------
+// Get the current number of presets
+// -----------------------------------------------------------------------------
+//
+TInt CCenrepHandler::PresetCount() const
+ {
+ FUNC_LOG;
+ return iBookKeeping->PresetCount();
+ }
+
+// -----------------------------------------------------------------------------
+// Gets the first preset
+// -----------------------------------------------------------------------------
+//
+TInt CCenrepHandler::FirstPreset() const
+ {
+ FUNC_LOG;
+ return iBookKeeping->FirstIndex();
+ }
+
+// -----------------------------------------------------------------------------
+// Get the next preset index that has been set, given the current index
+// -----------------------------------------------------------------------------
+//
+TInt CCenrepHandler::NextPreset( TInt aFromIndex ) const
+ {
+ FUNC_LOG;
+ return iBookKeeping->NextIndex( aFromIndex );
+ }
+
+// -----------------------------------------------------------------------------
+// Delete the current preset
+// -----------------------------------------------------------------------------
+//
+TInt CCenrepHandler::DeletePreset( TInt aIndex )
+ {
+ FUNC_LOG;
+ TInt err( KErrNone );
+ if ( -1 == aIndex )
+ {
+ // Delete all
+ TChannelIndexList channelIndexList;
+ for ( TInt j( FirstPreset() ); 0 <= j; j = FirstPreset() )
+ {
+ INFO_1("Deleting index: %i", j );
+ if ( KErrNone == CalculateChannelIndexes( j, channelIndexList ) )
+ {
+ iCentralRepository->Delete( channelIndexList.iNameIndex );
+ iCentralRepository->Delete( channelIndexList.iFrequencyIndex );
+ iCentralRepository->Delete( channelIndexList.iUrlIndex );
+ iCentralRepository->Delete( channelIndexList.iRestOfParametersIndex );
+ iBookKeeping->RemoveIndex( j );
+ }
+ }
+ }
+ else
+ {
+ TChannelIndexList channelIndexList;
+ err = CalculateChannelIndexes( aIndex, channelIndexList );
+ if ( KErrNone == err )
+ {
+ iCentralRepository->Delete( channelIndexList.iNameIndex );
+ iCentralRepository->Delete( channelIndexList.iFrequencyIndex );
+ iCentralRepository->Delete( channelIndexList.iUrlIndex );
+ iCentralRepository->Delete( channelIndexList.iRestOfParametersIndex );
+ iBookKeeping->RemoveIndex( aIndex );
+ }
+ }
+ if ( KErrNone == err )
+ {
+ SaveBookKeeping();
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TInt CCenrepHandler::SavePresetL( const TPreset& aPreset, TInt aIndex )
+ {
+ FUNC_LOG;
+ if ( 0 > aIndex )
+ {
+ aIndex = iBookKeeping->FindUnusedIndex();
+ }
+ if ( 0 > aIndex )
+ {
+ User::Leave( KErrDiskFull ); // Not really a good code for this
+ }
+ TChannelIndexList channelIndexList;
+ User::LeaveIfError( CalculateChannelIndexes( aIndex, channelIndexList) );
+
+ // First save name to its own key in the key sequence.
+ User::LeaveIfError( iCentralRepository->Set( channelIndexList.iNameIndex, aPreset.Name() ) );
+
+ // Frequency to its own key in the key sequence.
+ User::LeaveIfError( iCentralRepository->Set( channelIndexList.iFrequencyIndex, (TInt)aPreset.Frequency() ) );
+
+ // Url to its own key in the key sequence.
+ User::LeaveIfError( iCentralRepository->Set( channelIndexList.iUrlIndex, aPreset.Url() ) );
+
+ // Then externalize the rest of the data to a common key.
+ TInt err( KErrNone );
+ TInt length( aPreset.MyExternalizedDataSize() );
+ TUint i ( 1 );
+ INFO_1( "aPreset.MyExternalizedDataSize()=%i", length );
+ for ( TBool cont = ( 0 < length ) ? ETrue : EFalse; (cont); cont = ( KErrOverflow == err ) ? ETrue : EFalse )
+ {
+ HBufC8* buf = HBufC8::NewLC( i * length );
+ TPtr8 bufPtr = buf->Des();
+ RDesWriteStream outStream( bufPtr );
+ CleanupClosePushL( outStream );
+ TRAP( err, aPreset.ExternalizeL( outStream ) );
+ if ( KErrNone == err )
+ {
+ outStream.CommitL();
+ User::LeaveIfError( iCentralRepository->Set( channelIndexList.iRestOfParametersIndex, *buf ) );
+ }
+ else
+ {
+ INFO_2( "SavePresetL bigger buffer (%i) needed than required by aPreset.MyExternalizedDataSize()=%i", i*length, aPreset.MyExternalizedDataSize() );
+ ++i;
+ }
+ CleanupStack::PopAndDestroy( &outStream );
+ CleanupStack::PopAndDestroy( buf );
+ }
+ User::LeaveIfError( err );
+
+ iBookKeeping->AddIndex( aIndex );
+ SaveBookKeeping();
+ return aIndex;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CCenrepHandler::ReadPresetL( TInt aIndex, TPreset& aPreset )
+ {
+ FUNC_LOG;
+
+ // Read name from its own key in the key sequence
+ TChannelIndexList channelIndexList;
+ User::LeaveIfError( CalculateChannelIndexes( aIndex, channelIndexList) );
+ TPresetName tempChannelName;
+ User::LeaveIfError( iCentralRepository->Get(channelIndexList.iNameIndex, tempChannelName ) );
+ aPreset.SetName( tempChannelName );
+
+ // Read frequency from its own key in the key sequence
+ TInt frequency( 0 );
+ User::LeaveIfError( iCentralRepository->Get( channelIndexList.iFrequencyIndex, frequency ) );
+ aPreset.SetFrequency( frequency );
+
+ // Read url from its own key in the key sequence
+ TRadioUrl tempUrlName;
+ TInt err = iCentralRepository->Get( channelIndexList.iUrlIndex, tempUrlName );
+ if ( KErrNone == err )
+ {
+ aPreset.SetUrl( tempUrlName );
+ }
+ else if ( KErrNotFound == err )
+ {
+ // This is an optional parameter.
+ }
+ else
+ {
+ User::Leave( err );
+ }
+
+
+ // Then use the below code to internalize rest of parameters from the common key
+ TInt actualLength( aPreset.MyExternalizedDataSize() );
+ INFO_1( "ReadPresetL aPreset.MyExternalizedDataSize()=%i", actualLength );
+ for ( TBool cont = ( 0 < actualLength ) ? ETrue : EFalse; (cont); cont = ( KErrOverflow == err ) ? ETrue : EFalse )
+ {
+ HBufC8* buf = HBufC8::NewLC( actualLength );
+ TPtr8 bufPtr = buf->Des();
+ err = iCentralRepository->Get( channelIndexList.iRestOfParametersIndex, bufPtr, actualLength );
+ if ( ( KErrNone == err ) && ( 0 < buf->Length() ) )
+ {
+ RDesReadStream inStream;
+ inStream.Open( *buf );
+ CleanupClosePushL( inStream );
+ aPreset.InternalizeL( inStream );
+ CleanupStack::PopAndDestroy( &inStream );
+ }
+ else if ( KErrNotFound == err )
+ {
+ // This is not filled by CT tool even though name, frequency and URL might be
+ // filled for the current channel. Don't leave.
+ INFO_1( "ReadPresetL KErrNotFound, key=%i", channelIndexList.iRestOfParametersIndex );
+ }
+ else if ( KErrOverflow == err )
+ {
+ INFO_2( "ReadPresetL KErrOverflow, buf->Length()=%i actualLength=%i", buf->Length(), actualLength );
+ // Trying again with actual with buffer that can store the whole key
+ }
+ else
+ {
+ User::Leave( err );
+ }
+ CleanupStack::PopAndDestroy(buf);
+ } // for (;;)
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CCenrepHandler::ReadBookKeepingL()
+ {
+ FUNC_LOG;
+ TPtr8 bufPtr = iBookKeeping->BookKeepingData();
+
+ TInt err( iCentralRepository->Get( KRadioBookKeepingLocation, bufPtr ) );
+ if ( KErrNotFound == err )
+ {
+ // Bookkeeping does not exist. Search possible preconfigured channels.
+ ReadPreDefinedPresetsL();
+ err = KErrNone;
+ }
+ User::LeaveIfError( err );
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CCenrepHandler::SaveBookKeeping()
+ {
+ FUNC_LOG;
+ TInt err( iCentralRepository->Set( KRadioBookKeepingLocation, iBookKeeping->BookKeepingData() ) );
+ if ( KErrNone != err )
+ {
+ INFO_1("Saving of BookKeeping failed with error: %i ", err)
+ // It is better to destroy data that is out of sync
+ iCentralRepository->Delete( KRadioBookKeepingLocation );
+ // Go on with local bookkeeping data
+ }
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CCenrepHandler::ReadPreDefinedPresetsL()
+ {
+ FUNC_LOG;
+ TInt frequency ( 0 );
+ TInt err( KErrNone );
+ TChannelIndexList channelIndexList;
+ iBookKeeping->Clear();
+ for(TInt index = 0; index < KMaxNumberOfPresetStations; index++)
+ {
+ User::LeaveIfError( CalculateChannelIndexes( index, channelIndexList) );
+ err = iCentralRepository->Get( channelIndexList.iFrequencyIndex, frequency );
+ if ( KErrNone == err )
+ {
+ iBookKeeping->AddIndex( index );
+ }
+ }
+ SaveBookKeeping();
+ }