Bug 3539. Update localisation mappings.
/*
* 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 <e32std.h>
#include <centralrepository.h>
//#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
//#include <centralrepositoryinternal.h>
//#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<TUint32> 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<TUint32> 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<TUint32> 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<TUint32>& 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<CRepository::TTransactionMode>( 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<TIMPSSAPProtection>( tmpInteger ) );
RPointerArray< CIMPSSAPKeyValuePair >& pairs( aSAPSettings->KeyValuePairs().Pairs() );
pairs.ResetAndDestroy();
RArray<TUint32> 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<TUint32> 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<TUint32> 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<TUint32> 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<TUint32> 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<TIMPSSAPProtection>( 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<TInt>( aUid ) ) );
}
else
{
User::LeaveIfError( iRepository->Set( KDefaultPECSAPId,
static_cast<TInt>( 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<CIMPSSAPCenRep*>( ptr )->ReSetTransactionFlag();
}
// ---------------------------------------------------------
// CIMPSSAPCenRep::ReSetTransactionFlag
// ---------------------------------------------------------
//
void CIMPSSAPCenRep::ReSetTransactionFlag()
{
iInTransaction = EFalse;
}
//End 401-1808 - Ease of Instant Messaging SERVER customization
// End of File