xdmprotocols/XcapProtocol/src/XcapProtocol.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:05:17 +0200
changeset 0 c8caa15ef882
permissions -rw-r--r--
Revision: 201003 Kit: 201005

/*
* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: CXcapProtocol
*
*/



#include <hal.h>
#include <f32file.h>
#include <flogger.h>
#include <XdmSettingsApi.h>
#include <XdmSettingsProperty.h>
#include <XdmSettingsCollection.h>
#include <implementationproxy.h>
#include <msgconnmanagerapi.h>
#include "XcapAppUsage.h"
#include "XcapEarlyIms.h"
#include "XcapProtocol.h"
#include "XcapDocument.h"
#include "xdmlogwriter.h"
#include "XcapDocumentNode.h"
#include "XcapDirectory.h"
#include "XdmXmlParser.h"
#include "XdmCredentials.h"
#include "XcapHttpReqGet.h"
#include "XdmProtocolInfo.h"
#include "XdmShutdownTimer.h"
#include "XcapHttpTransport.h"
#include "XdmOperationFactory.h"

// ----------------------------------------------------------
// CXcapProtocol::CXcapProtocol
// 
// ----------------------------------------------------------
//
CXcapProtocol::CXcapProtocol() : iSuspend( EFalse ),
                                 iCacheUsage( EFalse ),
                                 iTransferMediaOpen( EFalse ),
                                 iSimRequestPending( EFalse ),
                                 iAuthType( EXcapAuthHttpDigest )
    {   
    }
        
// ----------------------------------------------------------
// CXcapProtocol::DeleteLogFileL
// 
// ----------------------------------------------------------
//
CXcapProtocol* CXcapProtocol::NewL( const TXdmProtocolParams& aProtocolParams )
    {
    CXcapProtocol* self = new ( ELeave ) CXcapProtocol();
    CleanupStack::PushL( self );
    self->ConstructL( aProtocolParams );
    CleanupStack::Pop();
    return self;
    }

// ----------------------------------------------------------
// CXcapProtocol::DeleteLogFileL
// 
// ----------------------------------------------------------
//
CXcapProtocol::~CXcapProtocol()
    {
    #ifdef _DEBUG
        WriteToLog( _L8( "CXcapProtocol::~CXcapProtocol()" ) );  
    #endif
    delete iRootUri;
    delete iPublicId;
    delete iXmlParser;
    delete iCapabilities;
    delete iImsResolver;
    delete iHttpTransport;
    delete iIdleTimer;
    if( iCacheUsage )
        {
        iCacheClient.Flush();
        #ifdef _DEBUG
            WriteToLog( _L8( "  Cache flushed" ) );
        #endif
        iCacheClient.Close();
        #ifdef _DEBUG
            WriteToLog( _L8( "  Cache closed" ) );
        #endif
        }
    if( iConnectionManager != NULL )
        iConnectionManager->Destroy();
    #ifdef _DEBUG
        WriteToLog( _L8( "  ConnMan destroyed" ) );
    #endif
    #ifdef _DEBUG
        WriteToLog( _L8( "  All finished, about to delete file logger" ) );
    #endif
    delete iLogWriter;
    iNotifyeeQueue.Close();
    }
 
// ----------------------------------------------------------
// CXcapProtocol::ConstructL
// 
// ----------------------------------------------------------
//
void CXcapProtocol::ConstructL( const TXdmProtocolParams& aProtocolParams )
    {
    #ifdef _DEBUG
        iLogWriter = CXdmLogWriter::NewL( KXcapEngLogFile );
        WriteToLog( _L8( "CXcapProtocol::ConstructL()" ) );  
    #endif
    iXdmEngine = CONST_CAST( CXdmEngine*, &aProtocolParams.iXdmEngine );
    iProtocolInfo = &aProtocolParams.iProtocolInfo;
    TInt error = SaveSettingsL();
    if( error == KErrNone )
        {
        iXmlParser = CXdmXmlParser::NewL();
        iIdleTimer = new ( ELeave ) CXdmShutdownTimer( *this, this );
        iIdleTimer->ConstructL();
        if( iProtocolInfo->IsCacheEnabled() )
            {
            iCacheUsage = ETrue;
            TInt error = iCacheClient.Connect();
            #ifdef _DEBUG
                WriteToLog( _L8( "  Cache start: %d" ), error );  
            #endif
            __ASSERT_DEBUG( ( error == KErrNone || error == KErrAlreadyExists ),
                              User::Panic( _L( "CXcapProtocol" ), 1 ) );
            }
        iUserName.Copy( iCredentials.iUserName );
        iConnectionManager = NewMsgConnManagerL( iAccessPoint );
        __ASSERT_DEBUG( iRootUri->Des().Length() > 0, User::Panic( _L( "CXcapProtocol" ), 1 ) );
        TBool secure = iProtocolInfo->IsSecure() || iRootUri->Des().FindF( KHttps ) == 0;
        HBufC* root = ParseRootLocationLC( secure, iRootUri->Des() );
        __ASSERT_ALWAYS( root != NULL, User::Panic( _L( "CXcapProtocol" ), 1 ) );
        iHttpTransport = CXcapHttpTransport::NewL( root->Des(), *iConnectionManager, iCredentials );
        CleanupStack::PopAndDestroy();  //root   
        }
    else User::Leave( error );
    }

// ----------------------------------------------------------
// CXcapProtocol::PublicID
// 
// ----------------------------------------------------------
//
EXPORT_C TPtrC8 CXcapProtocol::PublicID()
    {
    return iPublicId != NULL ? iPublicId->Des() : TPtrC8();  
    }

// ----------------------------------------------------------
// CXcapProtocol::Cache
// 
// ----------------------------------------------------------
//
EXPORT_C RXcapCache* CXcapProtocol::Cache()
    {
    return iCacheUsage ? &iCacheClient : NULL;  
    }

// ---------------------------------------------------------
// CXcapProtocol::Parser
// 
// ---------------------------------------------------------
//
EXPORT_C CXdmXmlParser& CXcapProtocol::Parser()
    {
    return *iXmlParser;
    }

// ---------------------------------------------------------
// CXcapProtocol::Transport
// 
// ---------------------------------------------------------
//
EXPORT_C CXcapHttpTransport& CXcapProtocol::Transport()
    {
    return *iHttpTransport;
    }
   
// ----------------------------------------------------------
// CXcapProtocol::IsNetworkAvailable
// 
// ----------------------------------------------------------
//
EXPORT_C TBool CXcapProtocol::IsNetworkAvailable()
    {
    return iConnectionManager->Status();
    } 
       
// ----------------------------------------------------------
// CXcapProtocol::SaveSettingsL
// 
// ----------------------------------------------------------
//
TInt CXcapProtocol::SaveSettingsL()
    {
    TInt settingsId = iProtocolInfo->SettingsID();
    #ifdef _DEBUG
        WriteToLog( _L8( "CXcapProtocol::SaveSettingsL() - ID: %d" ), settingsId );
    #endif
    CXdmSettingsCollection* settings = NULL;
    TRAPD( error, settings = TXdmSettingsApi::SettingsCollectionL( settingsId ) );
    if( error == KErrNone && settings != NULL )
        {
        CleanupStack::PushL( settings );
        SaveFromCollectionL( *settings );
        CleanupStack::PopAndDestroy();  //settings
        }
    else   //Default to HTTP-DIGEST
        {
        iAuthType = EXcapAuthHttpDigest;
        iAccessPoint = iProtocolInfo->AccessPoint();
        iCredentials = iProtocolInfo->Credentials();
        iRootUri = iProtocolInfo->Root().AllocL();
        error = iRootUri->Des().Length() > 0 &&
                iCredentials.iUserName.Length() > 0 &&
                iCredentials.iPassword.Length() > 0 ?
                KErrNone : KErrArgument;
        }
    return error;
    }

// ----------------------------------------------------------
// CXcapProtocol::SelectAuthType
// 
// ----------------------------------------------------------
//
void CXcapProtocol::SelectAuthTypeL( const CXdmSettingsCollection& aSettings )
    {
    #ifdef _DEBUG
        WriteToLog( _L8( "CXcapProtocol::SelectAuthTypeL()" ) );  
    #endif
    TPtrC authType( aSettings.Property( EXdmPropAuthType ) );
    if( authType.Compare( KXdmAuthGaa ) == 0 ) 
        {
        iAuthType = EXcapAuthGaa;
        #ifdef _DEBUG
            CXcapProtocol::WriteToLog( _L8( " GAA" ) );
        #endif
        }
    else if( authType.Compare( KXdmAuthEarlyIms ) == 0 )
        {
        #ifndef __WINSCW__ 
            iAuthType = EXcapAuthEarlyIms;
            ResolveIdentityL();
            #ifdef _DEBUG
                CXcapProtocol::WriteToLog( _L8( " EARLY-IMS" ) );
            #endif
        #endif
        #ifdef __FAKE_IMPU__
            iAuthType = EXcapAuthEarlyIms;
            ResolveIdentityL();
            #ifdef _DEBUG
                CXcapProtocol::WriteToLog( _L8( " EARLY-IMS" ) );
            #endif
        #else
            #ifdef _DEBUG
                CXcapProtocol::WriteToLog( _L8( " WINS, cannot authenticate without SIM card => ignore" ) );
            #endif
            iAuthType = EXcapAuthHttpDigest;
        #endif   
        }
    else
        {
        iAuthType = EXcapAuthHttpDigest;
        #ifdef _DEBUG
            CXcapProtocol::WriteToLog( _L8( " HTTP-DIGEST" ) );
        #endif
        } 
    //Fallback position: in case the server challenges us even though EXcapAuthEarlyIms
    //has been defined, use the credentials the client supplied regardless of what they are.
    TPtrC authName( aSettings.Property( EXdmPropAuthName ) );
    TPtrC authSecret( aSettings.Property( EXdmPropAuthSecret ) );
    //But they must not exceed the stipulated length
    __ASSERT_ALWAYS( authName.Length() <= KXdmMaxUserNameLength, User::Leave( KErrCorrupt ) );
    __ASSERT_ALWAYS( authSecret.Length() <= KXdmMaxPasswordLength, User::Leave( KErrCorrupt ) );
    iCredentials = TXdmCredentials( authName, authSecret );
    }

// ----------------------------------------------------------
// CXcapProtocol::SaveFromCollectionL
// 
// ----------------------------------------------------------
//
void CXcapProtocol::SaveFromCollectionL( const CXdmSettingsCollection& aSettings )
    {
    #ifdef _DEBUG
        for( TInt i = 0;i < aSettings.Count();i++ )
            {
            const CXdmSettingsProperty& prop = aSettings.Property( i );
            HBufC8* value = HBufC8::NewLC( prop.PropertyValue().Length() );
            value->Des().Copy( prop.PropertyValue() );
            TPtrC8 valueDes( value->Des() );
            WriteToLog( _L8( "  Property %d - Name: %d  Value: %S" ), i, prop.PropertyName(), &valueDes );
            CleanupStack::PopAndDestroy();  //value
            }
    #endif
    SelectAuthTypeL( aSettings );
    __ASSERT_DEBUG( aSettings.Property( EXdmPropToNapId ).Length() > 0, User::Leave( KErrCorrupt ) );
    __ASSERT_DEBUG( aSettings.Property( EXdmPropUri ).Length() > 0, User::Leave( KErrCorrupt ) );
    TLex accessPoint( aSettings.Property( EXdmPropToNapId ) );
    TInt error = accessPoint.Val( iAccessPoint );
    __ASSERT_DEBUG( error == KErrNone, User::Leave( KErrCorrupt ) );
    iRootUri = aSettings.Property( EXdmPropUri ).AllocL();
    #ifdef _DEBUG
        TBuf8<KXdmMaxUserNameLength> name( iCredentials.iUserName );
        TBuf8<KXdmMaxPasswordLength> password( iCredentials.iPassword );
        HBufC8* rootUri = HBufC8::NewLC( iRootUri->Des().Length() );
        rootUri->Des().Copy( iRootUri->Des() );
        TPtrC8 uriDes( rootUri->Des() );
        WriteToLog( _L8( " Finished - Error:    %d" ), error );
        WriteToLog( _L8( "  Access point:       %d" ), iAccessPoint );
        WriteToLog( _L8( "  URI:                %S" ), &uriDes );
        WriteToLog( _L8( "  User name:          %S" ), &name );
        WriteToLog( _L8( "  Password:           %S" ), &password );
        CleanupStack::PopAndDestroy();  //rootUri
    #endif
    iUserName.Copy( iCredentials.iUserName );
    }
    
// ----------------------------------------------------------
// CXcapProtocol::ParseRootLocationLC
// 
// ----------------------------------------------------------
//
HBufC* CXcapProtocol::ParseRootLocationLC( const TBool aSecurity,
                                           const TDesC& aRootLocation )
    {
    #ifdef _DEBUG
        TBuf8<1024> root;
        root.Copy( aRootLocation );
        WriteToLog( _L8( "CXcapProtocol::ParseRootLocationLC()" ) );
        WriteToLog( _L8( "  Security:     %d" ), aSecurity );
        WriteToLog( _L8( "  Provided URI: %S" ), &root );
    #endif
    HBufC* ret = NULL;
    HBufC* temp = CheckProtocolPrefixL( aRootLocation );
    if( temp != NULL )
        {
        CleanupStack::PushL( temp );
        ret = aSecurity ? ConstructSecureUriL( temp->Des() ) :
                          ConstructStandardUriL( temp->Des() );
        CleanupStack::PopAndDestroy();  //temp                       
        }
    else
        ret = aSecurity ? ConstructSecureUriL( aRootLocation ) :
                          ConstructStandardUriL( aRootLocation );
	TPtr desc( ret->Des() );
	if( desc[desc.Length() - 1] == '/' )
    	desc.Delete( desc.Length() - 1, 1 );
    CleanupStack::PushL( ret );
    return ret;
    }

// ----------------------------------------------------------
// CXcapProtocol::CheckProtocolPrefixLC
// 
// ----------------------------------------------------------
//
HBufC* CXcapProtocol::CheckProtocolPrefixL( const TDesC& aRootLocation )
    {
    #ifdef _DEBUG
        WriteToLog( _L8( "CXcapProtocol::CheckProtocolPrefixL()" ) );  
    #endif
    HBufC* buffer = NULL;
    if( aRootLocation.FindF( KHttp ) == 0 || aRootLocation.FindF( KHttps ) == 0 )
        {
        TInt length = aRootLocation.FindF( KHttp ) == 0 ?
                      KHttp().Length() : KHttps().Length();
        buffer = HBufC::NewL( aRootLocation.Length() - length );
        TPtrC desc( aRootLocation );
        TPtrC temp = desc.Right( aRootLocation.Length() - length );
        buffer->Des().Copy( temp );
        }  
    return buffer;
    }
    
// ----------------------------------------------------------
// CXcapProtocol::ConstructStandardUriL
// 
// ----------------------------------------------------------
//
HBufC* CXcapProtocol::ConstructStandardUriL( const TDesC& aBasicUri )
    {
    #ifdef _DEBUG
        WriteToLog( _L8( "CXcapProtocol::ConstructStandardUriLC()" ) );  
    #endif
    HBufC* ret = HBufC::NewL( aBasicUri.Length() +
                              TPtrC( KHttp ).Length() );
	TPtr desc( ret->Des() );
    desc.Copy( KHttp );
    desc.Append( aBasicUri );
    return ret;
    }
    
// ----------------------------------------------------------
// CXcapProtocol::ConstructSecureUriL
// 
// ----------------------------------------------------------
//
HBufC* CXcapProtocol::ConstructSecureUriL( const TDesC& aBasicUri )
    {
    #ifdef _DEBUG
        WriteToLog( _L8( "CXcapProtocol::ConstructSecureUriLC()" ) );  
    #endif
    TInt index = aBasicUri.FindF( KHostSeparator );
    HBufC* ret = HBufC::NewL( aBasicUri.Length() +
                        TPtrC( KHttps ).Length() );
    TPtr uriDesc( ret->Des() );
    if( index > 0 )
        {
        TPtrC basic( aBasicUri.Left( index ) );
        TPtrC theRest( aBasicUri.Mid( index ) );
        uriDesc.Copy( KHttps );
        uriDesc.Append( basic );
        uriDesc.Append( theRest );
        }
    else
        {
        uriDesc.Copy( KHttps );
        uriDesc.Append( aBasicUri );
        }
    return ret;
    }

// ----------------------------------------------------------
// CXcapProtocol::ResolveIdentityL
// 
// ----------------------------------------------------------
//
void CXcapProtocol::ResolveIdentityL()
    {
    #ifdef _DEBUG
        WriteToLog( _L8( "CXcapProtocol::ResolveIdentityL()" ) );  
    #endif
    iImsResolver = CXcapEarlyIms::NewL();
    iImsResolver->RequestSimDataL( this );
    iSimRequestPending = ETrue;
    }

// ---------------------------------------------------------
// CXcapProtocol::CheckActivity
//
// ---------------------------------------------------------
//
void CXcapProtocol::CheckActivity()
    {
    #ifdef _DEBUG
        WriteToLog( _L8( "CXcapProtocol::CheckActivity()" ) );
    #endif
    TBool activity = EFalse;
    const RPointerArray<CXdmDocument>& documents = iXdmEngine->DocumentCollection();
    const RPointerArray<CXdmDirectory>& directories = iXdmEngine->DirectoryCollection();
    TInt docCount = documents.Count();
    TInt dirCount = directories.Count();
    if( docCount > 0 || dirCount > 0 )
        {
        TInt i = 0;
        for( ;!activity && i < docCount;i++ )
            activity = documents[i]->IsActive();
        for( i = 0 && !activity;!activity && i < dirCount;i++ )
            activity = directories[i]->IsActive();
        }
    if( !activity )
        {
        //Just in case...
        iIdleTimer->Cancel();
        iIdleTimer->Start( iIdleTimeout * 1000000 );
        }
    }

// ---------------------------------------------------------
// CXcapProtocol::SimRequestPending
// 
// ---------------------------------------------------------
//
TBool CXcapProtocol::IsSimRequestPending( TInt& aError ) const
    {
    aError = iSimRequestPending ? KErrNotReady : iImsResolverError;
    return iSimRequestPending; 
    }

// ---------------------------------------------------------
// CXcapProtocol::AppendNotifyeeL
// 
// ---------------------------------------------------------
//
void CXcapProtocol::AppendNotifyeeL( CXcapDocument* aPendingDoc )
    {
    User::LeaveIfError( iNotifyeeQueue.Append( aPendingDoc ) );
    }

// ---------------------------------------------------------
// CXcapProtocol::CancelImsResolver
// 
// ---------------------------------------------------------
//
void CXcapProtocol::CancelImsResolver()
    {
    #ifdef _DEBUG
        CXcapProtocol::WriteToLog( _L8( "CXcapDocument::CancelImsResolver()" ) );
    #endif
    if( iImsResolver )
        iImsResolver->Cancel();
    }
       
// ---------------------------------------------------------
// CXcapDocument::RequestComplete
// 
// ---------------------------------------------------------
//
void CXcapProtocol::RequestComplete( TInt aError )
    {
    #ifdef _DEBUG
        CXcapProtocol::WriteToLog( _L8( "CXcapDocument::RequestComplete()" ) );
    #endif
    if( aError == KErrNone )
        {
        #ifdef _DEBUG
            CXcapProtocol::WriteToLog( _L8( " Public ID retrieved successfully" ) );
        #endif
        iPublicId = iImsResolver->PublicIDL().AllocL();
        delete iImsResolver;
        iImsResolver = NULL;
        }
    else
        {
        #ifdef _DEBUG
            CXcapProtocol::WriteToLog( _L8( " Public ID retrieval failed - Status: %d" ), aError );
        #endif
        iImsResolverError = aError;
        }
    for( TInt i = 0;i < iNotifyeeQueue.Count();i++ )
        {
        CXcapDocument* document = iNotifyeeQueue[i];
        if( document )
            document->NotifyResolverCompleteL( aError );
        }
    iSimRequestPending = EFalse;
    iNotifyeeQueue.Reset();
    }
        
// ----------------------------------------------------------
// CXcapProtocol::WriteToLog
// 
// ----------------------------------------------------------
//
void CXcapProtocol::WriteToLog( TRefByValue<const TDesC8> aFmt,... ) const                                 
    {
    VA_LIST list;
    VA_START( list, aFmt );
    TBuf8<KLogBufferMaxSize> buf;
    buf.FormatList( aFmt, list );
    iLogWriter->WriteToLog( buf );
    }

// ----------------------------------------------------
// CXcapProtocol::InitTransferMedium
// 
// ----------------------------------------------------
//
void CXcapProtocol::InitTransferMedium( TInt aIdleTimeout, TRequestStatus& aStatus )
    {
    #ifdef _DEBUG
        WriteToLog( _L8( "CXcapProtocol::InitTransferMedium()" ) );  
    #endif
    iIdleTimer->Cancel();
    iIdleTimeout = aIdleTimeout;
    if( !IsNetworkAvailable() )
        iConnectionManager->StartConnection( aStatus );
    else  //Already open
        {
        TRequestStatus* status = &aStatus;
        User::RequestComplete( status, KErrNone );
        }
    }

// ----------------------------------------------------
// CXcapProtocol::CancelTransferMediumInit
// 
// ----------------------------------------------------
//
void CXcapProtocol::CancelTransferMediumInit()
    {
    #ifdef _DEBUG
        WriteToLog( _L8( "CXcapProtocol::CancelTransferMediumInit()" ) );  
    #endif
    TInt error = KErrNone;
    TRAP( error, iConnectionManager->CancelStartL() );
    #ifdef _DEBUG
        WriteToLog( _L8( " Transfer media cancel completed - Error: %d" ), error );  
    #endif
    //Suppress build warning
    error = KErrNone;
    }

// ---------------------------------------------------------
// CXcapProtocol::IsTransferAvailable
// 
// ---------------------------------------------------------
//
TBool CXcapProtocol::IsTransferAvailable() const
    {
    return iConnectionManager->Status();
    }
    
// ---------------------------------------------------------
// CXcapProtocol::AuthType
// 
// ---------------------------------------------------------
//
TXcapAuthType CXcapProtocol::AuthType() const
    {
    return iAuthType;
    }
             
// ---------------------------------------------------------
// CXdmEngine::XdmProtocol
// 
// ---------------------------------------------------------
//
void CXcapProtocol::SwitchOff()
    {
    #ifdef _DEBUG
        WriteToLog( _L8( "CXcapProtocol::SwitchOff()" ) );
    #endif
    iConnectionManager->StopConnection();
    }

// ----------------------------------------------------
// CXcapProtocol::CreateDocumentL
// 
// ----------------------------------------------------
//
CXdmDocument* CXcapProtocol::CreateDocumentL( const TDesC& aDocumentName,
                                              const TXdmDocType aDocumentType )
    {
    return CXcapDocument::NewL( aDocumentType, aDocumentName, *iXdmEngine, *this );
    }
    
// ----------------------------------------------------
// CXcapProtocol::CreateDirectoryL
//
// ----------------------------------------------------
//
CXdmDirectory* CXcapProtocol::CreateDirectoryL( const TDesC& aDirectoryPath )
    {
    _LIT( KDirectoryDocName, "directory.xml" );
    CXdmDocument* document = iXdmEngine->CreateDocumentModelL( KDirectoryDocName, EXdmDirectory );
    CleanupStack::PushL( document );
    CXdmDirectory* directory = CXcapDirectory::NewL( aDirectoryPath, *iXdmEngine, document, *this );
    CleanupStack::Pop();               //document
    return directory;
    }

// ----------------------------------------------------
// CXcapProtocol::CreateDocumentNodeL
// 
// ----------------------------------------------------
//
CXdmDocumentNode* CXcapProtocol::CreateDocumentNodeL()
    {
    return CXcapDocumentNode::NewL( *iXdmEngine, *this );
    }
        
// ---------------------------------------------------------
// CXcapProtocol::GenerateUniqueIdL
// 
// ---------------------------------------------------------
//
TInt CXcapProtocol::GenerateUniqueIdL()
    {
    TInt period = 0;
    User::LeaveIfError( HAL::Get( HALData::ESystemTickPeriod, period ) );
    TInt millisecsPerTick = period / 1000;
    return User::TickCount() * millisecsPerTick;
    }

// ----------------------------------------------------------
// CXdmProtocol::UserName
// 
// ----------------------------------------------------------
//
TPtrC8 CXcapProtocol::UserName() const
    {
    return iUserName;
    }
        
// ----------------------------------------------------------
// CXdmProtocol::HandleBearerEventL
// 
// ----------------------------------------------------------
//
void CXcapProtocol::HandleBearerEventL( TBool aAuthoritativeClose,
                                        TMsgBearerEvent aBearerEvent )
    {
    #ifdef _DEBUG
        WriteToLog( _L8( "CXcapProtocol::HandleBearerEventL(): %d" ), aBearerEvent );
    #endif
    switch( aBearerEvent )
        {
        case EMsgBearerSuspended:
            #ifdef _DEBUG
                WriteToLog( _L8( "  Bearer suspended" ) );
            #endif
            iSuspend = ETrue;
            break;
        case EMsgBearerActive:
            #ifdef _DEBUG
                WriteToLog( _L8( "  Bearer active" ) );
            #endif
            iSuspend = EFalse;
            break;
        case EMsgBearerLost:
            #ifdef _DEBUG
                WriteToLog( _L8( "  Bearer lost - Authoritative: %d" ),
                                    aAuthoritativeClose );
            #endif
            break;
        default:
        		//Suppress build warning
        		aAuthoritativeClose = EFalse;
            break;
        }
    }

// ---------------------------------------------------------
// Map the interface UIDs to implementation factory functions
// 
// ---------------------------------------------------------
//
const TImplementationProxy ImplementationTable[] = 
	{
#ifdef __EABI__
    IMPLEMENTATION_PROXY_ENTRY( 0x10207423,	CXcapProtocol::NewL )
#else
    { { 0x10207423 }, CXcapProtocol::NewL }
#endif
    };

// ---------------------------------------------------------
// Return the implementation table & number of implementations
// 
// ---------------------------------------------------------
//
EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount )
    {
    aTableCount = sizeof( ImplementationTable ) / sizeof( TImplementationProxy );
    return ImplementationTable;
    }
    

  
// End of File