cmmanager/cmmgr/cmmserver/src/cmmsession.cpp
changeset 20 9c97ad6591ae
child 27 489cf6208544
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmmanager/cmmgr/cmmserver/src/cmmsession.cpp	Mon May 03 12:53:07 2010 +0300
@@ -0,0 +1,3064 @@
+/*
+* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* Handles client requests.
+*
+*/
+
+
+#include <cmconnectionmethoddef.h>
+#include <cmpluginembdestinationdef.h>
+#include <cmdefconnvalues.h>
+
+#include "cmmserver.h"
+#include "cmmserverdefs.h"
+#include "cmmsession.h"
+#include "cmmdestinationinstance.h"
+#include "cmmconnmethodinstance.h"
+
+#include "OstTraceDefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "cmmsessionTraces.h"
+#endif
+
+
+CCmmSession* CCmmSession::NewL( CCmmServer& aServer, CCmmCache& aCache )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_NEWL_ENTRY );
+
+    CCmmSession* self = CCmmSession::NewLC( aServer, aCache );
+    CleanupStack::Pop( self );
+
+    OstTraceFunctionExit0( CCMMSESSION_NEWL_EXIT );
+    return self;
+    }
+
+CCmmSession* CCmmSession::NewLC( CCmmServer& aServer, CCmmCache& aCache )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_NEWLC_ENTRY );
+
+    CCmmSession* self = new( ELeave ) CCmmSession( aServer, aCache );
+    CleanupStack::PushL( self ) ;
+    self->ConstructL() ;
+
+    OstTraceFunctionExit0( CCMMSESSION_NEWLC_EXIT );
+    return self ;
+    }
+
+// -----------------------------------------------------------------------------
+// Constructor.
+// -----------------------------------------------------------------------------
+//
+CCmmSession::CCmmSession( CCmmServer& aServer, CCmmCache& aCache )
+        :
+        iServer( aServer ),
+        iCache( aCache )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_CCMMSESSION_ENTRY );
+
+    iDestinationContainer = NULL;
+    iDestinationObjects = NULL;
+    iConnMethodContainer = NULL;
+    iConnMethodObjects = NULL;
+
+    OstTraceFunctionExit0( CCMMSESSION_CCMMSESSION_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// The second phase of two phase construction.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::ConstructL()
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_CONSTRUCTL_ENTRY );
+
+    iServer.IncrementSessions();
+
+    // Create a new object index (it stores the destination objects owned by
+    // this session).
+    iDestinationObjects = CObjectIx::NewL();
+
+    // Initialize the object container using the object container index in the
+    // server (Object container provides unique ids for the objects owned by
+    // this session).
+    iDestinationContainer = iServer.NewContainerL();
+
+    // The same for connection method subsessions.
+    iConnMethodObjects = CObjectIx::NewL();
+    iConnMethodContainer = iServer.NewContainerL();
+
+    OstTraceFunctionExit0( CCMMSESSION_CONSTRUCTL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CCmmSession::~CCmmSession()
+    {
+    OstTraceFunctionEntry0( DUP1_CCMMSESSION_CCMMSESSION_ENTRY );
+
+    iServer.DecrementSessions();
+
+    delete iDestinationObjects;
+    iDestinationObjects = NULL;
+
+    if ( iDestinationContainer != 0 )
+        {
+        iServer.RemoveContainer( iDestinationContainer );
+        iDestinationContainer = NULL;
+        }
+
+    delete iConnMethodObjects;
+    iConnMethodObjects = NULL;
+
+    if ( iConnMethodContainer != 0 )
+        {
+        iServer.RemoveContainer( iConnMethodContainer );
+        iConnMethodContainer = NULL;
+        }
+    OstTraceFunctionExit0( DUP1_CCMMSESSION_CCMMSESSION_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::ServiceL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::ServiceL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_SERVICEL_ENTRY );
+
+    TInt result( KErrNone );
+    switch ( aMessage.Function() )
+        {
+        case ECmmGetBearerInfoInt:
+            {
+            GetBearerInfoIntL( aMessage );
+            }
+            break;
+        case ECmmGetBearerInfoBool:
+            {
+            GetBearerInfoBoolL( aMessage );
+            }
+            break;
+        case ECmmGetBearerInfoString:
+            {
+            GetBearerInfoStringL( aMessage );
+            }
+            break;
+        case ECmmGetBearerInfoString8:
+            {
+            GetBearerInfoString8L( aMessage );
+            }
+            break;
+        case ECmmGetConnMethodInfoInt:
+            {
+            GetConnMethodInfoIntL( aMessage );
+            }
+            break;
+        case ECmmGetConnMethodInfoBool:
+            {
+            GetConnMethodInfoBoolL( aMessage );
+            }
+            break;
+        case ECmmGetConnMethodInfoString:
+            {
+            GetConnMethodInfoStringL( aMessage );
+            }
+            break;
+        case ECmmGetConnMethodInfoString8:
+            {
+            GetConnMethodInfoString8L( aMessage );
+            }
+            break;
+        case ECmmGetConnMethodArray:
+            {
+            GetConnMethodArrayL( aMessage );
+            }
+            break;
+        case ECmmGetAllDestinations:
+            {
+            GetAllDestinationsL( aMessage );
+            }
+            break;
+        case ECmmGetEasyWlanId:
+            {
+            GetEasyWLANIdL( aMessage );
+            }
+            break;
+        case ECmmRemoveAllReferences: // CM becomes uncategorized.
+            {
+            RemoveAllReferencesL( aMessage );
+            }
+            break;
+        case ECmmGetSupportedBearers:
+            {
+            GetSupportedBearersL( aMessage );
+            }
+            break;
+        case ECmmReadDefaultConnection:
+            {
+            ReadDefaultConnectionL( aMessage );
+            }
+            break;
+        case ECmmWriteDefaultConnection:
+            {
+            // Default connection is now just internet snap.
+            result = KErrNotSupported;
+            }
+            break;
+        case ECmmReadGeneralConnectionSettings:
+            {
+            ReadGenConnSettingsL( aMessage );
+            }
+            break;
+        case ECmmWriteGeneralConnectionSettings:
+            {
+            WriteGenConnSettingsL( aMessage );
+            }
+            break;
+        case ECmmGetBearerPriorityArray:
+            {
+            GetBearerPriorityArrayL( aMessage );
+            }
+            break;
+        case ECmmUpdateBearerPriorityArray:
+            {
+            UpdateBearerPriorityArrayL( aMessage );
+            }
+            break;
+        case ECmmCopyConnMethod:
+            {
+            CopyConnMethodL( aMessage );
+            }
+            break;
+        case ECmmMoveConnMethod:
+            {
+            MoveConnMethodL( aMessage );
+            }
+            break;
+        case ECmmRemoveConnMethod:
+            {
+            RemoveConnMethodL( aMessage );
+            }
+            break;
+
+        case EDestGetDestination:
+        case EDestRefresh:
+        case EDestCreateDestinationWithName:
+        case EDestCreateDestinationWithNameAndId:
+        case EDestCloseDestination:
+        case EDestGetConnMethodCount:
+        case EDestGetConnMethodPriority:
+        case EDestGetName:
+        case EDestGetId:
+        case EDestGetElementId:
+        case EDestMetadata:
+        case EDestGetProtectionLevel:
+        case EDestIsConnected:
+        case EDestIsHidden:
+        case EDestIsEqual:
+        case EDestAddConnMethod:
+        case EDestAddEmbeddedDestination:
+        case EDestDeleteConnMethod:
+        case EDestRemoveConnMethod:
+        case EDestModifyPriority:
+        case EDestSetName:
+        case EDestSetMetadata:
+        case EDestSetProtection:
+        case EDestSetHidden:
+        case EDestUpdate:
+        case EDestDelete:
+            {
+            ServiceDestinationL( aMessage );
+            }
+            break;
+
+        case ECMGetConnMethodWithId:
+        case ECMRefresh:
+        case ECMCreateConnMethod:
+        case ECMCreateConnMethodWithId:
+        case ECMGetConnMethodFromDestWithIndex:
+        case ECMGetConnMethodFromDestWithId:
+        case ECMCreateConnMethodToDest:
+        case ECMCreateConnMethodToDestWithId:
+        case ECMCreateCopyOfExisting:
+        case ECMCloseConnMethod:
+        case ECMGetIntAttribute:
+        case ECMGetBoolAttribute:
+        case ECMGetStringAttribute:
+        case ECMGetString8Attribute:
+        case ECMIsEqual:
+        case ECMSetIntAttribute:
+        case ECMSetBoolAttribute:
+        case ECMSetStringAttribute:
+        case ECMSetString8Attribute:
+        case ECMDelete:
+        case ECMUpdate:
+        case EDestGetEmbeddedDestination:
+            {
+            ServiceConnMethodL( aMessage );
+            }
+            break;
+        default:
+            {
+            result = KErrNotSupported;
+            }
+            break;
+        }
+
+    aMessage.Complete( result );
+
+    OstTraceFunctionExit0( CCMMSESSION_SERVICEL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Finds a connection method instance that belongs to this session and matches
+// the provided ID. Return NULL if no match is found.
+// -----------------------------------------------------------------------------
+//
+CCmmConnMethodInstance* CCmmSession::FindConnMethodInstanceById(
+        const TUint32& aConnMethodId )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_FINDCONNMETHODINSTANCEBYID_ENTRY );
+
+    CCmmConnMethodInstance* wantedConnMethodInstance( NULL );
+
+    for ( TInt i = 0; i < iConnMethodObjects->Count(); i++ )
+        {
+        CCmmConnMethodInstance* connMethodInstance =
+                ( CCmmConnMethodInstance* )( ( *iConnMethodObjects )[i] );
+        if ( connMethodInstance && connMethodInstance->GetId() == aConnMethodId )
+            {
+            wantedConnMethodInstance = connMethodInstance;
+            break;
+            }
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_FINDCONNMETHODINSTANCEBYID_EXIT );
+    return wantedConnMethodInstance;
+    }
+
+// -----------------------------------------------------------------------------
+// Finds a destination instance that belongs to this session and matches
+// the provided handle.
+// -----------------------------------------------------------------------------
+//
+CCmmDestinationInstance* CCmmSession::FindDestinationInstanceByHandleL(
+        const TInt& aDestinationHandle )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_FINDDESTINATIONINSTANCEBYHANDLEL_ENTRY );
+
+    return (CCmmDestinationInstance*)iDestinationObjects->AtL( aDestinationHandle );
+    }
+
+// -----------------------------------------------------------------------------
+// Finds a destination instance that belongs to this session and matches
+// the provided ID. Return NULL if no match is found.
+// -----------------------------------------------------------------------------
+//
+CCmmDestinationInstance* CCmmSession::FindDestinationInstanceById(
+        const TUint32& aDestinationId )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_FINDDESTINATIONINSTANCEBYID_ENTRY );
+
+    CCmmDestinationInstance* wantedDestinationInstance( NULL );
+
+    for ( TInt i = 0; i < iDestinationObjects->Count(); i++ )
+        {
+        CCmmDestinationInstance* destinationInstance =
+                ( CCmmDestinationInstance* )( ( *iDestinationObjects )[i] );
+        if ( destinationInstance && destinationInstance->GetId() == aDestinationId )
+            {
+            wantedDestinationInstance = destinationInstance;
+            break;
+            }
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_FINDDESTINATIONINSTANCEBYID_EXIT );
+    return wantedDestinationInstance;
+    }
+
+// -----------------------------------------------------------------------------
+// Check from all open destination handles in this session if the given
+// connection method is inside any of them. The given destination is skipped.
+// -----------------------------------------------------------------------------
+//
+TBool CCmmSession::ConnMethodInOtherDestination(
+        const TUint32& aConnMethodId,
+        const TUint32& aDestinationId )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_CONNMETHODINOTHERDESTINATION_ENTRY );
+
+    for ( TInt i = 0; i < iDestinationObjects->Count(); i++ )
+        {
+        CCmmDestinationInstance* destinationInstance =
+                ( CCmmDestinationInstance* )( ( *iDestinationObjects )[i] );
+        if ( destinationInstance && destinationInstance->GetId() != aDestinationId )
+            {
+            for ( TInt j = 0; j < destinationInstance->iConnMethodItemArray.Count(); j++ )
+                {
+                if ( destinationInstance->iConnMethodItemArray[i].iId == aConnMethodId )
+                    {
+                    OstTraceFunctionExit0( CCMMSESSION_CONNMETHODINOTHERDESTINATION_EXIT );
+                    return ETrue;
+                    }
+                }
+            }
+        }
+
+    OstTraceFunctionExit0( DUP1_CCMMSESSION_CONNMETHODINOTHERDESTINATION_EXIT );
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// Check for restrictions for adding an embedded destination from destination
+// instances of all clients.
+// - aDestinationId is the ID of the destination where a destination is beeing
+//   embedded.
+// - aEmbeddedDestinationId is the ID of the destination that is beeing
+//   embedded.
+// -----------------------------------------------------------------------------
+//
+TBool CCmmSession::EmbeddedDestinationConflictsFromAllSessions(
+        const TUint32& aDestinationId,
+        const TUint32& aEmbeddedDestinationId )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_EMBEDDEDDESTINATIONCONFLICTSFROMALLSESSIONS_ENTRY );
+
+    return iServer.EmbeddedDestinationConflictsFromAllSessions( aDestinationId, aEmbeddedDestinationId );
+    }
+
+// -----------------------------------------------------------------------------
+// Check for restrictions for adding an embedded destination from destination
+// instances of this session.
+// - aDestinationId is the ID of the destination where a destination is beeing
+//   embedded.
+// - aEmbeddedDestinationId is the ID of the destination that is beeing
+//   embedded.
+//
+// - Check that any destination instance does not contain aDestinationId as
+//   embedded destination.
+// - Check that any destination instance for aEmbeddedDestinationId does not
+//   contain an embedded destination.
+// -----------------------------------------------------------------------------
+//
+TBool CCmmSession::EmbeddedDestinationConflicts(
+        const TUint32& aDestinationId,
+        const TUint32& aEmbeddedDestinationId )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_EMBEDDEDDESTINATIONCONFLICTS_ENTRY );
+
+    TBool result( EFalse );
+
+    for ( TInt i = 0; i < iDestinationObjects->Count(); i++ )
+        {
+        CCmmDestinationInstance* destinationInstance =
+                ( CCmmDestinationInstance* )( ( *iDestinationObjects )[i] );
+        if ( destinationInstance )
+            {
+            if ( destinationInstance->HasEmbeddedWithId( aDestinationId ) ||
+                    ( destinationInstance->GetId() == aEmbeddedDestinationId &&
+                            destinationInstance->HasEmbedded() ) )
+                {
+                result = ETrue;
+                break;
+                }
+            }
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_EMBEDDEDDESTINATIONCONFLICTS_EXIT );
+    return result;
+    }
+
+// ---------------------------------------------------------------------------
+// After update to database, refresh temporary ID to real ID if necessary and
+// refresh status information for any related handles for all client sessions.
+// ---------------------------------------------------------------------------
+//
+void CCmmSession::RefreshHandlesForAllSessions( const TCmmIdStruct& aIdStruct )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_REFRESHHANDLESFORALLSESSIONS_ENTRY );
+
+    // If the ID structure contains a temporary ID, we need to update the
+    // temporary ID to the real ID for all relevant handles in this session and
+    // cache.
+    if ( aIdStruct.iTemporaryId )
+        {
+        // Real ID tells if this is a destination or connection method.
+
+        if ( aIdStruct.iRealId < KCmmConnMethodIdIntervalMax )
+            {
+            // Connection method. Need to iterate through all destination and
+            // connection method handles.
+
+            // Update the ID of the connection method on session side.
+            for ( TInt i = 0; i < iConnMethodObjects->Count(); i++ )
+                {
+                CCmmConnMethodInstance* connMethodInstance =
+                        ( CCmmConnMethodInstance* )( ( *iConnMethodObjects )[i] );
+                if ( connMethodInstance &&
+                        connMethodInstance->GetId() == aIdStruct.iTemporaryId )
+                    {
+                    connMethodInstance->SetId( aIdStruct.iRealId ); //TODO, need to set ID inside records?
+                    break; // Can only be 1 match.
+                    }
+                }
+            // Update the ID of the connection method in cache side also.
+            iCache.RefreshConnMethodId( aIdStruct );
+
+            // Iterate all destinations. If the connection method is in them,
+            // update the ID to real ID.
+            for ( TInt i = 0; i < iDestinationObjects->Count(); i++ )
+                {
+                CCmmDestinationInstance* destinationInstance =
+                        ( CCmmDestinationInstance* )( ( *iDestinationObjects )[i] );
+                if ( destinationInstance )
+                    {
+                    destinationInstance->RefreshConnMethodId( aIdStruct );
+                    }
+                }
+            }
+        else
+            {
+            // Destination. Need to iterate through all destination handles.
+            for ( TInt i = 0; i < iDestinationObjects->Count(); i++ )
+                {
+                CCmmDestinationInstance* destinationInstance =
+                        ( CCmmDestinationInstance* )( ( *iDestinationObjects )[i] );
+                if ( destinationInstance &&
+                        destinationInstance->GetId() == aIdStruct.iTemporaryId )
+                    {
+                    destinationInstance->SetId( aIdStruct.iRealId );
+                    break; // Can only be 1 match.
+                    }
+                }
+            // Update the ID of the destination in cache side also.
+            iCache.RefreshDestinationId( aIdStruct );
+            }
+        }
+
+    // Update status information for all related destination/connection method
+    // handles in all client sessions.
+    iServer.RefreshHandlesForAllSessions( aIdStruct.iRealId );
+
+    OstTraceFunctionExit0( CCMMSESSION_REFRESHHANDLESFORALLSESSIONS_EXIT );
+    }
+
+// ---------------------------------------------------------------------------
+// Removes a connection method from any open destination handle in this
+// session.
+// ---------------------------------------------------------------------------
+//
+void CCmmSession::RemoveConnMethodFromDestinationHandles(
+        const TUint32& aConnMethodId )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_REMOVECONNMETHODFROMDESTINATIONHANDLES_ENTRY );
+
+    for ( TInt i = 0; i < iDestinationObjects->Count(); i++ )
+        {
+        CCmmDestinationInstance* destinationInstance =
+                ( CCmmDestinationInstance* )( ( *iDestinationObjects )[i] );
+        if ( destinationInstance )
+            {
+            for ( TInt j = 0; j < destinationInstance->iConnMethodItemArray.Count(); j++ )
+                {
+                if ( destinationInstance->iConnMethodItemArray[j].iId == aConnMethodId )
+                    {
+                    destinationInstance->iConnMethodItemArray.Remove( j );
+                    break;
+                    }
+                }
+            }
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_REMOVECONNMETHODFROMDESTINATIONHANDLES_EXIT );
+    }
+
+// ---------------------------------------------------------------------------
+// Notify this session destination/connection method handles about an
+// updated/deleted destination/connection method.
+// ---------------------------------------------------------------------------
+//
+void CCmmSession::RefreshHandles( const TUint32& aId ) const
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_REFRESHHANDLES_ENTRY );
+
+    // Destination or connection method.
+    if ( aId < KCmmConnMethodIdIntervalMax )
+        {
+        // Connection method.
+        for ( TInt i = 0; i < iConnMethodObjects->Count(); i++ )
+            {
+            CCmmConnMethodInstance* connMethodInstance =
+                    ( CCmmConnMethodInstance* )( ( *iConnMethodObjects )[i] );
+            if ( connMethodInstance && connMethodInstance->GetId() == aId )
+                {
+                connMethodInstance->SetStatus( ECmmConnMethodStatusChanged );
+                }
+            }
+        }
+    else
+        {
+        // Destination.
+        for ( TInt i = 0; i < iDestinationObjects->Count(); i++ )
+            {
+            CCmmDestinationInstance* destinationInstance =
+                    ( CCmmDestinationInstance* )( ( *iDestinationObjects )[i] );
+            if ( destinationInstance && destinationInstance->GetId() == aId )
+                {
+                destinationInstance->SetStatus( ECmmDestinationStatusChanged ); //TODO, any record status need be set?
+                }
+            }
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_REFRESHHANDLES_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetBearerInfoIntL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetBearerInfoIntL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETBEARERINFOINTL_ENTRY );
+
+    TUint32 bearerType( aMessage.Int0() );
+    TUint32 attribute( aMessage.Int1() );
+
+    TUint32 result = iCache.GetBearerInfoIntL( bearerType, attribute );
+    TPckg<TUint32> resultPckg( result );
+    aMessage.WriteL( 2, resultPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETBEARERINFOINTL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetBearerInfoBoolL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetBearerInfoBoolL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETBEARERINFOBOOLL_ENTRY );
+
+    TUint32 bearerType( aMessage.Int0() );
+    TUint32 attribute( aMessage.Int1() );
+
+    TBool result = iCache.GetBearerInfoBoolL( bearerType, attribute );
+    TPckg<TBool> resultPckg( result );
+    aMessage.WriteL( 2, resultPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETBEARERINFOBOOLL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetBearerInfoStringL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetBearerInfoStringL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETBEARERINFOSTRINGL_ENTRY );
+
+    TUint32 bearerType( aMessage.Int0() );
+    TUint32 attribute( aMessage.Int1() );
+
+    HBufC* result = iCache.GetBearerInfoStringL( bearerType, attribute );
+    if ( !result )
+        {
+        OstTraceFunctionExit0( CCMMSESSION_GETBEARERINFOSTRINGL_EXIT );
+        return;
+        }
+    CleanupStack::PushL( result );
+
+    TInt bufferLen = aMessage.GetDesMaxLength( 2 );
+    if ( result && result->Length() > bufferLen )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    TPtrC resultPtr = result->Des();
+    aMessage.WriteL( 2, resultPtr );
+    CleanupStack::PopAndDestroy( result );
+
+    OstTraceFunctionExit0( DUP1_CCMMSESSION_GETBEARERINFOSTRINGL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetBearerInfoString8L
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetBearerInfoString8L( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETBEARERINFOSTRING8L_ENTRY );
+
+    TUint32 bearerType( aMessage.Int0() );
+    TUint32 attribute( aMessage.Int1() );
+
+    HBufC8* result = iCache.GetBearerInfoString8L( bearerType, attribute );
+    if ( !result )
+        {
+        OstTraceFunctionExit0( CCMMSESSION_GETBEARERINFOSTRING8L_EXIT );
+        return;
+        }
+    CleanupStack::PushL( result );
+
+    TInt bufferLen = aMessage.GetDesMaxLength( 2 );
+    if ( result && result->Length() > bufferLen )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    TPtrC8 resultPtr = result->Des();
+    aMessage.WriteL( 2, resultPtr );
+    CleanupStack::PopAndDestroy( result );
+
+    OstTraceFunctionExit0( DUP1_CCMMSESSION_GETBEARERINFOSTRING8L_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetConnMethodInfoIntL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetConnMethodInfoIntL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETCONNMETHODINFOINTL_ENTRY );
+
+    TUint32 cmId( aMessage.Int0() );
+    TUint32 attribute( aMessage.Int1() );
+
+    TUint32 result = iCache.GetConnectionMethodInfoIntL( cmId, attribute );
+    TPckg<TUint32> resultPckg( result );
+    aMessage.WriteL( 2, resultPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETCONNMETHODINFOINTL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetConnMethodInfoBoolL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetConnMethodInfoBoolL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETCONNMETHODINFOBOOLL_ENTRY );
+
+    TUint32 cmId( aMessage.Int0() );
+    TUint32 attribute( aMessage.Int1() );
+
+    TBool result = iCache.GetConnectionMethodInfoBoolL( cmId, attribute );
+    TPckg<TBool> resultPckg( result );
+    aMessage.WriteL( 2, resultPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETCONNMETHODINFOBOOLL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetConnMethodInfoStringL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetConnMethodInfoStringL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETCONNMETHODINFOSTRINGL_ENTRY );
+
+    TUint32 cmId( aMessage.Int0() );
+    TUint32 attribute( aMessage.Int1() );
+
+    HBufC* result = iCache.GetConnectionMethodInfoStringL( cmId, attribute );
+    if ( !result )
+        {
+        OstTraceFunctionExit0( CCMMSESSION_GETCONNMETHODINFOSTRINGL_EXIT );
+        return;
+        }
+    CleanupStack::PushL( result );
+
+    TInt bufferLen = aMessage.GetDesMaxLength( 2 );
+    if ( result && result->Length() > bufferLen )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    TPtrC resultPtr = result->Des();
+    aMessage.WriteL( 2, resultPtr );
+    CleanupStack::PopAndDestroy( result );
+
+    OstTraceFunctionExit0( DUP1_CCMMSESSION_GETCONNMETHODINFOSTRINGL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetConnMethodInfoString8L
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetConnMethodInfoString8L( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETCONNMETHODINFOSTRING8L_ENTRY );
+
+    TUint32 cmId( aMessage.Int0() );
+    TUint32 attribute( aMessage.Int1() );
+
+    HBufC8* result = iCache.GetConnectionMethodInfoString8L( cmId, attribute );
+    if ( !result )
+        {
+        OstTraceFunctionExit0( CCMMSESSION_GETCONNMETHODINFOSTRING8L_EXIT );
+        return;
+        }
+    CleanupStack::PushL( result );
+
+    TInt bufferLen = aMessage.GetDesMaxLength( 2 );
+    if ( result && result->Length() > bufferLen )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    TPtrC8 resultPtr = result->Des();
+    aMessage.WriteL( 2, resultPtr );
+    CleanupStack::PopAndDestroy( result );
+
+    OstTraceFunctionExit0( DUP1_CCMMSESSION_GETCONNMETHODINFOSTRING8L_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetConnMethodArrayL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetConnMethodArrayL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETCONNMETHODARRAYL_ENTRY );
+
+    // Read attribute flags from client request.
+    TPckgBuf<TCmmIpcStructGetConnMethods> parametersPckg;
+    aMessage.ReadL( 0, parametersPckg );
+    TCmmIpcStructGetConnMethods attributes = parametersPckg();
+
+    // Create connection method ID array.
+    RArray<TUint32> cmArray;
+    CleanupClosePushL( cmArray );
+    iCache.GetAllConnMethodsL( cmArray, attributes.iCheckBearerType );
+
+    // Check if only legacy connection methods are needed.
+    if ( attributes.iLegacyOnly )
+        {
+        // Remove all referenced connection methods.
+        for ( TInt i = cmArray.Count() - 1; i >= 0; i-- )
+            {
+            if ( iCache.DestinationsContainingConnMethod( cmArray[i] ) )
+                {
+                cmArray.Remove( i );
+                }
+            }
+        }
+
+    // EasyWLAN handling.
+    if ( !attributes.iEasyWlan )
+        {
+        // If there is an EasyWLAN IAP, the ID needs to be removed from the array.
+        TUint32 easyWlanId = iCache.EasyWlanIdL();
+        if ( easyWlanId != 0 )
+            {
+            TInt index = cmArray.Find( easyWlanId );
+            if ( index != KErrNotFound )
+                {
+                cmArray.Remove( index );
+                }
+            }
+        }
+
+    // Check connection method ID count.
+    TInt connMethodCount = cmArray.Count();
+    if ( connMethodCount > aMessage.GetDesMaxLengthL( 2 ) )
+        {
+        // Client buffer is too small to contain all the informarmation. Return
+        // without any answer and the client side will ask again using a bigger
+        // buffer.
+        CleanupStack::PopAndDestroy( &cmArray );
+        return;
+        }
+
+    TPckg<TInt> countPckg( connMethodCount );
+    aMessage.WriteL( 1, countPckg );
+
+    if ( connMethodCount == 0 )
+        {
+        CleanupStack::PopAndDestroy( &cmArray );
+        return;
+        }
+
+    // Write connection method IDs to client.
+    HBufC8* idBuf = HBufC8::NewLC( connMethodCount );
+    TPtr8 bufPtr( idBuf->Des() );
+    for ( TInt i = 0; i < connMethodCount; i++ )
+        {
+        bufPtr.Append( (TUint8)( cmArray[i] & 0x000000FF ) );
+        }
+    aMessage.WriteL( 2, bufPtr );
+
+    CleanupStack::PopAndDestroy( idBuf );
+    CleanupStack::PopAndDestroy( &cmArray );
+
+    OstTraceFunctionExit0( DUP1_CCMMSESSION_GETCONNMETHODARRAYL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetAllDestinationsL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetAllDestinationsL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETALLDESTINATIONSL_ENTRY );
+
+    TInt destCount = iCache.GetDestinationCount();
+    if ( destCount > aMessage.GetDesMaxLengthL( 1 ) )
+        {
+        // Client buffer is too small to contain all the informarmation. Return
+        // without any answer and the client side will ask again using a bigger
+        // buffer.
+        return;
+        }
+
+    // Write the destination count to client.
+    TPckg<TInt> countPckg( destCount );
+    aMessage.WriteL( 0, countPckg );
+
+    if ( destCount == 0 )
+        {
+        return;
+        }
+
+    // Get the destination IDs from database cache.
+    RArray<TUint32> destArray;
+    CleanupClosePushL( destArray );
+    iCache.GetDestinationsL( destArray );
+
+    HBufC16* idBuf = HBufC16::NewLC( destCount );
+    TPtr16 bufPtr( idBuf->Des() );
+    for ( TInt i = 0; i < destCount; i++ )
+        {
+        bufPtr.Append( destArray[i] );
+        }
+
+    // Write the destination IDs to client.
+    aMessage.WriteL( 1, bufPtr );
+
+    CleanupStack::PopAndDestroy( idBuf );
+    CleanupStack::PopAndDestroy( &destArray );
+
+    OstTraceFunctionExit0( DUP1_CCMMSESSION_GETALLDESTINATIONSL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetEasyWLANIdL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetEasyWLANIdL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETEASYWLANIDL_ENTRY );
+
+    TUint32 id = iCache.EasyWlanIdL();
+    TPckg<TUint32> idPckg( id );
+    aMessage.WriteL( 0, idPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETEASYWLANIDL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetSupportedBearersL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetSupportedBearersL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETSUPPORTEDBEARERSL_ENTRY );
+
+    // Get the supported bearer types.
+    RArray<TUint32> bearerArray;
+    CleanupClosePushL( bearerArray );
+    iServer.CmManager()->SupportedBearersL( bearerArray );
+
+    // Write bearer count to client.
+    TInt bearerCount( bearerArray.Count() );
+    TInt neededBufferSize( bearerCount * sizeof( TUint32 ) );
+    TPckg<TInt> countPckg( bearerCount );
+    aMessage.WriteL( 0, countPckg );
+
+    // Check the client buffer size.
+    if ( neededBufferSize > aMessage.GetDesMaxLengthL( 1 ) || bearerCount == 0 )
+        {
+        // Client buffer is too small to contain all the information. Return
+        // with only the bearer count information and the client side will ask
+        // again using a big enough buffer.
+        CleanupStack::PopAndDestroy( &bearerArray );
+        return;
+        }
+
+    // Add the bearer types into a buffer.
+    HBufC8* bearerBuf = HBufC8::NewLC( neededBufferSize );
+    TPtr8 ptr( bearerBuf->Des() );
+    for ( TInt i = 0; i < bearerCount; i++ )
+        {
+        TUint32 a( bearerArray[i] );
+        ptr.Append( (TUint8*)&a, 4 );
+        }
+
+    // Write the bearer types to client.
+    aMessage.WriteL( 1, ptr );
+
+    CleanupStack::PopAndDestroy( bearerBuf );
+    CleanupStack::PopAndDestroy( &bearerArray );
+
+    OstTraceFunctionExit0( DUP1_CCMMSESSION_GETSUPPORTEDBEARERSL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::ReadDefaultConnectionL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::ReadDefaultConnectionL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_READDEFAULTCONNECTIONL_ENTRY );
+
+    // Default connection is now simply the internet destination.
+    TCmDefConnValue defaultConnection;
+    defaultConnection.iType = ECmDefConnDestination;
+    defaultConnection.iId = 0;
+
+    iCache.InternetDestinationIdL( defaultConnection.iId );
+    if ( defaultConnection.iId == 0 )
+        {
+        User::Leave( KErrNotFound );
+        }
+
+    TPckgBuf<TCmDefConnValue> dcPckgBuf( defaultConnection );
+    aMessage.WriteL( 0, dcPckgBuf );
+
+    OstTraceFunctionExit0( CCMMSESSION_READDEFAULTCONNECTIONL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::ReadGenConnSettingsL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::ReadGenConnSettingsL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_READGENCONNSETTINGSL_ENTRY );
+
+    TCmGenConnSettings genConnSettings;
+    iCache.ReadGenConnSettingsL( genConnSettings );
+
+    TPckgBuf<TCmGenConnSettings> genConnSettingsPckgBuf( genConnSettings );
+    aMessage.WriteL( 0, genConnSettingsPckgBuf );
+
+    OstTraceFunctionExit0( CCMMSESSION_READGENCONNSETTINGSL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::WriteGenConnSettingsL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::WriteGenConnSettingsL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_WRITEGENCONNSETTINGSL_ENTRY );
+
+    // Read data from client request.
+    TPckgBuf<TCmGenConnSettings> genConnSettingsPckgBuf;
+    aMessage.ReadL( 0, genConnSettingsPckgBuf );
+    TCmGenConnSettings genConnSettings = genConnSettingsPckgBuf();
+
+    iCache.WriteGenConnSettingsL( genConnSettings );
+
+    OstTraceFunctionExit0( CCMMSESSION_WRITEGENCONNSETTINGSL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetBearerPriorityArrayL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetBearerPriorityArrayL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETBEARERPRIORITYARRAYL_ENTRY );
+
+    const TInt maxLength( aMessage.GetDesMaxLengthL( 0 ) );
+    if ( maxLength < 2 )
+        {
+        // Minimum length of 2 is needed to store count and needed length.
+        User::Leave( KErrArgument );
+        }
+
+    RPointerArray<CCmmBearerPriority> bearerPriorityArray;
+    CmmCleanupResetAndDestroyPushL( bearerPriorityArray );
+
+    iCache.CopyBearerPriorityArrayL( bearerPriorityArray );
+    const TInt bearerCountInArray( bearerPriorityArray.Count() );
+    TInt bearerCount( bearerCountInArray );
+
+    TInt maxBufLen( 2 );
+    // Check the length needed for serializing.
+    for ( TInt i = 0; i < bearerCountInArray; i++ )
+        {
+        // Skip if service type is not valid.
+        if ( bearerPriorityArray[i]->ServiceType() && bearerPriorityArray[i]->ServiceType()->Length() > 0 )
+            {
+            maxBufLen += KCmmBearerPriorityHeaderLength; // Priorities and servicetype length.
+            maxBufLen += bearerPriorityArray[i]->ServiceType()->Length();
+            }
+        else
+            {
+            bearerCount--;
+            }
+        }
+
+    // If given buffer is shorter than needed, just write count and needed length.
+    if ( maxBufLen > maxLength )
+        {
+        HBufC* buffer = HBufC::NewLC( KCmmDefaultBearerPriorityArraySize );
+        TPtr bufferPtr( buffer->Des() );
+
+        bufferPtr.Append( bearerCount );
+        bufferPtr.Append( maxBufLen );
+        aMessage.WriteL( 0, bufferPtr );
+
+        CleanupStack::PopAndDestroy( buffer );
+        CleanupStack::PopAndDestroy( &bearerPriorityArray );
+        OstTraceFunctionExit0( CCMMSESSION_GETBEARERPRIORITYARRAYL_EXIT );
+        return;
+        }
+
+    // Add needed buffer + space for bearerCount and maxlength.
+    HBufC* buffer = HBufC::NewLC( maxBufLen );
+    TPtr bufferPtr( buffer->Des() );
+
+    // Write count and bufmaxLen.
+    bufferPtr.Append( bearerCount );
+    bufferPtr.Append( maxBufLen );
+
+    for ( TInt i = 0; i < bearerCountInArray; i++ )
+        {
+        // Skip if service type is not valid.
+        if ( bearerPriorityArray[i]->ServiceType() && bearerPriorityArray[i]->ServiceType()->Length() > 0 )
+            {
+            TUint32 priority = bearerPriorityArray[i]->Priority();
+            TUint32 uiPriority = bearerPriorityArray[i]->UiPriority();
+            const HBufC* serviceType = bearerPriorityArray[i]->ServiceType();
+
+            bufferPtr.Append( priority >> KBitsInTwoBytes );
+            bufferPtr.Append( priority & 0x0000FFFF );
+            bufferPtr.Append( uiPriority >> KBitsInTwoBytes );
+            bufferPtr.Append( uiPriority & 0x0000FFFF );
+
+            const TInt stringLength = serviceType->Length();
+            bufferPtr.Append( stringLength );
+            bufferPtr.Append( *serviceType );
+            }
+        }
+    aMessage.WriteL( 0, bufferPtr );
+
+    CleanupStack::PopAndDestroy( buffer );
+    CleanupStack::PopAndDestroy( &bearerPriorityArray );
+
+    OstTraceFunctionExit0( DUP1_CCMMSESSION_GETBEARERPRIORITYARRAYL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::UpdateBearerPriorityArrayL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::UpdateBearerPriorityArrayL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_UPDATEBEARERPRIORITYARRAYL_ENTRY );
+
+    HBufC* bearerPriorityBuf = HBufC::NewLC( aMessage.GetDesMaxLengthL( 0 ) );
+    TPtr bearerPriorityBufPtr( bearerPriorityBuf->Des() );
+
+    aMessage.ReadL( 0, bearerPriorityBufPtr );
+
+    const TInt bearerCount = bearerPriorityBufPtr[0];
+    if ( ( bearerCount < 1 ) || ( aMessage.GetDesMaxLengthL( 0 ) < 2 ) )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    RPointerArray<CCmmBearerPriority> bearerPriorityArray;
+    CmmCleanupResetAndDestroyPushL( bearerPriorityArray );
+
+    TInt position( 2 ); // Start of first priority item.
+    for ( TInt i = 0; i < bearerCount; i++ )
+        {
+        TUint32 priority;
+        TUint32 uiPriority;
+        priority = bearerPriorityBufPtr[position] << KBitsInTwoBytes;
+        position++;
+        priority += bearerPriorityBufPtr[position];
+        position++;
+        uiPriority = bearerPriorityBufPtr[position] << KBitsInTwoBytes;
+        position++;
+        uiPriority += bearerPriorityBufPtr[position];
+        position++;
+        const TInt stringLength = bearerPriorityBufPtr[position];
+        position++;
+        if ( stringLength <= 0 )
+            {
+            User::Leave( KErrArgument );
+            }
+        else
+            {
+            HBufC* serviceName = HBufC::NewLC( stringLength );
+            serviceName->Des().Append( &( bearerPriorityBufPtr[position] ), stringLength );
+            position += stringLength;
+
+            TPtrC tempServiceType( serviceName->Des() );
+            CCmmBearerPriority* item = CCmmBearerPriority::NewLC( tempServiceType, priority, uiPriority );
+            bearerPriorityArray.AppendL( item );
+            CleanupStack::Pop( item );
+
+            CleanupStack::PopAndDestroy( serviceName );
+            }
+        }
+
+    // Update bearer priority array
+    iCache.UpdateBearerPriorityArrayL( bearerPriorityArray );
+
+    CleanupStack::PopAndDestroy( &bearerPriorityArray );
+    CleanupStack::PopAndDestroy( bearerPriorityBuf );
+
+    OstTraceFunctionExit0( CCMMSESSION_UPDATEBEARERPRIORITYARRAYL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Copies a connection method into a destination. If the connection method is
+// in any other destination, it becomes shared. Calls update on the target
+// destination.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::CopyConnMethodL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_COPYCONNMETHODL_ENTRY );
+
+    CCmmDestinationInstance* destination = ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int0() );
+    CCmmConnMethodInstance* connMethod = ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int1() );
+
+    // Can't add an embedded destination this way.
+    if ( connMethod->IsEmbeddedDestination() )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    //TODO, capability check, what to do if anything is protected.
+
+    // Add connection method into destination.
+    TInt index = destination->AddConnMethodL( *connMethod );
+
+    // Update destination into database.
+    destination->UpdateL();
+
+    // Write the connection method index (priority) inside the destination to client.
+    TPckg<TInt> indexPckg( index );
+    aMessage.WriteL( 2, indexPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_COPYCONNMETHODL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Moves a connection method from one destination to another. Calls update on
+// both the source and target destinations (which also updates the connection
+// method).
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::MoveConnMethodL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_MOVECONNMETHODL_ENTRY );
+
+    // Read data from client request.
+    TPckgBuf<TCmmIpcStructMoveConnMethod> attributesPckg;
+    aMessage.ReadL( 0, attributesPckg );
+    TCmmIpcStructMoveConnMethod attributes = attributesPckg();
+
+    CCmmDestinationInstance* sourceDestination =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( attributes.iSourceDestHandle );
+    CCmmDestinationInstance* targetDestination =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( attributes.iTargetDestHandle );
+    CCmmConnMethodInstance* connMethod =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( attributes.iConnMethodHandle );
+    TUint32 connMethodId( connMethod->GetId() );
+
+    // Can't add an embedded destination this way.
+    if ( connMethod->IsEmbeddedDestination() )
+        {
+        User::Leave( KErrArgument );
+        }
+    // Check if the connection method is in the source destination.
+    if ( !sourceDestination->ValidConnMethodIdInDestinationIncludeEmbedded( connMethodId ) )
+        {
+        User::Leave( KErrNotFound );
+        }
+    // Check if the connection method is already in the target destination.
+    if ( targetDestination->ValidConnMethodIdInDestinationIncludeEmbedded( connMethodId ) )
+        {
+        User::Leave( KErrAlreadyExists );
+        }
+    // Check if the connection method can be removed from the source destination.
+    if ( sourceDestination->ConnMethodInDestinationButLocked( connMethodId ) )
+        {
+        User::Leave( KErrLocked );
+        }
+    // Check that the connection method is not in use by an active connection.
+    if ( iCache.CheckIfCmConnected( connMethodId ) )
+        {
+        User::Leave( KErrInUse );
+        }
+
+    //TODO, capability checks, what to do if anything is protected.
+
+    // Add connection method into target destination and update it.
+    attributesPckg().iIndex = targetDestination->AddConnMethodL( *connMethod );
+    targetDestination->UpdateL();
+
+    // Remove connection method from source destination and update it.
+    sourceDestination->RemoveConnMethodFromDestinationL( *connMethod, EFalse ); // EFalse to not check connected state again.
+    sourceDestination->UpdateL();
+
+    // Write the index (priority) back to client.
+    aMessage.WriteL( 0, attributesPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_MOVECONNMETHODL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Remove a connection method froma destination. Does not call update on the
+// affected destination.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::RemoveConnMethodL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_REMOVECONNMETHODL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int0() );
+    CCmmConnMethodInstance* connMethodInstance =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int1() );
+
+    //TODO, capability checks
+
+    destinationInstance->RemoveConnMethodFromDestinationL( *connMethodInstance );
+    destinationInstance->UpdateL();
+
+    OstTraceFunctionExit0( CCMMSESSION_REMOVECONNMETHODL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Removes a connection method from every destination and make it uncategorized.
+// Updates any destination that contains the connection method.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::RemoveAllReferencesL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_REMOVEALLREFERENCESL_ENTRY );
+
+    CCmmConnMethodInstance* connMethodInstance =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int0() );
+
+    iCache.CheckIfConnMethodReferencesCanBeRemovedL( *connMethodInstance );
+    iCache.RemoveAllReferencesToConnMethodL( *connMethodInstance );
+
+    OstTraceFunctionExit0( CCMMSESSION_REMOVEALLREFERENCESL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::ServiceDestinationL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::ServiceDestinationL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_SERVICEDESTINATIONL_ENTRY );
+
+    switch ( aMessage.Function() )
+        {
+        case EDestGetDestination:
+            {
+            GetDestinationL( aMessage );
+            }
+            break;
+        case EDestRefresh:
+            {
+            RefreshDestinationL( aMessage );
+            }
+            break;
+        case EDestCreateDestinationWithName:
+            {
+            CreateDestinationWithNameL( aMessage );
+            }
+            break;
+        case EDestCreateDestinationWithNameAndId:
+            {
+            CreateDestinationWithNameAndIdL( aMessage );
+            }
+            break;
+        case EDestCloseDestination:
+            {
+            CloseDestination( aMessage );
+            }
+            break;
+        case EDestGetConnMethodCount:
+            {
+            GetConnectionMehodCountL( aMessage );
+            }
+            break;
+        case EDestGetConnMethodPriority:
+            {
+            GetConnMethodPriorityL( aMessage );
+            }
+            break;
+        case EDestGetName:
+            {
+            GetDestinationNameL( aMessage );
+            }
+            break;
+        case EDestGetId:
+            {
+            GetDestinationIdL( aMessage );
+            }
+            break;
+        case EDestGetElementId:
+            {
+            GetDestinationElementIdL( aMessage );
+            }
+            break;
+        case EDestMetadata:
+            {
+            GetDestinationMetadataL( aMessage );
+            }
+            break;
+        case EDestGetProtectionLevel:
+            {
+            GetDestinationProtectionLevelL( aMessage );
+            }
+            break;
+        case EDestIsConnected:
+            {
+            IsDestinationConnectedL( aMessage );
+            }
+            break;
+        case EDestIsHidden:
+            {
+            IsDestinationHiddenL( aMessage );
+            }
+            break;
+        case EDestIsEqual:
+            {
+            DestinationIsEqualL( aMessage );
+            }
+            break;
+        case EDestAddConnMethod:
+            {
+            DestAddConnMethodL( aMessage );
+            }
+            break;
+        case EDestAddEmbeddedDestination:
+            {
+            DestAddEmbeddedDestinationL( aMessage );
+            }
+            break;
+        case EDestDeleteConnMethod:
+            {
+            DestDeleteConnMethodL( aMessage );
+            }
+            break;
+        case EDestRemoveConnMethod:
+            {
+            DestRemoveConnMethodL( aMessage );
+            }
+            break;
+        case EDestModifyPriority:
+            {
+            ModifyConnMethodPriorityL( aMessage );
+            }
+            break;
+        case EDestSetName:
+            {
+            SetDestinationNameL( aMessage );
+            }
+            break;
+        case EDestSetMetadata:
+            {
+            SetDestinationMetadataL( aMessage );
+            }
+            break;
+        case EDestSetProtection:
+            {
+            SetDestinationProtectionL( aMessage );
+            }
+            break;
+        case EDestSetHidden:
+            {
+            SetDestinationHiddenL( aMessage );
+            }
+            break;
+        case EDestUpdate:
+            {
+            UpdateDestinationL( aMessage );
+            }
+            break;
+        case EDestDelete:
+            {
+            DeleteDestinationL( aMessage );
+            }
+            break;
+        default:
+            {
+            User::Leave( KErrNotSupported );
+            }
+            break;
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_SERVICEDESTINATIONL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetDestinationL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetDestinationL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETDESTINATIONL_ENTRY );
+
+    // Structure:
+    // - Check arguments.
+    // - Create session instance.
+    // - Ask cache to open/create target and put data to session instance.
+    // - Create subsession and complete message.
+
+    // API side checks that ID is between 0x1000 - 0x1100, and converts if necessary.
+    TUint32 destinationId( aMessage.Int0() );
+
+    // Check that the ID is in valid range.
+    if ( destinationId <= KCmDefaultDestinationAPTagId ||
+            destinationId >= KCmMaxDestinationAPTagId )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    // Check if a destination with given ID exists.
+    if ( !iCache.DestinationExistsWithId( destinationId ) )
+        {
+        User::Leave( KErrNotFound );
+        }
+
+    // If this session already has a destination with matching ID open, provide
+    // the client with a reference to the already opened handle.
+    CCmmDestinationInstance* destinationInstance = FindDestinationInstanceById( destinationId );
+    if ( destinationInstance )
+        {
+        TPckg<TInt> existingHandlePckg( destinationInstance->GetHandle() );
+        aMessage.WriteL( 1, existingHandlePckg );
+        User::Leave( KErrAlreadyExists );
+        }
+    destinationInstance = NULL;
+    TPckg<TInt> existingHandlePckg( 0 );
+    aMessage.WriteL( 1, existingHandlePckg );
+
+    destinationInstance = CCmmDestinationInstance::NewLC( this, &iCache );
+
+    // Cache will open a handle to the destination if not already open, and
+    // copy relevant data into this destination instance.
+    iCache.OpenDestinationL( *destinationInstance, destinationId );
+
+    iDestinationContainer->AddL( ( CObject* ) destinationInstance );
+    TInt handle = iDestinationObjects->AddL( ( CObject* ) destinationInstance );
+    destinationInstance->SetHandle( handle );
+    CleanupStack::Pop( destinationInstance );
+
+    TPckg<TInt> handlePckg( handle );
+    TInt err = aMessage.Write( 3, handlePckg );
+    if ( err )
+        {
+        // Removes from object index and destroys the object.
+        iDestinationObjects->Remove( handle );
+        User::Leave( err );
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_GETDESTINATIONL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::RefreshDestinationL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::RefreshDestinationL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_REFRESHDESTINATIONL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    iCache.RefreshDestinationL( *destinationInstance );
+
+    OstTraceFunctionExit0( CCMMSESSION_REFRESHDESTINATIONL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::CreateDestinationWithNameL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::CreateDestinationWithNameL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_CREATEDESTINATIONWITHNAMEL_ENTRY );
+
+    // Structure:
+    // - Check arguments.
+    // - Create session instance.
+    // - Ask cache to open/create target and put data to session instance.
+    // - Create subsession and complete message.
+
+    // Load and check name.
+    TInt destNameLength = aMessage.GetDesLength( 0 );
+    if ( destNameLength <= 0 )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    HBufC* destinationName = HBufC::NewLC( destNameLength );
+    TPtr ptrDestinationName = destinationName->Des();
+    aMessage.ReadL( 0, ptrDestinationName );
+
+    // Check if a destination with given name exists (or is already created but not yet saved).
+    if ( iCache.DestinationExistsWithNameL( *destinationName, 0 ) ||
+            iCache.NotSavedDestinationOpenWithNameL( *destinationName, 0 ) )
+        {
+        User::Leave( KErrAlreadyExists );
+        }
+
+    CCmmDestinationInstance* destinationInstance = CCmmDestinationInstance::NewLC( this, &iCache );
+
+    // Create a temporary ID to be used until a real one is obtained from the database.
+    TUint32 temporaryId = iCache.NextFreeTemporaryId();
+
+    // Cache will create the destination data structure and copy the relevant
+    // data to the session instance.
+    iCache.CreateDestinationL( *destinationInstance, *destinationName, temporaryId );
+
+    iDestinationContainer->AddL( ( CObject* ) destinationInstance );
+    TInt handle = iDestinationObjects->AddL( ( CObject* ) destinationInstance );
+    destinationInstance->SetHandle( handle );
+    CleanupStack::Pop( destinationInstance );
+    CleanupStack::PopAndDestroy( destinationName );
+
+    TPckg<TInt> handlePckg( handle );
+    TInt err = aMessage.Write( 3, handlePckg );
+    if ( err )
+        {
+        // Removes from object index and destroys the object.
+        iDestinationObjects->Remove( handle );
+        User::Leave( err );
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_CREATEDESTINATIONWITHNAMEL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::CreateDestinationWithNameAndIdL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::CreateDestinationWithNameAndIdL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_CREATEDESTINATIONWITHNAMEANDIDL_ENTRY );
+
+    // Structure:
+    // - Check arguments.
+    // - Create session instance.
+    // - Ask cache to open/create target and put data to session instance.
+    // - Create subsession and complete message.
+
+    // API side checks that ID is between 0x1000 - 0x1100, and converts if necessary.
+    TUint32 destinationId( (TUint32)aMessage.Int1() );
+
+    // Check that the ID is in valid range.
+    if ( destinationId <= KCmDefaultDestinationAPTagId ||
+            destinationId >= KCmMaxDestinationAPTagId )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    // Check if a destination with given ID exists (or is already created but not saved).
+    if ( iCache.DestinationExistsWithId( destinationId ) ||
+            iCache.DestinationOpenWithId( destinationId ) )
+        {
+        User::Leave( KErrAlreadyExists );
+        }
+
+    // Load and check name.
+    TInt destNameLength = aMessage.GetDesLength( 0 );
+    if ( destNameLength <= 0 )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    HBufC* destinationName = HBufC::NewLC( destNameLength );
+
+    TPtr ptrDestinationName = destinationName->Des();
+    aMessage.ReadL( 0, ptrDestinationName );
+
+    // Check if a destination with given name exists (or is already created but not yet saved).
+    if ( iCache.DestinationExistsWithNameL( *destinationName, 0 ) ||
+            iCache.NotSavedDestinationOpenWithNameL( *destinationName, 0 ) )
+        {
+        User::Leave( KErrAlreadyExists );
+        }
+
+    CCmmDestinationInstance* destinationInstance = CCmmDestinationInstance::NewLC( this, &iCache );
+
+    // Cache will create the destination data structure and copy the relevant
+    // data to the session instance.
+    iCache.CreateDestinationL( *destinationInstance, *destinationName, destinationId );
+
+    iDestinationContainer->AddL( ( CObject* ) destinationInstance );
+    TInt handle = iDestinationObjects->AddL( ( CObject* ) destinationInstance );
+    destinationInstance->SetHandle( handle );
+    CleanupStack::Pop( destinationInstance );
+    CleanupStack::PopAndDestroy( destinationName );
+
+    TPckg<TInt> handlePckg( handle );
+    TInt err = aMessage.Write( 3, handlePckg );
+    if ( err )
+        {
+        // Removes from object index and destroys the object.
+        iDestinationObjects->Remove( handle );
+        User::Leave( err );
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_CREATEDESTINATIONWITHNAMEANDIDL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::CloseDestinationL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::CloseDestination( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_CLOSEDESTINATION_ENTRY );
+
+    // Check first that the destination instance exists.
+    CObject* destinationObject = iDestinationObjects->At( aMessage.Int3() );
+    if ( destinationObject )
+        {
+        // Destination instance destructor will notify cache.
+        iDestinationObjects->Remove( aMessage.Int3() );
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_CLOSEDESTINATION_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Return the connection method count from the provided destination.
+// Embedded destinations are included.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetConnectionMehodCountL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETCONNECTIONMEHODCOUNTL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    TInt connMethodCount( destinationInstance->iConnMethodItemArray.Count() ); // Includes embedded destinations.
+
+    TPckg<TInt> countPckg( connMethodCount );
+    aMessage.WriteL( 0, countPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETCONNECTIONMEHODCOUNTL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetConnMethodPriorityL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetConnMethodPriorityL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETCONNMETHODPRIORITYL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    CCmmConnMethodInstance* connMethodInstance =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int0() );
+    TUint32 connMethodId = connMethodInstance->GetId();
+
+    TInt index( KErrNotFound );
+    for ( TInt i = 0; i < destinationInstance->iConnMethodItemArray.Count(); i++ )
+        {
+        if ( destinationInstance->iConnMethodItemArray[i].iId == connMethodId )
+            {
+            // Index in the connection method array is the connection method
+            // priority. But priority starts from 1, so adjust by +1.
+            index = i + 1;
+            break;
+            }
+        }
+
+    // Leave if given connection method is not inside this destination.
+    User::LeaveIfError( index );
+
+    // Check if the connection method is an embedded destination.
+    if ( connMethodInstance->GetBearerType() == KUidEmbeddedDestination )
+        {
+        index = CMManager::KDataMobilitySelectionPolicyPriorityWildCard;
+        }
+
+    //TODO, what if CM is virtual?
+
+    TUint priority = ( TUint )index;
+    TPckg<TUint> priorityPckg( priority );
+    aMessage.WriteL( 1, priorityPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETCONNMETHODPRIORITYL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetDestinationNameL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetDestinationNameL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETDESTINATIONNAMEL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    HBufC* name = destinationInstance->GetLocalisedDestinationNameL();
+    CleanupStack::PushL( name );
+    TPtrC namePtr( name->Des() );
+
+    TInt bufferLen = aMessage.GetDesMaxLength( 0 );
+    if ( namePtr.Length() > bufferLen )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    aMessage.WriteL( 0, namePtr );
+
+    CleanupStack::PopAndDestroy( name );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETDESTINATIONNAMEL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetDestinationIdL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetDestinationIdL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETDESTINATIONIDL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    TUint32 id = destinationInstance->GetRecordTagFromApRecordL();
+    TPckg<TUint32> idPckg( id );
+    aMessage.WriteL( 0, idPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETDESTINATIONIDL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetDestinationElementIdL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetDestinationElementIdL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETDESTINATIONELEMENTIDL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    TUint32 elementId = destinationInstance->GetElementIdL();
+    TPckg<TUint32> elementIdPckg( elementId );
+    aMessage.WriteL( 0, elementIdPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETDESTINATIONELEMENTIDL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetDestinationMetadataL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetDestinationMetadataL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETDESTINATIONMETADATAL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+    CMManager::TSnapMetadataField metadataField =
+            ( CMManager::TSnapMetadataField )aMessage.Int0();
+
+    TUint32 metadata( 0 );
+    destinationInstance->GetMetadataL( metadataField, metadata );
+
+    TPckg<TUint32> metadataPckg( metadata );
+    aMessage.WriteL( 1, metadataPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETDESTINATIONMETADATAL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetDestinationProtectionLevelL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetDestinationProtectionLevelL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETDESTINATIONPROTECTIONLEVELL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    CMManager::TProtectionLevel protLevel( CMManager::EProtLevel0 );
+    destinationInstance->GetProtectionL( protLevel );
+
+    TPckg<TInt> protLevelPckg( protLevel );
+    aMessage.WriteL( 0, protLevelPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETDESTINATIONPROTECTIONLEVELL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::IsDestinationConnectedL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::IsDestinationConnectedL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_ISDESTINATIONCONNECTEDL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    if ( !iCache.DestinationExistsWithId( destinationInstance->GetId() ) )
+        {
+        User::Leave( KErrNotFound );
+        }
+
+    TBool isConnected = iCache.DestinationConnectedL( destinationInstance->GetId() );
+    TPckg<TBool> isConnectedPckg( isConnected );
+    aMessage.WriteL( 0, isConnectedPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_ISDESTINATIONCONNECTEDL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::IsDestinationHiddenL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::IsDestinationHiddenL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_ISDESTINATIONHIDDENL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    TUint32 isHiddenMetadata( 0 );
+    destinationInstance->GetMetadataL( CMManager::ESnapMetadataHiddenAgent, isHiddenMetadata );
+
+    TBool isHidden( EFalse );
+    if ( isHiddenMetadata )
+        {
+        isHidden = ETrue;
+        }
+
+    TPckg<TBool> isHiddenPckg( isHidden );
+    aMessage.WriteL( 0, isHiddenPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_ISDESTINATIONHIDDENL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Checks if the destination given as parameter is equal to this destination
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::DestinationIsEqualL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_DESTINATIONISEQUALL_ENTRY );
+
+    CCmmDestinationInstance* dest =
+        ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    CCmmDestinationInstance* destToBeCompared =
+        ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int0() );
+
+    TBool equal( EFalse );
+    if ( dest->GetId() == destToBeCompared->GetId() )
+        {
+        equal = ETrue;
+        }
+
+    TPckg<TBool> equalPckg( equal );
+
+    aMessage.WriteL( 1, equalPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_DESTINATIONISEQUALL_EXIT );
+    }
+
+
+// -----------------------------------------------------------------------------
+// Adds a connection method into a destination. Does not add embedded
+// destinations.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::DestAddConnMethodL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_DESTADDCONNMETHODL_ENTRY );
+
+    CCmmDestinationInstance* destination =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+    CCmmConnMethodInstance* connMethod =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int0() );
+
+    if ( connMethod->IsEmbeddedDestination() )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    TInt index = destination->AddConnMethodL( *connMethod );
+    TPckg<TInt> indexPckg( index );
+    aMessage.WriteL( 1, indexPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_DESTADDCONNMETHODL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Adds a destination into a destination as an embedded destination.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::DestAddEmbeddedDestinationL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_DESTADDEMBEDDEDDESTINATIONL_ENTRY );
+
+    CCmmDestinationInstance* destination =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+    CCmmDestinationInstance* embeddedDestination =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int0() );
+
+    TInt index = destination->AddEmbeddedDestinationL( *embeddedDestination );
+    TPckg<TInt> indexPckg( index );
+    aMessage.WriteL( 1, indexPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_DESTADDEMBEDDEDDESTINATIONL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::DestDeleteConnMethodL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::DestDeleteConnMethodL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_DESTDELETECONNMETHODL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+    CCmmConnMethodInstance* connMethodInstance =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int0() );
+
+    //TODO, capability checks
+
+    destinationInstance->DeleteConnMethodFromDestinationL( *connMethodInstance );
+
+    OstTraceFunctionExit0( CCMMSESSION_DESTDELETECONNMETHODL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::DestRemoveConnMethodL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::DestRemoveConnMethodL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_DESTREMOVECONNMETHODL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+    CCmmConnMethodInstance* connMethodInstance =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int0() );
+
+    //TODO, capability checks
+
+    destinationInstance->RemoveConnMethodFromDestinationL( *connMethodInstance );
+
+    OstTraceFunctionExit0( CCMMSESSION_DESTREMOVECONNMETHODL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::ModifyConnMethodPriorityL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::ModifyConnMethodPriorityL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_MODIFYCONNMETHODPRIORITYL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+    CCmmConnMethodInstance* connMethodInstance =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int0() );
+
+    //TODO, capability checks
+
+    // Index values start from 0 (0 meaning highest priority).
+    TUint index( ( TUint )aMessage.Int1() );
+
+    destinationInstance->ModifyConnMethodPriorityL( *connMethodInstance, index );
+
+    OstTraceFunctionExit0( CCMMSESSION_MODIFYCONNMETHODPRIORITYL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::SetDestinationNameL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::SetDestinationNameL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_SETDESTINATIONNAMEL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    // Load and check name.
+    TInt destNameLength = aMessage.GetDesLength( 0 );
+    if ( destNameLength <= 0 )
+        {
+        User::Leave( KErrArgument ); //TODO, check also max length?
+        }
+
+    HBufC* newName = HBufC::NewLC( destNameLength );
+    TPtr ptrNewName = newName->Des();
+    aMessage.ReadL( 0, ptrNewName );
+
+    // Check if a destination with given name exists (or is already created but not yet saved).
+    if ( iCache.DestinationExistsWithNameL( *newName, destinationInstance->GetId() ) ||
+            iCache.NotSavedDestinationOpenWithNameL( *newName, destinationInstance->GetId() ) )
+        {
+        User::Leave( KErrAlreadyExists );
+        }
+
+    destinationInstance->SetDestinationNameL( *newName );
+
+    CleanupStack::PopAndDestroy( newName );
+
+    OstTraceFunctionExit0( CCMMSESSION_SETDESTINATIONNAMEL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::SetDestinationMetadataL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::SetDestinationMetadataL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_SETDESTINATIONMETADATAL_ENTRY );
+
+    //TODO, Capability check. Protection level or Internet destination.
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    CMManager::TSnapMetadataField metadataField =
+            ( CMManager::TSnapMetadataField )aMessage.Int0();
+    TUint32 metadata = aMessage.Int1();
+
+    destinationInstance->SetMetadataL( metadataField, metadata );
+
+    OstTraceFunctionExit0( CCMMSESSION_SETDESTINATIONMETADATAL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::SetDestinationProtectionL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::SetDestinationProtectionL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_SETDESTINATIONPROTECTIONL_ENTRY );
+
+    //TODO, Capability check: ECapabilityNetworkControl
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+    CMManager::TProtectionLevel protLevel =
+            ( CMManager::TProtectionLevel )aMessage.Int0();
+    destinationInstance->SetProtectionL( protLevel );
+
+    OstTraceFunctionExit0( CCMMSESSION_SETDESTINATIONPROTECTIONL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::SetDestinationHiddenL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::SetDestinationHiddenL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_SETDESTINATIONHIDDENL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    TBool hidden = aMessage.Int0();
+    destinationInstance->SetMetadataL( CMManager::ESnapMetadataHiddenAgent, hidden );
+
+    OstTraceFunctionExit0( CCMMSESSION_SETDESTINATIONHIDDENL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::UpdateDestinationL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::UpdateDestinationL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_UPDATEDESTINATIONL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+    destinationInstance->UpdateL();
+
+    OstTraceFunctionExit0( CCMMSESSION_UPDATEDESTINATIONL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::DeleteDestinationL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::DeleteDestinationL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_DELETEDESTINATIONL_ENTRY );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( aMessage.Int3() );
+
+    iCache.CheckIfDestinationCanBeDeletedL( *destinationInstance );
+    iCache.DeleteDestinationL( *destinationInstance );
+
+    // Close the destination handle. Destination instance destructor will
+    // notify cache. If the reference count for the cache side handle goes to
+    // zero, it will be deleted.
+    iDestinationObjects->Remove( aMessage.Int3() );
+
+    OstTraceFunctionExit0( CCMMSESSION_DELETEDESTINATIONL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::ServiceConnMethodL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::ServiceConnMethodL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_SERVICECONNMETHODL_ENTRY );
+
+    switch ( aMessage.Function() )
+        {
+        case ECMCreateConnMethod:
+            {
+            CreateConnMethodL( aMessage );
+            }
+            break;
+        case ECMUpdate:
+            {
+            UpdateConnMethodL( aMessage );
+            }
+            break;
+        case ECMCloseConnMethod:
+            {
+            CloseConnMethod( aMessage ); // Can't leave.
+            }
+            break;
+        case ECMDelete:
+            {
+            DeleteConnMethodL( aMessage );
+            }
+            break;
+        case ECMGetConnMethodWithId:
+            {
+            GetConnMethodWithIdL( aMessage );
+            }
+            break;
+        case ECMRefresh:
+            {
+            RefreshConnMethodL( aMessage );
+            }
+            break;
+        case ECMGetIntAttribute:
+            {
+            GetIntAttributeL( aMessage );
+            }
+            break;
+        case ECMGetBoolAttribute:
+            {
+            GetBoolAttributeL( aMessage );
+            }
+            break;
+        case ECMGetStringAttribute:
+            {
+            GetStringAttributeL( aMessage );
+            }
+            break;
+        case ECMGetString8Attribute:
+            {
+            GetString8AttributeL( aMessage );
+            }
+            break;
+        case ECMSetIntAttribute:
+            {
+            SetIntAttributeL( aMessage );
+            }
+            break;
+        case ECMSetBoolAttribute:
+            {
+            SetBoolAttributeL( aMessage );
+            }
+            break;
+        case ECMSetStringAttribute:
+            {
+            SetStringAttributeL( aMessage );
+            }
+            break;
+        case ECMSetString8Attribute:
+            {
+            SetString8AttributeL( aMessage );
+            }
+            break;
+        case ECMCreateConnMethodWithId:
+            {
+            CreateConnMethodWithIdL( aMessage );
+            }
+            break;
+        case ECMGetConnMethodFromDestWithIndex:
+            {
+            GetConnMethodFromDestWithIndexL( aMessage );
+            }
+            break;
+        case ECMGetConnMethodFromDestWithId:
+            {
+            GetConnMethodFromDestWithIdL( aMessage );
+            }
+            break;
+        case ECMCreateConnMethodToDest:
+            {
+            CreateConnMethodToDestL( aMessage );
+            }
+            break;
+        case ECMCreateConnMethodToDestWithId:
+            {
+            CreateConnMethodToDestWithIdL( aMessage );
+            }
+            break;
+        case ECMIsEqual:
+            {
+            CmIsEqualL( aMessage );
+            }
+            break;
+        case ECMCreateCopyOfExisting:
+            {
+            CreateCopyOfExistingL( aMessage );
+            }
+            break;
+        case EDestGetEmbeddedDestination:
+            {
+            GetEmbeddedDestinationL( aMessage );
+            }
+            break;
+        default:
+            {
+            User::Leave( KErrNotSupported );
+            }
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_SERVICECONNMETHODL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Create a new connection method (not embedded destination).
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::CreateConnMethodL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_CREATECONNMETHODL_ENTRY );
+
+    TUint32 bearerType( aMessage.Int0() );
+
+    CCmmConnMethodInstance* connMethod = CCmmConnMethodInstance::NewLC( this, &iCache );
+    iCache.CreateConnMethodL( *connMethod, NULL, bearerType, 0 );
+
+    iConnMethodContainer->AddL( ( CObject* ) connMethod );
+    TInt handle = iConnMethodObjects->AddL( ( CObject* ) connMethod );
+    connMethod->SetHandle( handle );
+    CleanupStack::Pop( connMethod );
+
+    TPckg<TInt> handlePckg( handle );
+    TInt error = aMessage.Write( 3, handlePckg );
+    if ( error )
+        {
+        // Remove from object index and destroy the object.
+        iConnMethodObjects->Remove( handle );
+        User::Leave( error );
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_CREATECONNMETHODL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::ConnMethodUpdateL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::UpdateConnMethodL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_UPDATECONNMETHODL_ENTRY );
+
+    CCmmConnMethodInstance* connMethod =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int3() );
+    connMethod->UpdateL();
+
+    OstTraceFunctionExit0( CCMMSESSION_UPDATECONNMETHODL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::CloseConnMethod
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::CloseConnMethod( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_CLOSECONNMETHOD_ENTRY );
+
+    // Check first that the connection method instance exists.
+    CObject* connMethodObject = iConnMethodObjects->At( aMessage.Int3() );
+    if ( connMethodObject )
+        {
+        // Connection method instance destructor will notify cache.
+        iConnMethodObjects->Remove( aMessage.Int3() );
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_CLOSECONNMETHOD_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::ConnMethodUpdateL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::DeleteConnMethodL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_DELETECONNMETHODL_ENTRY );
+
+    CCmmConnMethodInstance* connMethodInstance =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int3() );
+
+    iCache.CheckIfConnMethodCanBeDeletedL( *connMethodInstance );
+    iCache.DeleteConnMethodL( *connMethodInstance );
+    // Ignore the boolean return value. It is always true, or the
+    // DeleteL()-call leaves.
+
+    // Close the connection method handle. Connection method instance
+    // destructor will notify cache. If the reference count for the cache side
+    // handle goes to zero, it will be deleted.
+    iConnMethodObjects->Remove( aMessage.Int3() );
+
+    OstTraceFunctionExit0( CCMMSESSION_DELETECONNMETHODL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetConnMethodWithIdL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetConnMethodWithIdL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETCONNMETHODWITHIDL_ENTRY );
+
+    TUint32 connMethodId = aMessage.Int0();
+
+    // If this session already has a connection method with matching id open,
+    // provide the client with a reference to the already opened handle.
+    CCmmConnMethodInstance* cmInstance = FindConnMethodInstanceById( connMethodId );
+    if ( cmInstance )
+        {
+        // Also check that the connection method exists in database.
+        if ( iCache.ConnMethodExistsWithId( connMethodId ) )
+            {
+            TPckg<TInt> existingHandlePckg( cmInstance->GetHandle() );
+            aMessage.WriteL( 1, existingHandlePckg );
+            User::Leave( KErrAlreadyExists );
+            }
+        }
+    cmInstance = NULL;
+    TPckg<TInt> existingHandlePckg( 0 );
+    aMessage.WriteL( 1, existingHandlePckg );
+
+    cmInstance = CCmmConnMethodInstance::NewLC( this, &iCache );
+    // Will check if connection method ID is valid.
+    iCache.OpenConnMethodL( *cmInstance, NULL, connMethodId );
+
+    iConnMethodContainer->AddL( ( CObject* ) cmInstance );
+    TInt handle = iConnMethodObjects->AddL( ( CObject* ) cmInstance );
+    cmInstance->SetHandle( handle );
+    CleanupStack::Pop( cmInstance );
+
+    TPckg<TInt> handlePckg( handle );
+    TInt error = aMessage.Write( 3, handlePckg );
+    if ( error )
+        {
+        // Remove from object index and destroy the object.
+        iConnMethodObjects->Remove( handle );
+        User::Leave( error );
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_GETCONNMETHODWITHIDL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::RefreshConnMethodL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::RefreshConnMethodL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_REFRESHCONNMETHODL_ENTRY );
+
+    CCmmConnMethodInstance* connMethodInstance =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int3() );
+
+    iCache.RefreshConnMethodL( *connMethodInstance );
+
+    OstTraceFunctionExit0( CCMMSESSION_REFRESHCONNMETHODL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetIntAttributeL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetIntAttributeL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETINTATTRIBUTEL_ENTRY );
+
+    CCmmConnMethodInstance* cm =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int3() );
+
+    TUint32 attribute( aMessage.Int0() );
+    TUint32 value = cm->GetIntAttributeL( attribute );
+
+    TPckg<TUint32> valuePckg( value );
+    aMessage.WriteL( 1, valuePckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETINTATTRIBUTEL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetBoolAttributeL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetBoolAttributeL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETBOOLATTRIBUTEL_ENTRY );
+
+    CCmmConnMethodInstance* cm =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int3() );
+
+    TUint32 attribute( aMessage.Int0() );
+    TBool value = cm->GetBoolAttributeL( attribute );
+
+    TPckg<TBool> valuePckg( value );
+    aMessage.WriteL( 1, valuePckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_GETBOOLATTRIBUTEL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetStringAttributeL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetStringAttributeL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETSTRINGATTRIBUTEL_ENTRY );
+
+    CCmmConnMethodInstance* cm =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int3() );
+
+    TUint32 attribute( aMessage.Int0() );
+    HBufC* value = cm->GetStringAttributeL( attribute );
+    if ( !value )
+        {
+        OstTraceFunctionExit0( CCMMSESSION_GETSTRINGATTRIBUTEL_EXIT );
+        return;
+        }
+    CleanupStack::PushL( value );
+    TPtrC valuePtr = value->Des();
+
+    // check the buffer length of the given buffer
+    TInt bufferLen = aMessage.GetDesMaxLength( 1 );
+    if ( valuePtr.Length() > bufferLen )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    aMessage.WriteL( 1, valuePtr );
+    CleanupStack::PopAndDestroy( value );
+
+    OstTraceFunctionExit0( DUP1_CCMMSESSION_GETSTRINGATTRIBUTEL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::GetString8AttributeL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetString8AttributeL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETSTRING8ATTRIBUTEL_ENTRY );
+
+    CCmmConnMethodInstance* cm =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int3() );
+
+    TUint32 attribute( aMessage.Int0() );
+    HBufC8* value = cm->GetString8AttributeL( attribute );
+    if ( !value )
+        {
+        OstTraceFunctionExit0( CCMMSESSION_GETSTRING8ATTRIBUTEL_EXIT );
+        return;
+        }
+    CleanupStack::PushL( value );
+    TPtrC8 valuePtr = value->Des();
+
+    // check the buffer length of the given buffer
+    TInt bufferLen = aMessage.GetDesMaxLength( 1 );
+    if ( valuePtr.Length() > bufferLen )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    aMessage.WriteL( 1, valuePtr );
+    CleanupStack::PopAndDestroy( value );
+
+    OstTraceFunctionExit0( DUP1_CCMMSESSION_GETSTRING8ATTRIBUTEL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::SetIntAttributeL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::SetIntAttributeL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_SETINTATTRIBUTEL_ENTRY );
+
+    CCmmConnMethodInstance* cm =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int3() );
+
+    TUint32 attribute( aMessage.Int0() );
+    TUint32 value( aMessage.Int1() );
+
+    cm->SetIntAttributeL( attribute, value );
+
+    OstTraceFunctionExit0( CCMMSESSION_SETINTATTRIBUTEL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::SetBoolAttributeL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::SetBoolAttributeL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_SETBOOLATTRIBUTEL_ENTRY );
+
+    CCmmConnMethodInstance* cm =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int3() );
+
+    TUint32 attribute( aMessage.Int0() );
+    TBool value( aMessage.Int1() );
+
+    cm->SetBoolAttributeL( attribute, value );
+
+    OstTraceFunctionExit0( CCMMSESSION_SETBOOLATTRIBUTEL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::SetStringAttributeL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::SetStringAttributeL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_SETSTRINGATTRIBUTEL_ENTRY );
+
+    CCmmConnMethodInstance* cm =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int3() );
+
+    TUint32 attribute( aMessage.Int0() );
+
+    HBufC* value = HBufC::NewLC( aMessage.GetDesLengthL( 1 ) );
+    TPtr valuePtr( value->Des() );
+    aMessage.ReadL( 1, valuePtr );
+
+    cm->SetStringAttributeL( attribute, valuePtr );
+
+    CleanupStack::PopAndDestroy( value );
+
+    OstTraceFunctionExit0( CCMMSESSION_SETSTRINGATTRIBUTEL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// CCmmSession::SetString8AttributeL
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::SetString8AttributeL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_SETSTRING8ATTRIBUTEL_ENTRY );
+
+    CCmmConnMethodInstance* cm =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int3() );
+
+    TUint32 attribute( aMessage.Int0() );
+
+    HBufC8* value = HBufC8::NewLC( aMessage.GetDesLengthL( 1 ) );
+    TPtr8 valuePtr( value->Des() );
+    aMessage.ReadL( 1, valuePtr );
+
+    cm->SetString8AttributeL( attribute, valuePtr );
+
+    CleanupStack::PopAndDestroy( value );
+
+    OstTraceFunctionExit0( CCMMSESSION_SETSTRING8ATTRIBUTEL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Create a new connection method (not embedded destination) with specific ID.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::CreateConnMethodWithIdL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_CREATECONNMETHODWITHIDL_ENTRY );
+
+    TUint32 bearerType( aMessage.Int0() );
+    TUint32 connMethodId = ( aMessage.Int1() );
+
+    CCmmConnMethodInstance* connMethod =
+            CCmmConnMethodInstance::NewLC( this, &iCache );
+    // Will check if ID is available.
+    iCache.CreateConnMethodL( *connMethod, NULL, bearerType, connMethodId );
+
+    iConnMethodContainer->AddL( ( CObject* ) connMethod );
+    TInt handle = iConnMethodObjects->AddL( ( CObject* ) connMethod );
+    connMethod->SetHandle( handle );
+    CleanupStack::Pop( connMethod );
+
+    TPckg<TInt> handlePckg( handle );
+    TInt error = aMessage.Write( 3, handlePckg );
+    if ( error )
+        {
+        // Remove from object index and destroy the object.
+        iConnMethodObjects->Remove( handle );
+        User::Leave( error );
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_CREATECONNMETHODWITHIDL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Gets a Connection Method from a Destination with index number.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetConnMethodFromDestWithIndexL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETCONNMETHODFROMDESTWITHINDEXL_ENTRY );
+
+    TInt destinationHandle( aMessage.Int0() );
+    TInt connMethodIndex( aMessage.Int1() );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( destinationHandle );
+
+    // Check index is in range.
+    if ( connMethodIndex < 0 ||
+         connMethodIndex >= destinationInstance->iConnMethodItemArray.Count() )
+        {
+        User::Leave( KErrArgument );
+        }
+    TInt connMethodId( destinationInstance->iConnMethodItemArray[connMethodIndex].iId );
+
+    // If this session already has a connection method with matching id open
+    // and that connection method correctly belongs to the provided destination,
+    // provide the client with a reference to the already opened handle.
+    CCmmConnMethodInstance* cmInstance = FindConnMethodInstanceById( connMethodId );
+    if ( cmInstance &&
+            destinationInstance->ValidConnMethodIdInDestinationIncludeEmbedded( connMethodId ) )
+        {
+        // Also check that the connection method exists in database.
+        if ( iCache.ConnMethodExistsWithId( connMethodId ) ||
+                iCache.DestinationExistsWithId( connMethodId ) )
+            {
+            TPckg<TInt> existingHandlePckg( cmInstance->GetHandle() );
+            aMessage.WriteL( 2, existingHandlePckg );
+            User::Leave( KErrAlreadyExists );
+            }
+        }
+    cmInstance = NULL;
+    TPckg<TInt> existingHandlePckg( 0 );
+    aMessage.WriteL( 2, existingHandlePckg );
+
+    cmInstance = CCmmConnMethodInstance::NewLC( this, &iCache );
+    // Will check if connection method ID is valid.
+    iCache.OpenConnMethodL( *cmInstance, destinationInstance, connMethodId );
+
+    iConnMethodContainer->AddL( ( CObject* ) cmInstance );
+    TInt handle = iConnMethodObjects->AddL( ( CObject* ) cmInstance );
+    cmInstance->SetHandle( handle );
+    CleanupStack::Pop( cmInstance );
+
+    TPckg<TInt> handlePckg( handle );
+    TInt error = aMessage.Write( 3, handlePckg );
+    if ( error )
+        {
+        // Remove from object index and destroy the object.
+        iConnMethodObjects->Remove( handle );
+        User::Leave( error );
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_GETCONNMETHODFROMDESTWITHINDEXL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Gets a Connection Method from a Destination with Id.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetConnMethodFromDestWithIdL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETCONNMETHODFROMDESTWITHIDL_ENTRY );
+
+    TInt destinationHandle( aMessage.Int0() );
+    TUint32 connMethodId( aMessage.Int1() );
+
+    CCmmDestinationInstance* destinationInstance =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( destinationHandle );
+
+    // If this session already has a connection method with matching id open
+    // and that connection method correctly belongs to the provided destination,
+    // provide the client with a reference to the already opened handle.
+    CCmmConnMethodInstance* cmInstance = FindConnMethodInstanceById( connMethodId );
+    if ( cmInstance &&
+            destinationInstance->ValidConnMethodIdInDestinationIncludeEmbedded( connMethodId ) )
+        {
+        // Also check that the connection method exists in database.
+        if ( iCache.ConnMethodExistsWithId( connMethodId ) ||
+                iCache.DestinationExistsWithId( connMethodId ) )
+            {
+            TPckg<TInt> existingHandlePckg( cmInstance->GetHandle() );
+            aMessage.WriteL( 2, existingHandlePckg );
+            User::Leave( KErrAlreadyExists );
+            }
+        }
+    cmInstance = NULL;
+    TPckg<TInt> existingHandlePckg( 0 );
+    aMessage.WriteL( 2, existingHandlePckg );
+
+    cmInstance = CCmmConnMethodInstance::NewLC( this, &iCache );
+    // Will check if connection method ID is valid.
+    iCache.OpenConnMethodL( *cmInstance, destinationInstance, connMethodId );
+
+    iConnMethodContainer->AddL( ( CObject* ) cmInstance );
+    TInt handle = iConnMethodObjects->AddL( ( CObject* ) cmInstance );
+    cmInstance->SetHandle( handle );
+    CleanupStack::Pop( cmInstance );
+
+    TPckg<TInt> handlePckg( handle );
+    TInt error = aMessage.Write( 3, handlePckg );
+    if ( error )
+        {
+        // Remove from object index and destroy the object.
+        iConnMethodObjects->Remove( handle );
+        User::Leave( error );
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_GETCONNMETHODFROMDESTWITHIDL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Create a new connection method (not embedded destination) into a destination.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::CreateConnMethodToDestL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_CREATECONNMETHODTODESTL_ENTRY );
+
+    TInt destinationHandle( aMessage.Int0() );
+    TUint32 bearerType( aMessage.Int1() );
+
+    CCmmDestinationInstance* destination =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( destinationHandle );
+
+    CCmmConnMethodInstance* connMethod = CCmmConnMethodInstance::NewLC( this, &iCache );
+    iCache.CreateConnMethodL( *connMethod, destination, bearerType, 0 );
+
+    iConnMethodContainer->AddL( ( CObject* ) connMethod );
+    TInt handle = iConnMethodObjects->AddL( ( CObject* ) connMethod );
+    connMethod->SetHandle( handle );
+    CleanupStack::Pop( connMethod );
+
+    TPckg<TInt> handlePckg( handle );
+    TInt error = aMessage.Write( 3, handlePckg );
+    if ( error )
+        {
+        // Remove from object index and destroy the object.
+        iConnMethodObjects->Remove( handle );
+        User::Leave( error );
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_CREATECONNMETHODTODESTL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Create a new connection method (not embedded destination) with specific ID
+// into a destination.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::CreateConnMethodToDestWithIdL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_CREATECONNMETHODTODESTWITHIDL_ENTRY );
+
+    TInt destinationHandle( aMessage.Int0() );
+    TUint32 bearerType( aMessage.Int1() );
+    TUint32 connMethodId( aMessage.Int2() );
+
+    CCmmDestinationInstance* destination =
+            ( CCmmDestinationInstance* )iDestinationObjects->AtL( destinationHandle );
+
+    CCmmConnMethodInstance* connMethod =
+            CCmmConnMethodInstance::NewLC( this, &iCache );
+    // Will check if ID is available.
+    iCache.CreateConnMethodL( *connMethod, destination, bearerType, connMethodId );
+
+    iConnMethodContainer->AddL( ( CObject* ) connMethod );
+    TInt handle = iConnMethodObjects->AddL( ( CObject* ) connMethod );
+    connMethod->SetHandle( handle );
+    CleanupStack::Pop( connMethod );
+
+    TPckg<TInt> handlePckg( handle );
+    TInt error = aMessage.Write( 3, handlePckg );
+    if ( error )
+        {
+        // Remove from object index and destroy the object.
+        iConnMethodObjects->Remove( handle );
+        User::Leave( error );
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_CREATECONNMETHODTODESTWITHIDL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Checks if the CM given as parameter is equal to this CM
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::CmIsEqualL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_CMISEQUALL_ENTRY );
+
+    CCmmConnMethodInstance* cm =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int3() );
+
+    CCmmConnMethodInstance* cmToBeCompared =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int0() );
+
+    TBool equal( EFalse );
+    if ( cm->GetId() == cmToBeCompared->GetId() )
+        {
+        equal = ETrue;
+        }
+
+    TPckg<TBool> equalPckg( equal );
+    aMessage.WriteL( 1, equalPckg );
+
+    OstTraceFunctionExit0( CCMMSESSION_CMISEQUALL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Creates a copy of an existing connection method and opens a handle to it.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::CreateCopyOfExistingL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_CREATECOPYOFEXISTINGL_ENTRY );
+
+    CCmmConnMethodInstance* sourceCm =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int0() );
+    TUint32 cmId = sourceCm->GetId();
+
+    CCmmConnMethodInstance* targetCm =
+            CCmmConnMethodInstance::NewLC( this, &iCache );
+    iCache.CreateCopyOfConnMethodL( *targetCm, *sourceCm );
+
+    iConnMethodContainer->AddL( ( CObject* ) targetCm );
+    TInt handle = iConnMethodObjects->AddL( ( CObject* ) targetCm );
+    targetCm->SetHandle( handle );
+    CleanupStack::Pop( targetCm );
+
+    TPckg<TInt> handlePckg( handle );
+    TInt error = aMessage.Write( 3, handlePckg );
+    if ( error )
+        {
+        // Remove from object index and destroy the object.
+        iConnMethodObjects->Remove( handle );
+        User::Leave( error );
+        }
+
+    OstTraceFunctionExit0( CCMMSESSION_CREATECOPYOFEXISTINGL_EXIT );
+    }
+
+// -----------------------------------------------------------------------------
+// Creates a copy of an existing connection method and opens a handle to it.
+// -----------------------------------------------------------------------------
+//
+void CCmmSession::GetEmbeddedDestinationL( const RMessage2& aMessage )
+    {
+    OstTraceFunctionEntry0( CCMMSESSION_GETEMBEDDEDDESTINATIONL_ENTRY );
+
+    CCmmConnMethodInstance* connMethodInstance =
+            ( CCmmConnMethodInstance* )iConnMethodObjects->AtL( aMessage.Int3() );
+
+    if ( connMethodInstance->GetBearerType() != KUidEmbeddedDestination )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    TUint32 destinationId = connMethodInstance->GetId();
+
+    // Check that the ID is in valid range.
+    if ( destinationId <= KCmDefaultDestinationAPTagId ||
+            destinationId >= KCmMaxDestinationAPTagId )
+        {
+        User::Leave( KErrCorrupt );
+        }
+
+    // If this session already has a destination with matching ID open, provide
+    // the client with a reference to the already opened handle.
+    CCmmDestinationInstance* destinationInstance = FindDestinationInstanceById( destinationId );
+    if ( destinationInstance )
+        {
+        if ( iCache.DestinationExistsWithId( destinationId ) )
+            {
+            TPckg<TInt> existingHandlePckg( destinationInstance->GetHandle() );
+            aMessage.WriteL( 1, existingHandlePckg );
+            User::Leave( KErrAlreadyExists );
+            }
+        }
+    destinationInstance = NULL;
+    TPckg<TInt> existingHandlePckg( 0 );
+    aMessage.WriteL( 1, existingHandlePckg );
+
+    destinationInstance = CCmmDestinationInstance::NewLC( this, &iCache );
+
+    // Cache will open a handle to the destination if not already open, and
+    // copy relevant data into this destination instance.
+    iCache.OpenDestinationL( *destinationInstance, destinationId ); // Checks ID is valid.
+
+    iDestinationContainer->AddL( ( CObject* ) destinationInstance );
+    TInt handle = iDestinationObjects->AddL( ( CObject* ) destinationInstance );
+    destinationInstance->SetHandle( handle );
+    CleanupStack::Pop( destinationInstance );
+
+    TPckg<TInt> handlePckg( handle );
+    TInt error = aMessage.Write( 3, handlePckg );
+    if ( error )
+        {
+        // Removes from object index and destroys the object.
+        iDestinationObjects->Remove( handle );
+        User::Leave( error );
+        }
+    OstTraceFunctionExit0( CCMMSESSION_GETEMBEDDEDDESTINATIONL_EXIT );
+    }
+
+// End of file