diff -r 6ca72c0fe49a -r a941bc465d9f wvsettings20/IMPSSrc/CIMPSSAPCenRep.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wvsettings20/IMPSSrc/CIMPSSAPCenRep.cpp Wed Sep 01 12:31:13 2010 +0100 @@ -0,0 +1,1244 @@ +/* +* Copyright (c) 2005 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: IMPS SAP Settings Store implementation. +* +*/ + + +// INCLUDE FILES + +#include +#include +//#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +//#include +//#endif +#include "CIMPSSAPCenRep.h" +#include "cimpssapsettings.h" +#include "CIMPSSAPSettingsBody.h" +#include "cimpssapsettingslist.h" +#include "CIMPSSAPKeyValuePairs.h" +#include "CIMPSSAPKeyValuePair.h" +#include "CIMPSSAPNotifier.h" + +#include "IMPSSAPSettingsStoreCenRepUids.h" +#include "IMPSSAPSettingsStoreDebugPrint.h" +#include "IMPSSAPSettingsStorePanics.h" + +#include "RIMPSReleaseArray.h" + +#include "TIMPSSAPSettingsListItemNameKey.h" +#include "TIMPSCenRepOperations.h" + +// This implementation uses the following way of dividing the +// central repository id range for storing +// SAP Settings data: +// +// - 6 bits for base id(defines the SAP access group) +// - 10 bits for sap uid(unique within all groups) +// - 16 bits for settings, which is further divided into 256 +// subsets each containing 256 items. Currently 2 subsets are in use. +// First of the subsets contains settings that have fixed identifiers +// and the second one key-value pairs. + + +/* +Example: +------------------------------ + +cenrep entry: 3221356546 int 8081 0 + += + +110000 | 0000000010 | 0000000000000010 +------ ---------- ---------------- +SAP | SAP Uid | Setting Id +Base + +6 bits, 10 bits 16 bits +110000 ..010 = (10 = 2 dec = ESAPPort in TFixedSAPSetting) +(0x30) 2 dec +PEC base +id + +*/ + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::CIMPSSAPCenRep +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CIMPSSAPCenRep::CIMPSSAPCenRep() + { + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CIMPSSAPCenRep::ConstructL( TInt aPriority ) + { + iRepository = CRepository::NewL( KCRUidIMPSStore ); + iNotifier = CIMPSSAPNotifier::NewL( aPriority, KCRUidIMPSStore ); + iCommsDatabase = CCommsDatabase::NewL( EDatabaseTypeIAP ); + SetUpDefaultsL(); + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CIMPSSAPCenRep* CIMPSSAPCenRep::NewL( TInt aPriority ) + { + CIMPSSAPCenRep* self = CIMPSSAPCenRep::NewLC( aPriority ); + CleanupStack::Pop(); + + return self; + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::NewLC +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CIMPSSAPCenRep* CIMPSSAPCenRep::NewLC( TInt aPriority ) + { + CIMPSSAPCenRep* self = new( ELeave ) CIMPSSAPCenRep(); + + CleanupStack::PushL( self ); + self->ConstructL( aPriority ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::~CIMPSSAPCenRep +// Destructor +// ----------------------------------------------------------------------------- +// +CIMPSSAPCenRep::~CIMPSSAPCenRep() + { + delete iRepository; + delete iNotifier; + delete iCommsDatabase; + } + +// HELPER FUNCTIONS + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::MaskedId() +// Calculates masked central repository id for setting +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint32 CIMPSSAPCenRep::MaskedId( TInt aSetting, TUint32 aUid, + TIMPSAccessGroup aGroup ) + { + __ASSERT_ALWAYS( ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSIMAccessGroup ) || + ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSPECAccessGroup ), + Panic( EIMPSInvalidAccessGroup ) ); + + TUint32 maskBase( 0 ); + if ( aGroup & EIMPSIMAccessGroup ) + { + maskBase += KSAPSettingsIMBaseId << KBaseOffset; + } + else + { + maskBase += KSAPSettingsPECBaseId << KBaseOffset; + } + maskBase += aUid << KSAPOffset; + maskBase += aSetting; + + return maskBase; + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::SAPNameExistsL() +// Checks if SAP with given name already exists in given access group. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CIMPSSAPCenRep::SAPNameExistsL( const TDesC& aSAPName, TUint32 aUid, + TIMPSAccessGroup aGroup ) + { + __ASSERT_ALWAYS( ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSIMAccessGroup ) || + ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSPECAccessGroup ), + Panic( EIMPSInvalidAccessGroup ) ); + + CIMPSSAPSettingsList* list = CIMPSSAPSettingsList::NewLC(); + + PopulateSAPSettingsListL( *list, aGroup ); + + TInt count( list->Count() ); + TBool alreadyExists( EFalse ); + TInt index( 0 ); + if ( list->FindNameL( aSAPName, index ) == 0 ) + { + if ( list->UidForIndex( index ) != aUid ) + { + alreadyExists = ETrue; + } + } + + + CleanupStack::PopAndDestroy( list ); + return alreadyExists; + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::SAPProtectionL() +// Checks SAP protection level. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// + +TIMPSSAPProtection CIMPSSAPCenRep::SAPProtectionL( TUint32 aUid, + TIMPSAccessGroup aGroup ) + { + __ASSERT_ALWAYS( ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSIMAccessGroup ) || + ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSPECAccessGroup ), + Panic( EIMPSInvalidAccessGroup ) ); + + TInt ret( ESAPNoProtection ); + User::LeaveIfError( iRepository->Get( EProtection + aUid, ret ) ); + return static_cast< TIMPSSAPProtection >( ret ); + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::NewUidL() +// Gets new Uid for new SAP +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// + +TUint32 CIMPSSAPCenRep::NewUidL() + { + TInt newUid; + TInt ret; + ret = iRepository->Get( KSAPHighestUid, newUid ); + if ( ret == KErrNotFound ) // Highest uid not found, create it + { + // Check if we have existing SAPs despite not having the highest uid. + // This may happen if we have older settings. + if ( SAPCountL( EIMPSAccessFilterAll ) > 0 ) // existing SAPs + { + RArray foundSAPs; + CleanupClosePushL( foundSAPs ); + // FindL return value is currently undocumented, + // thus silently consumed for now + iRepository->FindL( ESAPName, KSAPPopulateAllMask, foundSAPs ); + TInt count( foundSAPs.Count() ); + for ( TInt i( 0 ); i < count; ++i ) + { + //transform found cenrep uids to SAP uids + foundSAPs[i] &= KSAPUidMask; + foundSAPs[i] = foundSAPs[i] >> KSAPOffset; + } + foundSAPs.SortUnsigned(); + // Find the highest existing uid + for ( TUint32 i( KLastSAPId ); i >= KFirstSAPId;i-- ) + { + if ( foundSAPs.Find( i ) == KErrNone ) + { + if ( i < KLastSAPId ) + { + newUid = i + 1; + } + else + { + newUid = KFirstSAPId; + } + break; + } + } + CleanupStack::PopAndDestroy(); // foundSAPs + } + else // No existing SAPs + { + newUid = KFirstSAPId; + } + User::LeaveIfError( iRepository->Create( KSAPHighestUid, newUid ) ); + } + + else // Otherwise if it's an error situation + { + User::LeaveIfError( ret ); + } + + if ( newUid < KFirstSAPId ) + { + // Something is wrong if we get here + User::Leave( KErrGeneral ); + } + else if ( newUid >= KLastSAPId ) // If at the end of the range + { + // start from the beginning + newUid = KFirstSAPId; + } + // Check if there are ANY free uids + if ( ( KLastSAPId - KFirstSAPId ) <= SAPCountL( EIMPSAccessFilterAll ) ) + { + User::Leave( KErrInUse ); // All UIDs in use + } + + // Check if there is the next uid is unused. + TBool okId( EFalse ); + TInt err( KErrNone ); + while ( !okId ) + { + newUid++; + TUint32 maskedUid = newUid << KSAPOffset; + RArray foundSAPs; + CleanupClosePushL( foundSAPs ); + err = iRepository->FindL( maskedUid, KSAPExistsMask, foundSAPs ); + if ( err == KErrNotFound ) // The uid is free + { + okId = ETrue; + } + else if ( err == KErrNone ) // There was a SAP with that uid + { + // Check range + if ( newUid >= KLastSAPId ) + { + newUid = KFirstSAPId; // Start from the beginning. + } + } + else + { + User::Leave( err ); + } + CleanupStack::PopAndDestroy(); //foundSAPs + } + // Save the new highest + User::LeaveIfError( iRepository->Set( KSAPHighestUid, newUid ) ); + return newUid; // return the new uid + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::SAPTypeL() +// Gets SAP type +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// + +TIMPSAccessGroup CIMPSSAPCenRep::SAPTypeL( TUint32 aUid ) + { + TIMPSAccessGroup type( EIMPSNoAccessGroup ); + aUid &= KSAPBaseMask; + aUid = aUid >> KBaseOffset; + if ( aUid == KSAPSettingsPECBaseId ) + { + type = EIMPSPECAccessGroup; + } + else if ( aUid == KSAPSettingsIMBaseId ) + { + type = EIMPSIMAccessGroup; + } + else + { + // aUid was found in unknown access group. Should not happen. + User::Leave( KErrGeneral ); + } + return type; + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::SAPExistsL() +// Checks if SAP exists in central repository +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// + +void CIMPSSAPCenRep::SAPExistsL( TUint32 aUid ) + { + RArray foundSAPs; + CleanupClosePushL( foundSAPs ); + // FindL return value is currently undocumented, + // thus silently consumed for now + iRepository->FindL( aUid, KSAPExistsMask, foundSAPs ); + if ( foundSAPs.Count() != 1 ) + { + User::Leave( KErrNotFound ); + } + CleanupStack::PopAndDestroy(); //foundSAPs + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::SetUpDefaultsL() +// Sets up default SAP ids if they do not exist in the repository +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// + +void CIMPSSAPCenRep::SetUpDefaultsL() + { + TInt uid( 0 ); + TInt err ( iRepository->Get( KDefaultIMSAPId, uid ) ); + if ( err == KErrNotFound ) + { + User::LeaveIfError( iRepository->Create( KDefaultIMSAPId, + KIMPSSettingsNullUid ) ); + } + else + { + User::LeaveIfError( err ); + } + + err = iRepository->Get( KDefaultPECSAPId, uid ); + if ( err == KErrNotFound ) + { + User::LeaveIfError( iRepository->Create( KDefaultPECSAPId, + KIMPSSettingsNullUid ) ); + } + else + { + User::LeaveIfError( err ); + } + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::FindSAPsFromAccessGroupL() +// Finds and populates SAP ids to an array from desired access group +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// + +void CIMPSSAPCenRep::FindSAPsFromAccessGroupL( TIMPSAccessGroup aGroup, + RArray& aFoundSAPs ) + { + if ( aGroup == EIMPSAccessFilterAll ) + { + iRepository->FindL( ESAPAddress, KSAPPopulateAllMask, aFoundSAPs ); + } + else if ( aGroup == EIMPSIMAccessGroup ) + { + iRepository->FindL( MaskedId( ESAPAddress, KIMPSSettingsNullUid, + EIMPSIMAccessGroup ), KSAPPopulateGroupMask, aFoundSAPs ); + } + else if ( aGroup == EIMPSPECAccessGroup ) + { + iRepository->FindL( MaskedId( ESAPAddress, KIMPSSettingsNullUid, + EIMPSPECAccessGroup ), KSAPPopulateGroupMask, aFoundSAPs ); + } + } + + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::StartOwnTransaction() +// Starts new transaction if there is no ongoing transaction +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CIMPSSAPCenRep::StartOwnTransactionL( TInt aMode ) + { +// TInt transaction( iRepository->TransactionState() ); + + if( !iInTransaction ) + { + iInTransaction = ETrue; + CleanupStack::PushL( TCleanupItem( ReSetTransactionState, this )); + iRepository->StartTransaction( static_cast( aMode ) ); + return ETrue; + } + return EFalse; + } + +// OBSERVER SUPPORT + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::AddObserverL() +// Adds SAP observer +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CIMPSSAPCenRep::AddObserverL( MIMPSSAPObserver* aObserver, + TIMPSAccessGroup aGroup ) + { + SSS_DP_TXT( "CIMPSSAPCenRep::AddObserverL()" ); + iNotifier->AddObserverL( aObserver, aGroup ); + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::RemoveObserverL() +// Removes SAP observer +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CIMPSSAPCenRep::RemoveObserver( MIMPSSAPObserver* aObserver ) + { + SSS_DP_TXT( "CIMPSSAPCenRep::RemoveObserver()" ); + iNotifier->RemoveObserver( aObserver ); + } + +// SAP SETTINGS + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::StoreNewSAPL() +// Stores new SAP in central repository +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint32 CIMPSSAPCenRep::StoreNewSAPL( CIMPSSAPSettings* aSAPSettings, + TIMPSAccessGroup aGroup ) + { + SSS_DP_TXT( "CIMPSSAPCenRep::StoreNewSAPL()" ); + + __ASSERT_ALWAYS( ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSIMAccessGroup ) || + ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSPECAccessGroup ), + Panic( EIMPSInvalidAccessGroup ) ); + + // SAP name must be defined + if ( aSAPSettings->SAPName().Length() == 0 ) + { + User::Leave( KErrArgument ); + } + + // no documentation for StartTransaction() return values, leave if any error + iInTransaction = ETrue; + CleanupStack::PushL(TCleanupItem( ReSetTransactionState, this )); + User::LeaveIfError( iRepository->StartTransaction( CRepository::EReadWriteTransaction ) ); + + iRepository->CleanupCancelTransactionPushL(); + + //Check if SAP with given name already exists + + // KIMPSSettingsNullUid cannot exist so this checks for all duplicates + if ( SAPNameExistsL( aSAPSettings->SAPName(), KIMPSSettingsNullUid, + aGroup ) ) + { + User::Leave( KErrAlreadyExists ); + } + + RIMPSReleaseArray tempArray; + CleanupClosePushL( tempArray ); + + // Assign Uid for the new entry, leave if all Uids are in use + TUint32 newUid( NewUidL() ); + + //Encrypt passwords before storing has been removed + //401-1808 - Ease of Instant Messaging SERVER customization + HBufC* tmpPasswd = aSAPSettings->SAPUserPassword().AllocLC(); + HBufC* tmpHTTPPasswd = aSAPSettings->HTTPProxyUserPassword().AllocLC(); + TPtr passwdPtr( tmpPasswd->Des() ); + TPtr httpPasswdPtr( tmpHTTPPasswd->Des() ); + + //get the first stored setting ID as the returnable ID for the client + TUint32 returnId( MaskedId( ESAPAddress, newUid, aGroup ) ); + + // If this is the first SAP to be stored in either access group, + // set it to default + if ( aGroup == EIMPSIMAccessGroup ) + { + if ( SAPCountL( EIMPSIMAccessGroup ) == 0 ) + { + User::LeaveIfError( iRepository->Set( KDefaultIMSAPId, + static_cast< TInt >( returnId ) ) ); + } + } + else + { + if ( SAPCountL( EIMPSPECAccessGroup ) == 0 ) + { + User::LeaveIfError( iRepository->Set( KDefaultPECSAPId, + static_cast< TInt >( returnId ) ) ); + } + } + + TIMPSCenRepOperations op( returnId, *iRepository ); + + op.CreateL( ESAPAddress, aSAPSettings->SAPAddress() ); + op.CreateL( ESAPName, aSAPSettings->SAPName() ); + op.CreateL( ESAPPort, static_cast< TInt >( aSAPSettings->SAPPort() ) ); + op.CreateL( ESAPUserId, aSAPSettings->SAPUserId() ); + op.CreateL( ESAPUserPassword, passwdPtr ); + op.CreateL( EHTTPProxyUserId, aSAPSettings->HTTPProxyUserId() ); + op.CreateL( EHTTPProxyUserPassword, httpPasswdPtr ); + op.CreateL( EHTTPProxyAddress, aSAPSettings->HTTPProxyAddress() ); + op.CreateL( EHTTPProxyPort, static_cast< TInt >( aSAPSettings->HTTPProxyPort() ) ); + + HBufC* apName = DoGetAccessPointsNameL( + static_cast< TInt >( aSAPSettings->AccessPoint() ) ); + CleanupStack::PushL( apName ); + op.CreateL( EAccessPoint, *apName ); + CleanupStack::PopAndDestroy( apName ); + + op.CreateL( EClientId, aSAPSettings->ClientId() ); + op.CreateL( EServerAuthenticationName, aSAPSettings->ServerAuthenticationName() ); + op.CreateL( EServerAuthenticationPassword, aSAPSettings->ServerAuthenticationPassword() ); + op.CreateL( EServerAcceptedContentType, aSAPSettings->ServerAcceptedContentType() ); + op.CreateL( EHighLevelServices, static_cast< TInt >( aSAPSettings->HighLevelServices() ) ); + op.CreateL( EAuthorizationMode, static_cast< TInt >( aSAPSettings->AuthorizationMode() ) ); + op.CreateL( EProtection, static_cast< TInt >( aSAPSettings->Protection() ) ); + + const RPointerArray< CIMPSSAPKeyValuePair >& pairs( aSAPSettings->KeyValuePairs().Pairs() ); + + TInt count( pairs.Count() ); + + for ( TInt i( 0 );i < count; ++i ) + { + //HBufC ownership transfers here + HBufC* valuePairFlat = pairs[i]->KeyValuePairFlatLC(); + User::LeaveIfError( iRepository->Create( EKeyValuePairBase + + returnId + i, + *valuePairFlat ) ); + // CRepository->Create() is not copying the pointed data during transaction + // so these must be stored until the transaction has completed + tempArray.AppendL( valuePairFlat ); + CleanupStack::Pop( valuePairFlat ); + } + + TUint32 err( KErrNone ); + //passed err will be silently consumed because the value is of no use to client + User::LeaveIfError( iRepository->CommitTransaction( err ) ); + iInTransaction = EFalse; + CleanupStack::PopAndDestroy( 5 ); //cleanupitem, Transaction, tempArray, tmpPasswd, tmpHTTPPasswd + + aSAPSettings->Body().DoSetUid( returnId ); + aSAPSettings->Body().DoSetAccessGroup( aGroup ); + return returnId; + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::GetSAPL() +// Gets SAP from central repository +// (other items were commented in a header). +// ----------------------------------------------------------------------------- + +void CIMPSSAPCenRep::GetSAPL( TUint32 aUid, CIMPSSAPSettings* aSAPSettings ) + { + TRAPD( err, DoGetSAPL( aUid, aSAPSettings ) ); + if ( err == KErrArgument ) + { + aSAPSettings->Reset(); + } + else if ( err ) + { + User::Leave( err ); + } + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::DoGetSAPL() +// Does the actual get operation +// (other items were commented in a header). +// ----------------------------------------------------------------------------- + +void CIMPSSAPCenRep::DoGetSAPL( TUint32 aUid, CIMPSSAPSettings* aSAPSettings ) + { + SSS_DP_TXT( "CIMPSSAPCenRep::GetSAPL()" ); + + TBool transaction( StartOwnTransactionL( CRepository::EReadTransaction ) ); + if ( transaction ) + { + iRepository->CleanupCancelTransactionPushL(); + } + + HBufC* tmpBuffer = HBufC::NewLC( NCentralRepositoryConstants::KMaxUnicodeStringLength ); + TPtr tmpPtr( tmpBuffer->Des() ); + + TInt tmpInteger( 0 ); + + SAPExistsL( aUid ); + + TIMPSAccessGroup type( SAPTypeL( aUid ) ); + + TIMPSCenRepOperations op( aUid, *iRepository ); + + op.GetL( ESAPAddress, tmpPtr ); + aSAPSettings->SetSAPAddressL( tmpPtr ); + + op.GetL( ESAPName, tmpPtr ); + aSAPSettings->SetSAPNameL( tmpPtr ); + + op.GetL( ESAPPort, tmpInteger ); + aSAPSettings->SetSAPPort( tmpInteger ); + + op.GetL( ESAPUserId, tmpPtr ); + aSAPSettings->SetSAPUserIdL( tmpPtr ); + + op.GetL( ESAPUserPassword, tmpPtr ); + //Decrypting of passwrd has been removed + //401-1808 - Ease of Instant Messaging SERVER customization + aSAPSettings->SetSAPUserPasswordL( tmpPtr ); + + op.GetL( EHTTPProxyUserId, tmpPtr ); + aSAPSettings->SetHTTPProxyUserIdL( tmpPtr ); + + //Decrypting of passwrd has been removed + //401-1808 - Ease of Instant Messaging SERVER customization + op.GetL( EHTTPProxyUserPassword, tmpPtr ); + aSAPSettings->SetHTTPProxyUserPasswordL( tmpPtr ); + + op.GetL( EHTTPProxyAddress, tmpPtr ); + aSAPSettings->SetHTTPProxyAddressL( tmpPtr ); + + op.GetL( EHTTPProxyPort, tmpInteger ); + aSAPSettings->SetHTTPProxyPort( tmpInteger ); + + //op.GetL( EAccessPoint, tmpInteger ); + op.GetL( EAccessPoint, tmpPtr ); + tmpInteger = static_cast< TInt >( DoGetAccessPointsL( tmpPtr ) ); + aSAPSettings->SetAccessPoint( tmpInteger ); + + op.GetL( EClientId, tmpPtr ); + aSAPSettings->SetClientIdL( tmpPtr ); + + op.GetL( EServerAuthenticationName, tmpPtr ); + aSAPSettings->SetServerAuthenticationNameL( tmpPtr ); + + op.GetL( EServerAuthenticationPassword, tmpPtr ); + aSAPSettings->SetServerAuthenticationPasswordL( tmpPtr ); + + op.GetL( EServerAcceptedContentType, tmpPtr ); + aSAPSettings->SetServerAcceptedContentTypeL( tmpPtr ); + + op.GetL( EHighLevelServices, tmpInteger ); + aSAPSettings->SetHighLevelServices( tmpInteger ); + + op.GetL( EAuthorizationMode, tmpInteger ); + aSAPSettings->SetAuthorizationMode( tmpInteger ); + + op.GetL( EProtection, tmpInteger ); + aSAPSettings->ProtectL( static_cast( tmpInteger ) ); + + RPointerArray< CIMPSSAPKeyValuePair >& pairs( aSAPSettings->KeyValuePairs().Pairs() ); + pairs.ResetAndDestroy(); + + RArray foundPairs; + CleanupClosePushL( foundPairs ); + iRepository->FindL( EKeyValuePairBase + aUid, KSAPPairsMask, foundPairs ); + TInt count( foundPairs.Count() ); + + for ( TInt i( 0 );i < count; ++i ) + { + TPtr valuePairFlatPtr( tmpBuffer->Des() ); + + User::LeaveIfError( + iRepository->Get( foundPairs[ i ], + valuePairFlatPtr ) ); + + // parse the key-value pair descriptor + + CIMPSSAPKeyValuePair* pair = CIMPSSAPKeyValuePair::NewLC( valuePairFlatPtr ); + + pairs.AppendL( pair ); + + CleanupStack::Pop( pair ); + } + + if ( transaction ) + { + TUint32 err( KErrNone ); + User::LeaveIfError( iRepository->CommitTransaction( err ) ); + iInTransaction = EFalse; + CleanupStack::PopAndDestroy(2); // cleanupitem, transaction + } + CleanupStack::PopAndDestroy( 2 ); // foundPairs, tmpBuffer + aSAPSettings->Body().DoSetAccessGroup( type ); + aSAPSettings->Body().DoSetUid( aUid ); + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::SAPCountL() +// Counts the number of SAPs +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CIMPSSAPCenRep::SAPCountL( TIMPSAccessGroup aGroup ) + { + SSS_DP_TXT( "CIMPSSAPCenRep::SAPCountL()" ); + + __ASSERT_ALWAYS( aGroup & EIMPSAccessFilterAll, + Panic( EIMPSInvalidAccessGroup ) ); + + RArray foundSAPs; + CleanupClosePushL( foundSAPs ); + FindSAPsFromAccessGroupL( aGroup, foundSAPs ); + TInt count( foundSAPs.Count() ); + CleanupStack::PopAndDestroy(); //foundSAPs + return count; + } + + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::DeleteSAPL() +// Deletes SAP from central repository +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CIMPSSAPCenRep::DeleteSAPL( TUint32 aUid ) + { + SSS_DP_TXT( "CIMPSSAPCenRep::DeleteSAPL()" ); + + iInTransaction = ETrue; + CleanupStack::PushL( TCleanupItem( ReSetTransactionState, this )); + User::LeaveIfError( iRepository->StartTransaction( CRepository::EReadWriteTransaction ) ); + iRepository->CleanupCancelTransactionPushL(); + + SAPExistsL( aUid ); + TIMPSAccessGroup type( SAPTypeL( aUid ) ); + + RArray foundIds; + CleanupClosePushL( foundIds ); + iRepository->FindL( aUid, KSAPUidMask, foundIds ); + TInt count( foundIds.Count() ); + for ( TInt i( 0 ); i < count; ++i ) + { + User::LeaveIfError( iRepository->Delete( foundIds[ i ] ) ); + } + + CleanupStack::PopAndDestroy(); //foundIds + + TInt sapCount( SAPCountL( type ) ); + + if ( sapCount > 1 ) // deletion not commited yet, but nowadays the API + // seems to give up-to-date counts regardless + { + TUint32 defaultUid; + GetDefaultL( defaultUid, type ); + // default SAP id is set to KIMPSSettingsNullUid if the + // default SAP was deleted + if ( type == EIMPSIMAccessGroup ) + { + if ( aUid == defaultUid ) + { + User::LeaveIfError( iRepository->Set( KDefaultIMSAPId, + KIMPSSettingsNullUid ) ); + } + } + else + { + if ( aUid == defaultUid ) + { + User::LeaveIfError( iRepository->Set( KDefaultPECSAPId, + KIMPSSettingsNullUid ) ); + } + } + } + // If there is only one SAP left after the deletion, set it to default. + if ( sapCount == 1 ) + { + CIMPSSAPSettingsList* list = CIMPSSAPSettingsList::NewLC(); + PopulateSAPSettingsListL( *list, type ); + TUint32 newDefault( list->UidForIndex( 0 ) ); + SetToDefaultL( newDefault, type ); + CleanupStack::PopAndDestroy( list ); + } + // If there are no SAPs left after the deletion, default SAP id is + // set to KIMPSSettingsNullUid + if ( sapCount == 0 ) + { + if ( type == EIMPSIMAccessGroup ) + { + User::LeaveIfError( iRepository->Set( KDefaultIMSAPId, + KIMPSSettingsNullUid ) ); + } + else + { + User::LeaveIfError( iRepository->Set( KDefaultPECSAPId, + KIMPSSettingsNullUid ) ); + } + } + TUint32 err; + User::LeaveIfError( iRepository->CommitTransaction( err ) ); + iInTransaction = EFalse; + CleanupStack::PopAndDestroy(2); //cleanupitem, Transaction + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::UpdateOldSAPL() +// Updates existing SAP +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CIMPSSAPCenRep::UpdateOldSAPL( CIMPSSAPSettings* aSAPSettings, TUint32 aUid ) + { + SSS_DP_TXT( "CIMPSSAPCenRep::UpdateOldSAPL()" ); + + iInTransaction = ETrue; + CleanupStack::PushL( TCleanupItem( ReSetTransactionState, this )); + User::LeaveIfError( iRepository->StartTransaction( CRepository::EReadWriteTransaction ) ); + iRepository->CleanupCancelTransactionPushL(); + + SAPExistsL( aUid ); + TIMPSAccessGroup type( SAPTypeL( aUid ) ); + TIMPSSAPProtection protection( SAPProtectionL( aUid, type ) ); + + if ( protection == ESAPBrandProtection ) + { + CIMPSSAPSettings* settings = CIMPSSAPSettings::NewLC(); + GetSAPL( aUid, settings ); + if ( ( settings->SAPName().Compare( aSAPSettings->SAPName() ) != 0 ) ) + { + // User is trying to modify protected values, leave + User::Leave( KErrAccessDenied ); + } + CleanupStack::PopAndDestroy( settings ); + } + + //Check for duplicate SAP names. SAPName in SAP with aUid is permitted to be + //same as it is the one we are updating. + if ( SAPNameExistsL( aSAPSettings->SAPName(), aUid, type ) ) + { + User::Leave( KErrAlreadyExists ); + } + + RIMPSReleaseArray tempArray; + CleanupClosePushL( tempArray ); + + //Encrypt password before storing has been removed + //401-1808 - Ease of Instant Messaging SERVER customization + HBufC* tmpPasswd = aSAPSettings->SAPUserPassword().AllocLC(); + HBufC* tmpHTTPPasswd = aSAPSettings->HTTPProxyUserPassword().AllocLC(); + TPtr passwdPtr( tmpPasswd->Des() ); + TPtr httpPasswdPtr( tmpHTTPPasswd->Des() ); + + TIMPSCenRepOperations op( aUid, *iRepository ); + + op.SetL( ESAPAddress, aSAPSettings->SAPAddress() ); + op.SetL( ESAPName, aSAPSettings->SAPName() ); + op.SetL( ESAPPort, static_cast< TInt >( aSAPSettings->SAPPort() ) ); + op.SetL( ESAPUserId, aSAPSettings->SAPUserId() ); + op.SetL( ESAPUserPassword, passwdPtr ); + op.SetL( EHTTPProxyUserId, aSAPSettings->HTTPProxyUserId() ); + op.SetL( EHTTPProxyUserPassword, httpPasswdPtr ); + op.SetL( EHTTPProxyAddress, aSAPSettings->HTTPProxyAddress() ); + op.SetL( EHTTPProxyPort, static_cast< TInt >( aSAPSettings->HTTPProxyPort() ) ); + + HBufC* apName = DoGetAccessPointsNameL( + static_cast< TInt >( aSAPSettings->AccessPoint() ) ); + CleanupStack::PushL( apName ); + op.SetL( EAccessPoint, *apName ); + CleanupStack::PopAndDestroy( apName ); + + op.SetL( EClientId, aSAPSettings->ClientId() ); + op.SetL( EServerAuthenticationName, aSAPSettings->ServerAuthenticationName() ); + op.SetL( EServerAuthenticationPassword, aSAPSettings->ServerAuthenticationPassword() ); + op.SetL( EServerAcceptedContentType, aSAPSettings->ServerAcceptedContentType() ); + op.SetL( EHighLevelServices, static_cast< TInt >( aSAPSettings->HighLevelServices() ) ); + op.SetL( EAuthorizationMode, static_cast< TInt >( aSAPSettings->AuthorizationMode() ) ); + op.SetL( EProtection, static_cast< TInt >( aSAPSettings->Protection() ) ); + + //First delete old key-value pairs + RArray foundPairs; + CleanupClosePushL( foundPairs ); + iRepository->FindL( EKeyValuePairBase + aUid, KSAPPairsMask, foundPairs ); + TInt oldCount( foundPairs.Count() ); + + for ( TInt i( 0 ); i < oldCount; ++i ) + { + User::LeaveIfError( iRepository->Delete( foundPairs[i] ) ); + } + + //Create new pairs + const RPointerArray< CIMPSSAPKeyValuePair >& pairs( aSAPSettings->KeyValuePairs().Pairs() ); + + TInt count( pairs.Count() ); + + for ( TInt i( 0 );i < count; ++i ) + { + //this creates a new hbufc and transfers ownership here + HBufC* valuePairFlat = pairs[i]->KeyValuePairFlatLC(); + TPtr valuePairFlatPtr( valuePairFlat->Des() ); + + User::LeaveIfError( iRepository->Create( EKeyValuePairBase + i + aUid, + valuePairFlatPtr ) ); + + // CRepository->Set() is not copying the pointed data during transaction + // so these must be stored until the transaction has completed + tempArray.AppendL( valuePairFlat ); + CleanupStack::Pop( valuePairFlat ); + } + + TUint32 err( KErrNone ); + User::LeaveIfError( iRepository->CommitTransaction( err ) ); + iInTransaction = EFalse; + CleanupStack::PopAndDestroy( 6 ); // cleanupitem, Transaction, tmpPasswd, tmpHTTPPasswd, tempArray, foundPairs + + aSAPSettings->Body().DoSetUid( aUid ); + aSAPSettings->Body().DoSetAccessGroup( type ); + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::PopulateSAPSettingsListL() +// Populates SAP settings list +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// + +void CIMPSSAPCenRep::PopulateSAPSettingsListL( CIMPSSAPSettingsList& aList, + TIMPSAccessGroup aGroup, TBool aAscending ) + { + SSS_DP_TXT( "CIMPSSAPCenRep::PopulateSAPSettingsListL()" ); + + __ASSERT_ALWAYS( aGroup & EIMPSAccessFilterAll, + Panic( EIMPSInvalidAccessGroup ) ); + + TBool transaction( StartOwnTransactionL( CRepository::EReadTransaction ) ); + if ( transaction ) + { + iRepository->CleanupCancelTransactionPushL(); + } + + CIMPSSAPSettingsListItem* listItem = NULL; + TIMPSSAPSettingsListItemNameKey key( aAscending ); + + RArray foundSAPs; + CleanupClosePushL( foundSAPs ); + + FindSAPsFromAccessGroupL( aGroup, foundSAPs ); + + TInt count( foundSAPs.Count() ); + + for ( TInt i( 0 ); i < count; ++i ) + { + HBufC16* name = HBufC::NewLC( NCentralRepositoryConstants::KMaxUnicodeStringLength ); + TPtr namePtr( name->Des() ); + + TIMPSAccessGroup type( SAPTypeL( foundSAPs[i] ) ); + + TInt err( iRepository->Get( foundSAPs[i] + ESAPName, namePtr ) ); + if ( err && ( err != KErrArgument ) ) + { + User::Leave( err ); + } + + TInt protectionInt( ESAPNoProtection ); + err = iRepository->Get( foundSAPs[i] + EProtection, protectionInt ); + + if ( err && ( err != KErrArgument ) ) + { + User::Leave( err ); + } + + listItem = CIMPSSAPSettingsListItem::NewLC( *name, foundSAPs[ i ], type, + static_cast( protectionInt ) ); + aList.InsertIsqAllowDuplicatesL( listItem, key ); //takes ownership of listitem + CleanupStack::Pop( listItem ); + CleanupStack::PopAndDestroy( name ); + } + CleanupStack::PopAndDestroy(); // foundSAPs + if ( transaction ) + { + TUint32 err( KErrNone ); + User::LeaveIfError( iRepository->CommitTransaction( err ) ); + iInTransaction = EFalse; + CleanupStack::PopAndDestroy(2); // cleanupitem, transaction + } + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::GetDefaultL() +// Gets Uid of default SAP +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// + +void CIMPSSAPCenRep::GetDefaultL( TUint32& aUid, TIMPSAccessGroup aGroup ) + { + SSS_DP_TXT( "CIMPSSAPCenRep::GetDefaultL()" ); + + __ASSERT_ALWAYS( ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSIMAccessGroup ) || + ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSPECAccessGroup ), + Panic( EIMPSInvalidAccessGroup ) ); + TBool transaction( StartOwnTransactionL( CRepository::EReadTransaction ) ); + if ( transaction ) + { + iRepository->CleanupCancelTransactionPushL(); + } + + TInt uid( 0 ); + if ( aGroup & EIMPSIMAccessGroup ) + { + User::LeaveIfError( iRepository->Get( KDefaultIMSAPId, uid ) ); + } + else + { + User::LeaveIfError( iRepository->Get( KDefaultPECSAPId, uid ) ); + } + if ( transaction ) + { + TUint32 err( KErrNone ); + User::LeaveIfError( iRepository->CommitTransaction( err ) ); + iInTransaction = EFalse; + CleanupStack::PopAndDestroy(2); // cleanupitem, transaction + } + aUid = uid; + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::GetDefaultL() +// Gets default SAP to settings container +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// + +void CIMPSSAPCenRep::GetDefaultL( CIMPSSAPSettings* aSAPSettings, + TIMPSAccessGroup aGroup ) + { + SSS_DP_TXT( "CIMPSSAPCenRep::GetDefaultL() #2" ); + + __ASSERT_ALWAYS( ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSIMAccessGroup ) || + ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSPECAccessGroup ), + Panic( EIMPSInvalidAccessGroup ) ); + + TUint32 uid; + GetDefaultL( uid, aGroup ); + GetSAPL( uid, aSAPSettings ); + } + +// ----------------------------------------------------------------------------- +// CIMPSSAPCenRep::SetToDefaultL() +// Sets given SAP to default SAP +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// + +void CIMPSSAPCenRep::SetToDefaultL( TUint32 aUid, TIMPSAccessGroup aGroup ) + { + SSS_DP_TXT( "CIMPSSAPCenRep::SetToDefaultL()" ); + + __ASSERT_ALWAYS( ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSIMAccessGroup ) || + ( ( aGroup & EIMPSAccessFilterAll ) == EIMPSPECAccessGroup ), + Panic( EIMPSInvalidAccessGroup ) ); + + TBool transaction( StartOwnTransactionL( CRepository::EReadWriteTransaction ) ); + if ( transaction ) + { + iRepository->CleanupCancelTransactionPushL(); + } + + // check that aUid exists + SAPExistsL( aUid ); + + //and it belongs to the given group + if ( SAPTypeL( aUid ) & aGroup ) + { + if ( aGroup & EIMPSIMAccessGroup ) + { + User::LeaveIfError( iRepository->Set( KDefaultIMSAPId, + static_cast( aUid ) ) ); + } + else + { + User::LeaveIfError( iRepository->Set( KDefaultPECSAPId, + static_cast( aUid ) ) ); + } + } + else + { + User::Leave( KErrNotFound ); + } + + if ( transaction ) + { + TUint32 err( KErrNone ); + User::LeaveIfError( iRepository->CommitTransaction( err ) ); + iInTransaction = EFalse; + CleanupStack::PopAndDestroy(2); // cleanupitem, transaction + } + } + +//401-1808 - Ease of Instant Messaging SERVER customization + +// --------------------------------------------------------- +// CIMPSSAPCenRep::DoGetAccessPointsL +// --------------------------------------------------------- +// +TUint32 CIMPSSAPCenRep::DoGetAccessPointsL( const TDesC& aAPName ) + { + TUint32 ap = 0; + TInt err( KErrNone ); + + // Iterate the IAP table from CommsDat + CCommsDbTableView* table = NULL; + + table = iCommsDatabase->OpenViewMatchingTextLC( TPtrC( IAP ), TPtrC( COMMDB_NAME ), aAPName ); + + err = table->GotoFirstRecord(); + + if ( !err ) + { + // Read IAP's ID + // + table->ReadUintL( TPtrC( COMMDB_ID ), ap ); + } + + CleanupStack::PopAndDestroy( table ); + + return ap; + } + + +// --------------------------------------------------------- +// CIMPSSAPCenRep::DoGetAccessPointsNameL +// --------------------------------------------------------- +// +HBufC* CIMPSSAPCenRep::DoGetAccessPointsNameL( const TUint32 aAP ) + { + TInt err( KErrNone ); + HBufC* buf1 = NULL; + + // Iterate the IAP table from CommsDat + CCommsDbTableView* table = NULL; + table = iCommsDatabase->OpenViewMatchingUintLC( TPtrC( IAP ), TPtrC( COMMDB_ID ), aAP ); + err = table->GotoFirstRecord(); + + if ( !err ) + { + TInt length1( 0 ); + + // Read IAP's connection name + // + table->ReadColumnLengthL( TPtrC( COMMDB_NAME ), length1 ); + buf1 = HBufC::NewLC( length1 ); + TPtr ptr1( buf1->Des() ); + table->ReadTextL( TPtrC( COMMDB_NAME ), ptr1 ); + } + else + { + buf1 = KNullDesC().AllocLC(); + } + + CleanupStack::Pop( buf1 ); + CleanupStack::PopAndDestroy( table ); + + return buf1; + } + +// --------------------------------------------------------- +// CIMPSSAPCenRep::ReSetTransactionState +// --------------------------------------------------------- +// +void CIMPSSAPCenRep::ReSetTransactionState(TAny* ptr) + { + reinterpret_cast( ptr )->ReSetTransactionFlag(); + } + +// --------------------------------------------------------- +// CIMPSSAPCenRep::ReSetTransactionFlag +// --------------------------------------------------------- +// +void CIMPSSAPCenRep::ReSetTransactionFlag() + { + iInTransaction = EFalse; + } +//End 401-1808 - Ease of Instant Messaging SERVER customization + +// End of File