adaptationlayer/tsy/nokiatsy_dll/src/cmmuiccmesshandler.cpp
author <dalarub>
Fri, 06 Nov 2009 17:28:23 +0000
changeset 0 63b37f68c1ce
child 5 8ccc39f9d787
permissions -rw-r--r--
First Contribution. Vanilla as it came from Nokia

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "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:   ?Description
*
*/



// INCLUDE FILES
#include "cmmuiccmesshandler.h"
#include "cmmphonetsender.h"
#include "tsylogger.h"
#include "cmmmessagerouter.h"

#include <ctsy/serviceapi/mmtsy_ipcdefs.h>
#include <e32cmn.h>
#include <pn_const.h>
#include <uiccisi.h>
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "cmmuiccmesshandlerTraces.h"
#endif


// LOCAL CONSTANTS AND MACROS
const TUint8 KUiccPadding( 0 );
const TUint8 KUiccSbApplPathSize( SIZE_UICC_SB_APPL_PATH + KFilePathLength );
const TUint8 KUiccSbFileDataSize( SIZE_UICC_SB_FILE_DATA + KFileDataLength );
const TUint8 KUiccApplCmdReqOffset( ISI_HEADER_SIZE + SIZE_UICC_APPL_CMD_REQ );
const TUint8 KUiccRecordNotDefined( 0 );
const TUint16 KUiccFileIdNotDefined( 0 );
const TUint8 KUiccServiceTypeNotDefined( 0 );
const TUint8 KUiccApduReqSubblockOffset(ISI_HEADER_SIZE + SIZE_UICC_APDU_REQ);
const TUint8 KUiccSbApduLengthOffset( 6 );
const TUint8 KUiccSbApduDataOffset( 8 );
const TUint16 KUiccSbApduSize( SIZE_UICC_SB_APDU + KApduDataLength );


// ============================= LOCAL FUNCTIONS ===============================

void CMmUiccMessHandler::SendTerminalProfile()
    {
    // Temporary for testing purposes, terminal profile sending will be moved
    // to SAT TSY
TFLOGSTRING("TSY: CMmUiccMessHandler::SendTerminalProfile TEMPORARY SOLUTION FOR TESTING");
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_SENDTERMINALPROFILE, "CMmUiccMessHandler::SendTerminalProfile TEMPORARY SOLUTION FOR TESTING" );

    // Create UICC_CAT_TERMINAL_PROFILE message
    TIsiSend isiMsg( iPhoNetSender->SendBufferDes() );
    isiMsg.Set8bit( ISI_HEADER_OFFSET_RESOURCEID, PN_UICC );
    isiMsg.Set8bit( ISI_HEADER_SIZE, UICC_CAT_REQ_OFFSET_TRANSID ); // transaction id
    isiMsg.Set8bit( ISI_HEADER_SIZE + UICC_CAT_REQ_OFFSET_MESSAGEID, UICC_CAT_REQ );
    isiMsg.Set8bit( ISI_HEADER_SIZE + UICC_CAT_REQ_OFFSET_SERVICETYPE, UICC_CAT_TERMINAL_PROFILE );
    isiMsg.Set8bit( ISI_HEADER_SIZE + UICC_CAT_REQ_OFFSET_NSB, 1 ); // num of subblocks

    // Create subblock
    TBuf8<30> terminalProfileBuf( 0 );
    TIsiSubBlock uiccSbTerminalProfile(
        terminalProfileBuf,
        UICC_SB_TERMINAL_PROFILE,
        EIsiSubBlockTypeId16Len16 );

    // 2x filler
    terminalProfileBuf.Append( KUiccPadding );
    terminalProfileBuf.Append( KUiccPadding );

    // Terminal profile length (16-bit)
    terminalProfileBuf.Append( KUiccPadding );
    terminalProfileBuf.Append( 1 );
    terminalProfileBuf.Append( 0 );

    // Append subblock to ISI message
    isiMsg.CopyData(
        ISI_HEADER_SIZE + 4,
        uiccSbTerminalProfile.CompleteSubBlock() );

    iPhoNetSender->Send( isiMsg.Complete() );
    }

// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// TUiccParamsBase::TUiccParamsBase
// Constructor
// -----------------------------------------------------------------------------
//
TUiccParamsBase::TUiccParamsBase()
    {
    // Initialize data
    messHandlerPtr = NULL;
    trId = ETrIdNotDefined;
    fileId = KUiccFileIdNotDefined;
    fileIdSfi = UICC_SFI_NOT_PRESENT;
    serviceType = KUiccServiceTypeNotDefined;
    filePath.Append( KNullDesC8 );
    }

// -----------------------------------------------------------------------------
// TUiccApplFileInfo::TUiccApplFileInfo
// Constructor
// -----------------------------------------------------------------------------
//
TUiccApplFileInfo::TUiccApplFileInfo()
    {
    // None
    }

// -----------------------------------------------------------------------------
// TUiccReadTransparent::TUiccReadTransparent
// Constructor
// -----------------------------------------------------------------------------
//
TUiccReadTransparent::TUiccReadTransparent()
    {
    dataOffset = 0;
    dataAmount = 0;
    }

// -----------------------------------------------------------------------------
// TUiccWriteTransparent::TUiccWriteTransparent
// Constructor
// -----------------------------------------------------------------------------
//
TUiccWriteTransparent::TUiccWriteTransparent()
    {
    fileData.Append( KNullDesC8 );
    }

// -----------------------------------------------------------------------------
// TUiccReadLinearFixed::TUiccReadLinearFixed
// Constructor
// -----------------------------------------------------------------------------
//
TUiccReadLinearFixed::TUiccReadLinearFixed()
    {
    record = KUiccRecordNotDefined;
    }

// -----------------------------------------------------------------------------
// TUiccWriteLinearFixed::TUiccWriteLinearFixed
// Constructor
// -----------------------------------------------------------------------------
//
TUiccWriteLinearFixed::TUiccWriteLinearFixed()
    {
    fileData.Append( KNullDesC8 );
    }

// -----------------------------------------------------------------------------
// TUiccSendApdu::TUiccSendApdu
// Constructor
// -----------------------------------------------------------------------------
//
TUiccSendApdu::TUiccSendApdu():TUiccParamsBase()
    {
    apdu.Append( KNullDesC8 );
    }

// -----------------------------------------------------------------------------
// TUiccParamsApduReq::TUiccParamsApduReq
// Constructor
// -----------------------------------------------------------------------------
//
TUiccParamsApduReq::TUiccParamsApduReq():TUiccParamsBase()
    {
    action = KUiccRecordNotDefined;
    apduData.Append( KNullDesC8 );
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CMmUiccMessHandler
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CMmUiccMessHandler::CMmUiccMessHandler()
    {
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::ConstructL(
    CMmPhoNetSender* aPhoNetSender,
    CMmPhoNetReceiver* aPhoNetReceiver)
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::ConstructL");
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CONSTRUCTL, "CMmUiccMessHandler::ConstructL" );

    // Reset the pointer array
    iMessHandlerPrtList.Reset();
    iPhoNetSender = aPhoNetSender;
    aPhoNetReceiver->RegisterL( this, PN_UICC );

    iCardType = UICC_CARD_TYPE_UNKNOWN;
    iApplicationId = UICC_APPL_ID_UNKNOWN;
    iApplicationType = UICC_APPL_TYPE_UNKNOWN;
    iApplicationStatus = UICC_STATUS_APPL_NOT_ACTIVE;
    iUiccServerStatus = UICC_STATUS_NOT_READY;
    iUiccClientId = 0;
    iUiccIsimClientId = 0;
    iIsimApplicationId = UICC_APPL_ID_UNKNOWN;
    iIsimApplicationStatus = UICC_STATUS_APPL_NOT_ACTIVE;
    iIsimApplicationFound = EFalse;
    iPin1Id = 0;
    iPin2Id = 0;
    iActivePin = RMobilePhone::ESecurityCodePin1;
    iAid.Zero();

    // Initialized for USIM application
    iApplFileId.Append( 0x7F );
    iApplFileId.Append( 0xFF );
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CMmUiccMessHandler* CMmUiccMessHandler::NewL(
    CMmPhoNetSender* aPhoNetSender,
    CMmPhoNetReceiver* aPhoNetReceiver,
    CMmMessageRouter* aMessageRouter )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::NewL");
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_NEWL, "CMmUiccMessHandler::NewL" );

    CMmUiccMessHandler* uiccMessHandler( new ( ELeave ) CMmUiccMessHandler() );
    CleanupStack::PushL( uiccMessHandler );
    uiccMessHandler->iMessageRouter = aMessageRouter;
    uiccMessHandler->ConstructL( aPhoNetSender, aPhoNetReceiver );
    CleanupStack::Pop( uiccMessHandler );
    return uiccMessHandler;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::~CMmUiccMessHandler()
// Destructor
// -----------------------------------------------------------------------------
//
CMmUiccMessHandler::~CMmUiccMessHandler()
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::~CMmUiccMessHandler");
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CMMUICCMESSHANDLER, "CMmUiccMessHandler::~CMmUiccMessHandler" );
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::ReceiveMessageL
// Receive ISI messages from phonet
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::ReceiveMessageL( const TIsiReceiveC& aIsiMsg )
    {
    TInt status( KErrNone );
    TUint8 messageId( aIsiMsg.Get8bit( ISI_HEADER_OFFSET_MESSAGEID ) );
    TUint8 trId( aIsiMsg.Get8bit( ISI_HEADER_OFFSET_TRANSID ) );
    TUint8 serviceType( 0 );
    TPtrC8 fileData;

TFLOGSTRING3("TSY: CMmUiccMessHandler::ReceiveMessageL, message ID :0x%x, transaction ID: %d", messageId, trId );
OstTraceExt2( TRACE_NORMAL, CMMUICCMESSHANDLER_RECEIVEMESSAGEL, "CMmUiccMessHandler::ReceiveMessageL;messageId=%hhx;trId=%hhu", messageId, trId );

    // Get the correct message handler for this operation
    MUiccOperationBase* messHandler( iMessHandlerPrtList.At( trId ) );

    switch( messageId )
        {
        case UICC_CAT_IND:
            {
            // Send terminal profile ( to be moved to SAT TSY later )
            SendTerminalProfile();
            break;
            }
        case UICC_CAT_RESP:
            {
            // To be moved to SAT TSY later
            break;
            }
        case UICC_CARD_IND:
            {
            serviceType = aIsiMsg.Get8bit(
                ISI_HEADER_SIZE + UICC_CARD_IND_OFFSET_SERVICETYPE );
            // Start application activation procedure if the card is ready and
            // the application is not active yet
            if ( UICC_CARD_READY == serviceType &&
                UICC_STATUS_APPL_ACTIVE != iApplicationStatus )
                {
                TUiccParamsBase params;
                params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
                params.trId = ETrIdGetUiccApplication;
                CreateUiccApplicationReq( params, UICC_APPL_LIST );
                }
            // No else. Application was active already
            break;
            }
        case UICC_RESP:
            {
            iUiccServerStatus = HandleUiccResp( aIsiMsg );
            // Start application activation procedure if the card is ready and
            // the application is not active yet
            if ( UICC_STATUS_START_UP_COMPLETED == iUiccServerStatus &&
                UICC_STATUS_APPL_ACTIVE != iApplicationStatus)
                {
                // Read the application ID
                TUiccParamsBase params;
                params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
                params.trId = ETrIdGetUiccApplication;
                CreateUiccApplicationReq( params, UICC_APPL_LIST );
                }
            break;
            }
        case UICC_APPLICATION_RESP:
            {
            status = HandleUiccApplicationResp( aIsiMsg );
            break;
            }
        case UICC_APPLICATION_IND:
            {
            TInt8 serviceType( aIsiMsg.Get8bit(
                ISI_HEADER_SIZE + UICC_APPLICATION_IND_OFFSET_SERVICETYPE ) );

            iApplicationStatus = UICC_STATUS_APPL_ACTIVE;
            // Application activation indication with service type
            // UICC_APPL_ACTIVATED, as part of PowerOnSim sequence.
            // Transaction id is set to ETrIdSimPowerOn and operation
            // is added to list and flag is disabled.
            if( UICC_APPL_ACTIVATED == serviceType )
                {
                iDoNotRemoveTransactionID = EFalse;
                status = KErrNone;
                trId = ETrIdSimPowerOn;
                messHandler = iMessHandlerPrtList.At( trId );
                }
            break;
            }
        case UICC_APPL_CMD_RESP:
            {
            status = aIsiMsg.Get8bit(
                ISI_HEADER_SIZE + UICC_APPL_CMD_RESP_OFFSET_STATUS );
            TInt8 serviceType( aIsiMsg.Get8bit(
                ISI_HEADER_SIZE + UICC_APPL_CMD_RESP_OFFSET_SERVICETYPE ) );

            if ( UICC_STATUS_OK == status )
                {
                // If READ operation was required, read data from subblock
                if ( UICC_APPL_READ_TRANSPARENT == serviceType ||
                   UICC_APPL_READ_LINEAR_FIXED == serviceType )
                    {
                    fileData.Set( GetFileData( aIsiMsg ) );
                    }
                if ( UICC_APPL_FILE_INFO == serviceType )
                    {
                    fileData.Set( GetFileFCI( aIsiMsg ) );
                    }
                if ( UICC_APPL_APDU_SEND == serviceType )
                    {
                    fileData.Set( GetApduData( aIsiMsg ) );
                    }
                }
            else
                {
TFLOGSTRING2("TSY: CMmUiccMessHandler::ReceiveMessageL, case UICC_APPL_CMD_RESP, status: %d", status );
OstTraceExt1( TRACE_NORMAL, DUP1_CMMUICCMESSHANDLER_RECEIVEMESSAGEL, "CMmUiccMessHandler::ReceiveMessageL, case UICC_APPL_CMD_RESP;status=%hhu", status );
                }
            break;
            }
        case UICC_APDU_RESP:
            {
            status = aIsiMsg.Get8bit(
                ISI_HEADER_SIZE + UICC_APDU_RESP_OFFSET_STATUS );
            TInt8 serviceType( aIsiMsg.Get8bit(
                ISI_HEADER_SIZE + UICC_APDU_RESP_OFFSET_SERVICETYPE ) );

            // Extract actual APDU from SB_APDU
            if( UICC_STATUS_OK == status )
                {
                if( UICC_APDU_ATR_GET == serviceType
                    || UICC_APDU_SEND == serviceType )
                    {
                    fileData.Set( GetApduData( aIsiMsg ) );
                    }
                }
            break;
            }
        case UICC_APDU_RESET_IND:
            {
            TInt8 serviceType( aIsiMsg.Get8bit(
                ISI_HEADER_SIZE + UICC_APDU_RESET_IND_OFFSET_SERVICETYPE ) );

            // Indication that SAP APDU interface is activated
            if( UICC_READY == serviceType )
                {
                // Disable flag
                iDoNotRemoveTransactionID = EFalse;
                status = KErrNone;
                }
            break;
            }
        case UICC_CONNECTOR_RESP:
            {
            status = aIsiMsg.Get8bit(
                ISI_HEADER_SIZE + UICC_CONNECTOR_RESP_OFFSET_STATUS );
            }
            break;
        case UICC_CARD_RESP:
            {
            status = aIsiMsg.Get8bit(
                ISI_HEADER_SIZE + UICC_CARD_RESP_OFFSET_STATUS );
            TUint8 serviceType( aIsiMsg.Get8bit(
                ISI_HEADER_SIZE + UICC_CARD_RESP_OFFSET_SERVICETYPE ) );

            if( UICC_STATUS_OK == status
                && UICC_CARD_STATUS_GET  == serviceType )
                {
                // File data from SIZE_UICC_SB_CARD_STATUS
                TUint uiccSbFileDataOffset( 0 );
                TInt cardStatusFieldLength( 1 );

                if ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
                    ISI_HEADER_SIZE + SIZE_UICC_CARD_RESP,
                    UICC_SB_CARD_STATUS,
                    EIsiSubBlockTypeId16Len16,
                    uiccSbFileDataOffset ) )
                    {
                    fileData.Set(aIsiMsg.GetData(
                        uiccSbFileDataOffset +
                        UICC_SB_CARD_STATUS_OFFSET_CARDSTATUS,
                        cardStatusFieldLength) );
                    }
                }
            }
            break;
        default:
            {
TFLOGSTRING("TSY: CMmUiccMessHandler::ReceiveMessageL, default" );
OstTrace0( TRACE_NORMAL, DUP2_CMMUICCMESSHANDLER_RECEIVEMESSAGEL, "CMmUiccMessHandler::ReceiveMessageL, default" );
            break;
            }
        }

    if ( NULL != messHandler )
        {
        if( !iDoNotRemoveTransactionID )
            {
            iMessHandlerPrtList[trId] = NULL;
            }
        messHandler->ProcessUiccMsg( trId, status, fileData );
        }
    else
        {
TFLOGSTRING("TSY: CMmUiccMessHandler::ReceiveMessageL, message handler not found -> no further handling of this message" );
OstTrace0( TRACE_NORMAL, DUP3_CMMUICCMESSHANDLER_RECEIVEMESSAGEL, "CMmUiccMessHandler::ReceiveMessageL, message handler not found -> no further handling of this message" );
        }
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CreateUiccApplCmdReq
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CMmUiccMessHandler::CreateUiccApplCmdReq(
    const TUiccParamsBase& aParams,
    const TUint8 aApplType )
    {
    TInt ret( KErrNone );
    TInt trId( aParams.trId );
    TInt8 serviceType( aParams.serviceType );
    TUint8 numOfSubblocks( 0 );
    TUint8 sizeOfApplPathSubblock( 0 );

TFLOGSTRING2("TSY: CMmUiccMessHandler::CreateUiccApplCmdReq, transaction ID: %d", trId );
OstTrace1( TRACE_NORMAL, CMMUICCMESSHANDLER_CREATEUICCAPPLCMDREQ, "CMmUiccMessHandler::CreateUiccApplCmdReq;trId=%d", trId );

    TUint8 applId( aApplType == UICC_APPL_TYPE_UICC_ISIM ?
        iIsimApplicationId : iApplicationId );

    // If there is the previous request ongoing (pointer was already set for
    // this operation)  we can't handle this request.
    if ( NULL == iMessHandlerPrtList.At( trId ) )
        {
        // Save pointer to message handler, it is needed when receiving
        // respone for this operation
        iMessHandlerPrtList[trId] = aParams.messHandlerPtr;
        // Create UICC_APPL_CMD_REQ message
        TIsiSend isiMsg( iPhoNetSender->SendBufferDes() );
        isiMsg.Set8bit( ISI_HEADER_OFFSET_RESOURCEID, PN_UICC );
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_APPL_CMD_REQ_OFFSET_TRANSID,
            trId );
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_APPL_CMD_REQ_OFFSET_MESSAGEID,
            UICC_APPL_CMD_REQ );
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_APPL_CMD_REQ_OFFSET_SERVICETYPE,
            serviceType );
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_APPL_CMD_REQ_OFFSET_APPLID,
            applId );
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_APPL_CMD_REQ_OFFSET_SESSIONID,
            UICC_SESSION_ID_NOT_USED );
        isiMsg.Set16bit(
            ISI_HEADER_SIZE + UICC_APPL_CMD_REQ_OFFSET_FILLERBYTE1,
            KUiccPadding );

        switch ( serviceType )
            {
            case UICC_APPL_READ_TRANSPARENT:
                {
                numOfSubblocks = 3;
                // Create and append UICC_SB_CLIENT
                CreateUiccSbClient( isiMsg, KUiccApplCmdReqOffset );
                // Create and append UICC_SB_TRANSPARENT
                CreateUiccSbTransparent(
                    static_cast <const TUiccReadTransparent&>( aParams ),
                    isiMsg,
                    KUiccApplCmdReqOffset + SIZE_UICC_SB_CLIENT );
                // Create and append UICC_SB_APPL_PATH
                CreateUiccSbApplPath(
                    aParams,
                    isiMsg,
                    KUiccApplCmdReqOffset + SIZE_UICC_SB_CLIENT +
                    SIZE_UICC_SB_TRANSPARENT,
                    sizeOfApplPathSubblock );
                break;
                }
            case UICC_APPL_UPDATE_TRANSPARENT:
                {
                numOfSubblocks = 4;
                // Create and append UICC_SB_CLIENT
                CreateUiccSbClient( isiMsg, KUiccApplCmdReqOffset );
                // Create and append UICC_SB_TRANSPARENT
                CreateUiccSbTransparent(
                    static_cast <const TUiccWriteTransparent&>( aParams ),
                    isiMsg,
                    KUiccApplCmdReqOffset + SIZE_UICC_SB_CLIENT );
                // Create and append UICC_SB_APPL_PATH
                CreateUiccSbApplPath(
                    static_cast <const TUiccWriteTransparent&>( aParams ),
                    isiMsg,
                    KUiccApplCmdReqOffset + SIZE_UICC_SB_CLIENT +
                    SIZE_UICC_SB_TRANSPARENT,
                    sizeOfApplPathSubblock );
                // Create and append UICC_SB_FILE_DATA
                CreateUiccSbFileData(
                    isiMsg,
                    KUiccApplCmdReqOffset + SIZE_UICC_SB_CLIENT +
                    SIZE_UICC_SB_TRANSPARENT + sizeOfApplPathSubblock,
                    static_cast
                    <const TUiccWriteTransparent&>( aParams ).fileData );
                break;
                }
            case UICC_APPL_READ_LINEAR_FIXED:
                {
                numOfSubblocks = 3;
                // Create and append UICC_SB_CLIENT
                CreateUiccSbClient( isiMsg, KUiccApplCmdReqOffset );
                // Create and append UICC_SB_LINEAR_FIXED
                CreateUiccSbLinearFixed(
                    static_cast <const TUiccReadLinearFixed&>( aParams ),
                    isiMsg,
                    KUiccApplCmdReqOffset + SIZE_UICC_SB_CLIENT );
                // Create and append UICC_SB_APPL_PATH
                CreateUiccSbApplPath(
                    static_cast <const TUiccReadLinearFixed&>( aParams ),
                    isiMsg,
                    KUiccApplCmdReqOffset + SIZE_UICC_SB_CLIENT +
                    SIZE_UICC_SB_LINEAR_FIXED,
                    sizeOfApplPathSubblock );
                break;
                }
            case UICC_APPL_UPDATE_LINEAR_FIXED:
                {
                // UICC_SB_LINEAR_FIXED, UICC_SB_APPL_PATH, UICC_SB_FILE_DATA
                numOfSubblocks = 4;
                // Create and append UICC_SB_CLIENT
                CreateUiccSbClient( isiMsg, KUiccApplCmdReqOffset );
                // Create and append UICC_SB_LINEAR_FIXED
                CreateUiccSbLinearFixed(
                    static_cast <const TUiccWriteLinearFixed&>( aParams ),
                    isiMsg,
                    KUiccApplCmdReqOffset + SIZE_UICC_SB_CLIENT );
                // Create and append UICC_SB_APPL_PATH
                CreateUiccSbApplPath(
                    static_cast <const TUiccWriteLinearFixed&>( aParams ),
                    isiMsg,
                    KUiccApplCmdReqOffset + SIZE_UICC_SB_CLIENT +
                    SIZE_UICC_SB_LINEAR_FIXED,
                    sizeOfApplPathSubblock );
                // Create and append UICC_SB_FILE_DATA
                CreateUiccSbFileData(
                    isiMsg,
                    KUiccApplCmdReqOffset + SIZE_UICC_SB_CLIENT +
                    SIZE_UICC_SB_TRANSPARENT + sizeOfApplPathSubblock,
                    static_cast
                        <const TUiccWriteLinearFixed&>( aParams ).fileData);
                break;
                }
            case UICC_APPL_FILE_INFO:
                {
                numOfSubblocks = 1;
                // Create and append UICC_SB_APPL_PATH
                CreateUiccSbApplPath(
                    aParams,
                    isiMsg,
                    KUiccApplCmdReqOffset,
                    sizeOfApplPathSubblock );
                break;
                }
            case UICC_APPL_APDU_SEND:
                {
                numOfSubblocks = 3;
                // Create and append UICC_SB_CLIENT
                CreateUiccSbClient( isiMsg, KUiccApplCmdReqOffset, aApplType );
                // Create and append UICC_SB_APPL_PATH
                CreateUiccSbApplPath(
                    aParams,
                    isiMsg,
                    KUiccApplCmdReqOffset + SIZE_UICC_SB_CLIENT,
                    sizeOfApplPathSubblock );
                // Create and append UICC_SB_APDU
                const TUiccSendApdu* tmpPtr = static_cast<const TUiccSendApdu*>( &aParams );
                CreateUiccSbApdu(
                    isiMsg,
                    KUiccApplCmdReqOffset + SIZE_UICC_SB_CLIENT +
                    sizeOfApplPathSubblock,
                    tmpPtr->apdu );
                break;
                }
            default:
                {
                ret = KErrArgument;
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccApplCmdReq, unknown service type!" );
OstTrace0( TRACE_NORMAL, DUP2_CMMUICCMESSHANDLER_CREATEUICCAPPLCMDREQ, "CMmUiccMessHandler::CreateUiccApplCmdReq, unknown service type!" );
                break;
                }
            } // End of switch ( serviceType )

        if ( KErrNone == ret )
            {
            // Set number of subblocks
            isiMsg.Set8bit(
                ISI_HEADER_SIZE + UICC_APPL_CMD_REQ_OFFSET_NSB,
                numOfSubblocks );
            return( iPhoNetSender->Send( isiMsg.Complete() ) );
            }
        } // End of if ( NULL == iMessHandlerPrtList.At( trId ) )
    else
        {
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccApplCmdReq, cannot handle the request, server busy!" );
OstTrace0( TRACE_NORMAL, DUP1_CMMUICCMESSHANDLER_CREATEUICCAPPLCMDREQ, "CMmUiccMessHandler::CreateUiccApplCmdReq, cannot handle the request, server busy!" );
        ret = KErrServerBusy;
        }
    return ret;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CreateUiccApplicationReq
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CMmUiccMessHandler::CreateUiccApplicationReq(
    const TUiccParamsBase& aParams,
    TUint8 aServiceType,
    TUint8 aApplType )
    {
TFLOGSTRING2("TSY: CMmUiccMessHandler::CreateUiccApplicationReq, service type: %d", aServiceType );
OstTraceExt1( TRACE_NORMAL, CMMUICCMESSHANDLER_CREATEUICCAPPLICATIONREQ, "CMmUiccMessHandler::CreateUiccApplicationReq;aServiceType=%hhu", aServiceType );

    TInt ret (KErrGeneral);
    TUiccTrId trId( aParams.trId );
    TUint8 numOfSubblocks( 0 );

    // If there is the previous request ongoing (pointer was already set for
    // this operation)  we can't handle this request.
    if ( NULL == iMessHandlerPrtList.At( trId ) )
        {
        // Save pointer to message handler, it is needed when receiving
        // response for this operation
        iMessHandlerPrtList[trId] = aParams.messHandlerPtr;

        // Create the ISI message
        TIsiSend isiMsg( iPhoNetSender->SendBufferDes() );
        isiMsg.Set8bit( ISI_HEADER_OFFSET_RESOURCEID, PN_UICC );
        isiMsg.Set8bit(
        ISI_HEADER_SIZE + UICC_APPLICATION_REQ_OFFSET_MESSAGEID,
            UICC_APPLICATION_REQ );
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_APPLICATION_REQ_OFFSET_SERVICETYPE,
            aServiceType );

        switch ( aServiceType )
            {
            case UICC_APPL_LIST:
                {
                // No subblocks in this case
                break;
                }
            case UICC_APPL_HOST_ACTIVATE:
                {
                numOfSubblocks = 1;
                CreateUiccSbApplication(
                    isiMsg,
                    ISI_HEADER_SIZE + SIZE_UICC_APPLICATION_REQ,
                    aApplType );
                break;
                }
            default:
                {
                break;
                }
            }

        // Set transaction ID and number of subblocks to ISI message
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_APPLICATION_REQ_OFFSET_TRANSID,
            trId );
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_APPLICATION_REQ_OFFSET_NSB,
            numOfSubblocks );
        ret = iPhoNetSender->Send( isiMsg.Complete() );
        }
    else
        {
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccApplicationReq, cannot handle the request, server busy!" );
OstTrace0( TRACE_NORMAL, DUP1_CMMUICCMESSHANDLER_CREATEUICCAPPLICATIONREQ, "CMmUiccMessHandler::CreateUiccApplicationReq, cannot handle the request, server busy!" );
        ret = KErrServerBusy;
        }
    return ret;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetApplicationId
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TUint8 CMmUiccMessHandler::GetApplicationId() const
    {
TFLOGSTRING2("TSY: CMmUiccMessHandler::GetApplicationId, application ID: %d", iApplicationId );
OstTraceExt1( TRACE_NORMAL, CMMUICCMESSHANDLER_GETAPPLICATIONID, "CMmUiccMessHandler::GetApplicationId;aApplId=%hhu", iApplicationId );
    return iApplicationId;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetApplicationType
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TUint8 CMmUiccMessHandler::GetApplicationType() const
    {
TFLOGSTRING2("TSY: CMmUiccMessHandler::GetApplicationType, application type: %d", iApplicationType );
OstTraceExt1( TRACE_NORMAL, CMMUICCMESSHANDLER_GETAPPLICATIONTYPE, "CMmUiccMessHandler::GetApplicationType;aApplType=%hhu", iApplicationType );
    return iApplicationType;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetApplicationFileId
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
const TDesC8& CMmUiccMessHandler::GetApplicationFileId() const
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::GetApplicationFileId" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_GETAPPLICATIONFILEID, "CMmUiccMessHandler::GetApplicationFileId" );
    return iApplFileId;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetCardType
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TUint8 CMmUiccMessHandler::GetCardType() const
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::GetCardType" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_GETCARDTYPE, "CMmUiccMessHandler::GetCardType" );
    return iCardType;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetIsimApplicationStatus
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TUint8 CMmUiccMessHandler::GetIsimApplicationStatus() const
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::GetIsimApplicationStatus" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_GETISIMAPPLICATIONSTATUS, "CMmUiccMessHandler::GetIsimApplicationStatus" );
    return iIsimApplicationStatus;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::IsIsimApplicationFound
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CMmUiccMessHandler::IsIsimApplicationFound() const
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::IsIsimApplicationFound" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_ISISIMAPPLICATIONFOUND, "CMmUiccMessHandler::IsIsimApplicationFound" );
    return iIsimApplicationFound;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetAid
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
const RMobilePhone::TAID& CMmUiccMessHandler::GetAid() const
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::GetAid" );
OstTrace0( TRACE_NORMAL, DUP1_CMMUICCMESSHANDLER_GETAPPLICATIONFILEID, "CMmUiccMessHandler::GetApplicationFileId" );
    return iAid;
    }
// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CreateUiccSbApplPath
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::CreateUiccSbApplPath(
    const TUiccParamsBase& aParams,
    TIsiSend& aIsiMsg,
    TUint8 aMsgOffset,
    TUint8& aSizeOfSubblock )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccSbApplPath" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CREATEUICCSBAPPLPATH, "CMmUiccMessHandler::CreateUiccSbApplPath" );

    // UICC_SB_APPL_PATH subblock
    TBuf8<KUiccSbApplPathSize> uiccSbApplPathBuf( 0 );
    TIsiSubBlock uiccSbApplPath(
        uiccSbApplPathBuf,
        UICC_SB_APPL_PATH,
        EIsiSubBlockTypeId16Len16 );

    // File ID, 16-bit
    uiccSbApplPathBuf.Append( static_cast<TUint8>( aParams.fileId >> 8 ) );
    uiccSbApplPathBuf.Append( static_cast<TUint8>( aParams.fileId ) );
    // File ID SFI, 8-bit
    uiccSbApplPathBuf.Append( aParams.fileIdSfi );
    // Filler, 8-bit
    uiccSbApplPathBuf.Append( KUiccPadding );
    // Length of the DF path, 8-bit
    uiccSbApplPathBuf.Append( aParams.filePath.Length() );
    // Filler, 8-bit
    uiccSbApplPathBuf.Append( KUiccPadding );
    // Application file ID depends on card type, USIM or SIM
    uiccSbApplPathBuf.Append( aParams.filePath );
    // Append subblock to ISI message
    aIsiMsg.CopyData( aMsgOffset, uiccSbApplPath.CompleteSubBlock() );

    aSizeOfSubblock = uiccSbApplPathBuf.Length();
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CreateUiccSbClient
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::CreateUiccSbClient(
    TIsiSend& aIsiMsg,
    TUint8 aMsgOffset,
    const TUint8 aApplType )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccSbClient" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CREATEUICCSBCLIENT, "CMmUiccMessHandler::CreateUiccSbClient" );

    // UICC_SB_CLIENT subblock
    TBuf8<SIZE_UICC_SB_CLIENT> uiccSbClientBuf( 0 );
    TIsiSubBlock uiccSbClient(
        uiccSbClientBuf,
        UICC_SB_CLIENT,
        EIsiSubBlockTypeId16Len16 );

    // 3x filler
    uiccSbClientBuf.Append( KUiccPadding );
    uiccSbClientBuf.Append( KUiccPadding );
    uiccSbClientBuf.Append( KUiccPadding );

    if( UICC_APPL_TYPE_UICC_USIM == aApplType ||
        UICC_APPL_TYPE_ICC_SIM == aApplType )
        {
        // Client ID
        uiccSbClientBuf.Append( iUiccClientId );

        // Append subblock to ISI message
        aIsiMsg.CopyData( aMsgOffset, uiccSbClient.CompleteSubBlock() );
        }
    else if( UICC_APPL_TYPE_UICC_ISIM == aApplType )
        {
        // Client ID
        uiccSbClientBuf.Append( iUiccIsimClientId );

        // Append subblock to ISI message
        aIsiMsg.CopyData( aMsgOffset, uiccSbClient.CompleteSubBlock() );
        }
    else
        {
TFLOGSTRING2("TSY: CMmUiccMessHandler::CreateUiccSbClient: unknown appl type: 0x%x", aApplType );
OstTrace1( TRACE_NORMAL, DUP1_CMMUICCMESSHANDLER_CREATEUICCSBCLIENT, "CMmUiccMessHandler::CreateUiccSbClient: unknown appl type: 0x%x", aApplType );
        }
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CreateUiccSbTransparent
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::CreateUiccSbTransparent(
    const TUiccReadTransparent& aParams,
    TIsiSend& aIsiMsg,
    TUint8 aMsgOffset )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccSbTransparent" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CREATEUICCSBTRANSPARENT, "CMmUiccMessHandler::CreateUiccSbTransparent" );

    // UICC_SB_TRANSPARENT subblock
    TBuf8<SIZE_UICC_SB_TRANSPARENT> uiccSbTransparentBuf( 0 );
    TIsiSubBlock uiccSbTransparent(
        uiccSbTransparentBuf,
        UICC_SB_TRANSPARENT,
        EIsiSubBlockTypeId16Len16 );

    // File offset, 16-bit
    uiccSbTransparentBuf.Append(
        static_cast<TInt8>( aParams.dataOffset >> 8 ) );
    uiccSbTransparentBuf.Append( static_cast<TInt8>( aParams.dataOffset ) );
    // Data amount, 16-bit, only used in read case
    uiccSbTransparentBuf.Append(
        static_cast<TInt8>( aParams.dataAmount >> 8 ) );
    uiccSbTransparentBuf.Append( static_cast<TInt8>( aParams.dataAmount ) );

    // Append subblock to ISI message
    aIsiMsg.CopyData( aMsgOffset, uiccSbTransparent.CompleteSubBlock() );
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CreateUiccSbLinearFixed
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::CreateUiccSbLinearFixed(
    const TUiccReadLinearFixed& aParams,
    TIsiSend& aIsiMsg,
    TUint8 aMsgOffset )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccSbLinearFixed" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CREATEUICCSBLINEARFIXED, "CMmUiccMessHandler::CreateUiccSbLinearFixed" );

    // UICC_SB_LINEAR_FIXED subblock
    TBuf8<SIZE_UICC_SB_LINEAR_FIXED> uiccSbLinearFixedBuf( 0 );
    TIsiSubBlock uiccSbLinearFixed(
        uiccSbLinearFixedBuf,
        UICC_SB_LINEAR_FIXED,
        EIsiSubBlockTypeId16Len16 );

    // File record, 8-bit
    uiccSbLinearFixedBuf.Append( aParams.record );
    // Record offset in bytes, 8-bit
    uiccSbLinearFixedBuf.Append( static_cast<TInt8>( aParams.dataOffset ) );
    // Data amount, 8-bit
    uiccSbLinearFixedBuf.Append( static_cast<TInt8>( aParams.dataAmount ) );

    // Append subblock to ISI message
    aIsiMsg.CopyData( aMsgOffset, uiccSbLinearFixed.CompleteSubBlock() );
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CreateUiccSbFileData
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::CreateUiccSbFileData(
    TIsiSend& aIsiMsg,
    TUint8 aMsgOffset,
    const TDesC8& aUpdateData
    )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccSbFileData" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CREATEUICCSBFILEDATA, "CMmUiccMessHandler::CreateUiccSbFileData" );

    // UICC_SB_FILE_DATA subblock
    TBuf8<KUiccSbFileDataSize> uiccSbFileDataBuf( 0 );
    TIsiSubBlock uiccSbFileData(
        uiccSbFileDataBuf,
        UICC_SB_FILE_DATA,
        EIsiSubBlockTypeId16Len16 );

    // Length of file data, 32-bit
    TInt length( aUpdateData.Length() );
    uiccSbFileDataBuf.Append( static_cast<TInt8>( length >> 24 ) );
    uiccSbFileDataBuf.Append( static_cast<TInt8>( length >> 16 ) );
    uiccSbFileDataBuf.Append( static_cast<TInt8>( length >> 8 ) );
    uiccSbFileDataBuf.Append( static_cast<TInt8>( length ) );

    // Data
    uiccSbFileDataBuf.Append( aUpdateData );

    // Append subblock to ISI message
    aIsiMsg.CopyData( aMsgOffset, uiccSbFileData.CompleteSubBlock() );
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CreateUiccSbApplication
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::CreateUiccSbApplication(
    TIsiSend& aIsiMsg,
    TUint8 aMsgOffset,
    TUint8 aApplType )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccSbApplication" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CREATEUICCSBAPPLICATION, "CMmUiccMessHandler::CreateUiccSbApplication" );

    // SIZE_UICC_SB_APPLICATION_STR
    TBuf8<SIZE_UICC_SB_APPLICATION> uiccSbApplicationBuf( 0 );
    TIsiSubBlock uiccSbApplication(
        uiccSbApplicationBuf,
        UICC_SB_APPLICATION,
        EIsiSubBlockTypeId16Len16 );

    // 2x filler
    uiccSbApplicationBuf.Append( KUiccPadding );
    uiccSbApplicationBuf.Append( KUiccPadding );

    if( UICC_APPL_TYPE_UICC_USIM == aApplType ||
        UICC_APPL_TYPE_ICC_SIM == aApplType )
        {
        // Application type (8-bit)
        uiccSbApplicationBuf.Append( iApplicationType );

        // Application ID (8-bit)
        uiccSbApplicationBuf.Append( iApplicationId );

        // Append subblock to ISI message
        aIsiMsg.CopyData( aMsgOffset, uiccSbApplication.CompleteSubBlock() );
        }
    else if( UICC_APPL_TYPE_UICC_ISIM == aApplType )
        {
        // Application type (8-bit)
        uiccSbApplicationBuf.Append( aApplType );

        // Application ID (8-bit)
        uiccSbApplicationBuf.Append( iIsimApplicationId );

        // Append subblock to ISI message
        aIsiMsg.CopyData( aMsgOffset, uiccSbApplication.CompleteSubBlock() );
        }
    else
        {
TFLOGSTRING2("TSY: CMmUiccMessHandler::CreateUiccSbApplication: unknown application type: 0x%x", aApplType );
OstTrace1( TRACE_NORMAL, DUP1_CMMUICCMESSHANDLER_CREATEUICCSBAPPLICATION, "CMmUiccMessHandler::CreateUiccSbApplication: unknown application type: 0x%x", aApplType );
        }
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetFileData
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
const TPtrC8 CMmUiccMessHandler::GetFileData( const TIsiReceiveC& aIsiMsg )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::GetFileData" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_GETFILEDATA, "CMmUiccMessHandler::GetFileData" );

    TPtrC8 data( KNullDesC8 );

    // File data from UICC_SB_FILE_DATA
    TUint uiccSbFileDataOffset( 0 );
    if ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
        ISI_HEADER_SIZE + SIZE_UICC_APPL_CMD_RESP,
        UICC_SB_FILE_DATA,
        EIsiSubBlockTypeId16Len16,
        uiccSbFileDataOffset ) )
        {
        TInt fileDataLength( aIsiMsg.Get32bit(
            uiccSbFileDataOffset + UICC_SB_FILE_DATA_OFFSET_DATALENGTH ) );
        data.Set( aIsiMsg.GetData(
            uiccSbFileDataOffset + UICC_SB_FILE_DATA_OFFSET_DATA,
            fileDataLength ) );
        }
    return data;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::HandleUiccResp
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TUint8 CMmUiccMessHandler::HandleUiccResp( const TIsiReceiveC& aIsiMsg )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::HandleUiccResp" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_HANDLEUICCRESP, "CMmUiccMessHandler::HandleUiccResp" );

    TUint8 serverStatus( UICC_STATUS_NOT_READY );
    // Check the service type
    TUint8 serviceType( aIsiMsg.Get8bit(
        ISI_HEADER_SIZE + UICC_RESP_OFFSET_SERVICETYPE ) );
    if ( UICC_STATUS_GET  == serviceType )
        {
        // Get the status
        TUint8 status(
            aIsiMsg.Get8bit( ISI_HEADER_SIZE + UICC_RESP_OFFSET_STATUS ) );
        if ( UICC_STATUS_OK == status )
            {
            // Get the UICC server status
            serverStatus = aIsiMsg.Get8bit(
                ISI_HEADER_SIZE + UICC_RESP_OFFSET_SERVERSTATUS );
            }
        }
    return serverStatus;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::HandleUiccApplicationResp
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CMmUiccMessHandler::HandleUiccApplicationResp(
    const TIsiReceiveC& aIsiMsg )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::HandleUiccApplicationResp" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_HANDLEUICCAPPLICATIONRESP, "CMmUiccMessHandler::HandleUiccApplicationResp" );

    TInt ret( KErrNone );
    // Get service type and status
    TUint8 serviceType( aIsiMsg.Get8bit(
        ISI_HEADER_SIZE + UICC_APPLICATION_RESP_OFFSET_SERVICETYPE ) );
    TUint8 status( aIsiMsg.Get8bit(
        ISI_HEADER_SIZE + UICC_APPLICATION_RESP_OFFSET_STATUS ) );
    iCardType = aIsiMsg.Get8bit(
        ISI_HEADER_SIZE + UICC_APPLICATION_RESP_OFFSET_CARDTYPE );
    TUint8 trId( aIsiMsg.Get8bit(
        ISI_HEADER_SIZE + UICC_APPLICATION_RESP_OFFSET_TRANSID ) );
    TUint16 startIndex( ISI_HEADER_SIZE + SIZE_UICC_APPLICATION_RESP );

    if ( UICC_STATUS_OK == status )
        {
        switch( serviceType )
            {
            case UICC_APPL_LIST:
                {
                // Check if UICC_SB_APPL_DATA_OBJECT is included => UICC application
                TUint uiccSbApplDataObjectOffset( 0 );
                TUint8 applicationType( 0 );
                TUint16 sbLen( 0 );

                TBool usimApplFound( EFalse );

                while ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
                    startIndex,
                    UICC_SB_APPL_DATA_OBJECT,
                    EIsiSubBlockTypeId16Len16,
                    uiccSbApplDataObjectOffset ) )
                    {
                    applicationType = aIsiMsg.Get8bit(
                        uiccSbApplDataObjectOffset +
                        UICC_SB_APPL_DATA_OBJECT_OFFSET_APPLICATIONTYPE );

                    sbLen = aIsiMsg.Get16bit(
                        uiccSbApplDataObjectOffset +
                        UICC_SB_APPL_DATA_OBJECT_OFFSET_SBLEN );

                    if ( UICC_APPL_TYPE_UICC_USIM == applicationType &&
                        EFalse == usimApplFound )
                        {
                        iApplicationType = applicationType;

                        iApplicationId = aIsiMsg.Get8bit(
                            uiccSbApplDataObjectOffset +
                            UICC_SB_APPL_DATA_OBJECT_OFFSET_APPLID );
                        iApplicationStatus = aIsiMsg.Get8bit(
                            uiccSbApplDataObjectOffset +
                            UICC_SB_APPL_DATA_OBJECT_OFFSET_APPLSTATUS );

                        TUint8 length( aIsiMsg.Get8bit(
                            uiccSbApplDataObjectOffset +
                            UICC_SB_APPL_DATA_OBJECT_OFFSET_APPLDOLEN ) );

                        // Application data object contains EF dir data,
                        // 5 bytes are mandatory. See TS 102.221 V7.11.0 table 13.2
                        if ( 5 <= length )
                            {
                            TPtrC8 applDataObject( aIsiMsg.GetData(
                                uiccSbApplDataObjectOffset +
                                UICC_SB_APPL_DATA_OBJECT_OFFSET_APPLDO,
                                length ) );
                            // Length of AID is located in index 3
                            TUint8 aidLength( applDataObject[3] );
                            // Copy actual AID
                            iAid.Copy( applDataObject.Mid( 4, aidLength ) );
                            }

                        usimApplFound = ETrue;
                        }
                    else if( UICC_APPL_TYPE_UICC_ISIM == applicationType &&
                        EFalse == iIsimApplicationFound )
                        {
                        iIsimApplicationFound = ETrue;

                        iIsimApplicationId = aIsiMsg.Get8bit(
                            uiccSbApplDataObjectOffset +
                            UICC_SB_APPL_DATA_OBJECT_OFFSET_APPLID );
                        iIsimApplicationStatus = aIsiMsg.Get8bit(
                            uiccSbApplDataObjectOffset +
                            UICC_SB_APPL_DATA_OBJECT_OFFSET_APPLSTATUS );
                        }
                    startIndex = uiccSbApplDataObjectOffset + sbLen;
                    }
                if ( EFalse == usimApplFound ) // ICC application
                    {
                    iApplicationType = UICC_APPL_TYPE_ICC_SIM;
                    iApplicationId =  UICC_APPL_ID_UNKNOWN;
                    // Application file ID for GSM
                    TBuf8<2> gsmFileId;
                    gsmFileId.Append( 0x7F );
                    gsmFileId.Append( 0x20 );
                    iApplFileId.Copy( gsmFileId );
                    }
                // Activate the application
                if ( UICC_STATUS_APPL_ACTIVE != iApplicationStatus )
                    {
                    TUiccParamsBase params;
                    params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
                    params.trId = ETrIdActivateUiccApplication;
                    ret = CreateUiccApplicationReq( params, UICC_APPL_HOST_ACTIVATE );
                    }
                break;
                }
            case UICC_APPL_HOST_ACTIVATE:
                {
                TUint uiccSbClientOffset( 0 );
                if ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
                    startIndex,
                    UICC_SB_CLIENT,
                    EIsiSubBlockTypeId16Len16,
                    uiccSbClientOffset ) )
                    {
                    if( ETrIdActivateUiccApplication == trId )
                        {
                        iUiccClientId = aIsiMsg.Get8bit(
                            uiccSbClientOffset +
                            UICC_SB_CLIENT_OFFSET_CLIENTID );
                        }
                    else if( ETrIdActivateIsimApplication == trId )
                        {
                        iUiccIsimClientId = aIsiMsg.Get8bit(
                            uiccSbClientOffset +
                            UICC_SB_CLIENT_OFFSET_CLIENTID );
                        }
                    }
                // UICC_SB_FCI contains PIN key references
                TUint uiccSbFciOffset( 0 );
                if ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
                    ISI_HEADER_SIZE + SIZE_UICC_APPLICATION_RESP,
                    UICC_SB_FCI,
                    EIsiSubBlockTypeId16Len16,
                    uiccSbFciOffset ) )
                    {
                    TInt fileDataLength( aIsiMsg.Get16bit(
                        uiccSbFciOffset + UICC_SB_FCI_OFFSET_FCILENGTH ) );
                    if ( 0 < fileDataLength )
                        {
                        StorePinKeyReferences( aIsiMsg.GetData(
                            uiccSbFciOffset + UICC_SB_FCI_OFFSET_FCI,
                            fileDataLength ) );
                        }
                    }
                // In case of ICC there is two UICC_SB_CHV subblocks
                // that contain PIN IDs for ICC application
                TUint uiccSbChvOffset( 0 );
                while ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
                    startIndex,
                    UICC_SB_CHV,
                    EIsiSubBlockTypeId16Len16,
                    uiccSbChvOffset ) )
                    {
                    TUint8 chvQualifier( aIsiMsg.Get8bit(
                        uiccSbChvOffset +
                        UICC_SB_CHV_OFFSET_CHVQUALIFIER ) );
                    if ( UICC_CHV1 == chvQualifier ) // PIN1
                        {
                        iPin1Id = aIsiMsg.Get8bit(
                            uiccSbChvOffset + UICC_SB_CHV_OFFSET_PINID );
                        }
                    else // PIN2
                        {
                        iPin2Id = aIsiMsg.Get8bit(
                            uiccSbChvOffset + UICC_SB_CHV_OFFSET_PINID );
                        }
                    startIndex = uiccSbChvOffset + SIZE_UICC_SB_CHV;
                    }
                break;
                }
            default:
                {
                break;
                }
            }
        }
    else // if ( UICC_STATUS_OK == status )
        {
        ret = KErrGeneral;
        TUint8 details( aIsiMsg.Get8bit(
            ISI_HEADER_SIZE + UICC_APPLICATION_RESP_OFFSET_DETAILS ) );
        }
    return ret;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetFileFCI
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
const TPtrC8 CMmUiccMessHandler::GetFileFCI( const TIsiReceiveC& aIsiMsg )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::GetFileFCI");
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_GETFILEFCI, "CMmUiccMessHandler::GetFileFCI" );

    TPtrC8 data( KNullDesC8 );
    TUint uiccSbFileDataOffset( 0 );

    if ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
        ISI_HEADER_SIZE + SIZE_UICC_APPL_CMD_RESP,
        UICC_SB_FCI,
        EIsiSubBlockTypeId16Len16,
        uiccSbFileDataOffset ) )
        {
        TInt fileDataLength( aIsiMsg.Get16bit(
            uiccSbFileDataOffset + UICC_SB_FCI_OFFSET_FCILENGTH ) );
        data.Set( aIsiMsg.GetData(
            uiccSbFileDataOffset + UICC_SB_FCI_OFFSET_FCI,
            fileDataLength ) );
        }
    return data;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CreateUiccConnectorReq
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CMmUiccMessHandler::CreateUiccConnectorReq(
    const TUiccParamsBase& aParams )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccConnectorReq");
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CREATEUICCCONNREQ, "CMmUiccMessHandler::CreateUiccConnectorReq" );

    TInt ret (KErrGeneral);
    TInt trId( aParams.trId );
    TInt8 serviceType( aParams.serviceType );
    TUint8 numOfSubblocks( 0 );

    // If there is the previous request ongoing (pointer was already set for
    // this operation)  we can't handle this request.
    if ( NULL == iMessHandlerPrtList.At( trId ) )
        {
        // Save pointer to message handler, it is needed when receiving
        // response for this operation
        iMessHandlerPrtList[trId] = aParams.messHandlerPtr;

        // Create UICC_CONNECTOR_REQ message
        TIsiSend isiMsg( iPhoNetSender->SendBufferDes() );
        isiMsg.Set8bit( ISI_HEADER_OFFSET_RESOURCEID, PN_UICC );
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_CONNECTOR_REQ_OFFSET_TRANSID, trId );
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_CONNECTOR_REQ_OFFSET_MESSAGEID,
            UICC_CONNECTOR_REQ );
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_CONNECTOR_REQ_OFFSET_SERVICETYPE,
            serviceType );

        switch( serviceType )
            {
            case UICC_CONNECT:
                {
                // Set status to not active, since UICC connect request
                // resets smartcard.
                iApplicationStatus = UICC_STATUS_APPL_NOT_ACTIVE;

                // Sets flag, that when the response for this request is
                // received traid is not removed from the list, until
                // UICC_APPLICATION_IND is received.
                iDoNotRemoveTransactionID = ETrue;
                break;
                }
            default:
                break;
            }

        isiMsg.Set8bit(
                ISI_HEADER_SIZE + UICC_CONNECTOR_REQ_OFFSET_NSB,
                numOfSubblocks );

        return( iPhoNetSender->Send( isiMsg.Complete() ) );
        }
    else
        {
        ret = KErrServerBusy;
        }
    return ret;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CreateUiccApduReq
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CMmUiccMessHandler::CreateUiccApduReq( const TUiccParamsApduReq& aParams )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccApduReq");
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CREATEUICCAPDUREQ, "CMmUiccMessHandler::CreateUiccApduReq" );

    TInt ret (KErrGeneral);
    TInt trId( aParams.trId );
    TInt8 serviceType( aParams.serviceType );
    TUint8 numOfSubblocks( 0 );
    TUint8 action( aParams.action );

    // If there is the previous request ongoing (pointer was already set for
    // this operation)  we can't handle this request.
    if ( NULL == iMessHandlerPrtList.At( trId ) )
        {
        // Save pointer to message handler, it is needed when receiving
        // response for this operation
        iMessHandlerPrtList[trId] = aParams.messHandlerPtr;
        // Create UICC_APDU_REQ
        TIsiSend isiMsg( iPhoNetSender->SendBufferDes() );
        isiMsg.Set8bit( ISI_HEADER_OFFSET_RESOURCEID, PN_UICC );
        isiMsg.Set8bit( ISI_HEADER_SIZE + UICC_APDU_REQ_OFFSET_TRANSID, trId );
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_APDU_REQ_OFFSET_MESSAGEID,
            UICC_APDU_REQ );
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_APDU_REQ_OFFSET_SERVICETYPE,
            serviceType );

        switch( serviceType )
            {
            case UICC_APDU_CONTROL:
                {
                if( UICC_CONTROL_CARD_ACTIVATE == action )
                    {
                    // Sets flag, that when the response for this request is
                    // received traid is not removed from the list, until
                    // UICC_APDU_RESET_IND is received.
                    iDoNotRemoveTransactionID = ETrue;
                    }
                // Create subblock UICC_SB_APDU_ACTIONS.
                CreateUiccSbApduActions(
                    isiMsg,
                    action );
                numOfSubblocks = 1;
                break;
                }
            case UICC_APDU_SEND:
                {
                // create SB UICC_SB_APDU.
                CreateUiccSbApdu(
                    isiMsg,
                    KUiccApduReqSubblockOffset,
                    aParams .apduData );
                numOfSubblocks = 1;
                break;
                }
            default:
                {
                break;
                }
            }

        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_APDU_REQ_OFFSET_NSB,
            numOfSubblocks );

        ret = iPhoNetSender->Send( isiMsg.Complete() );
        }
    else
        {
        ret = KErrServerBusy;
        }
    return ret;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CreateUiccSbApduActions
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::CreateUiccSbApduActions(
    TIsiSend& aIsiMsg,
    TUint8 aAction )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccSbApduActions");
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CREATEUICCASBPDUACTION, "CMmUiccMessHandler::CreateUiccSbApduActions" );

    // SIZE_UICC_SB_APPLICATION_STR
    TBuf8<SIZE_UICC_SB_APDU_ACTIONS> uiccSbApduActionBuf( 0 );
    TIsiSubBlock uiccSbApduAction(
        uiccSbApduActionBuf,
        UICC_SB_APDU_ACTIONS,
        EIsiSubBlockTypeId16Len16 );

    // Action
    uiccSbApduActionBuf.Append( aAction );
    // 3x filler
    uiccSbApduActionBuf.Append( KUiccPadding );
    uiccSbApduActionBuf.Append( KUiccPadding );
    uiccSbApduActionBuf.Append( KUiccPadding );

    // Append subblock to ISI message
    aIsiMsg.CopyData(
        KUiccApduReqSubblockOffset,
        uiccSbApduAction.CompleteSubBlock() );
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetAPduData
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
const TPtrC8 CMmUiccMessHandler::GetApduData( const TIsiReceiveC& aIsiMsg )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::GetApduData");
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_GETAPDUDATA, "CMmUiccMessHandler::GetApduData" );

    TPtrC8 data( KNullDesC8 );

    // File data from UICC_SB_APDU
    TUint uiccSbApduOffset( 0 );
    if ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
        ISI_HEADER_SIZE + SIZE_UICC_APPL_CMD_REQ,
        UICC_SB_APDU,
        EIsiSubBlockTypeId16Len16,
        uiccSbApduOffset ) )
        {
        TInt apduDataLength( aIsiMsg.Get16bit(
            uiccSbApduOffset + KUiccSbApduLengthOffset ) );

        data.Set( aIsiMsg.GetData(
            uiccSbApduOffset + KUiccSbApduDataOffset,
            apduDataLength ) );
        }
    return data;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CreateUiccSbApdu
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::CreateUiccSbApdu(
        TIsiSend& aIsiMsg,
        TUint8 aMsgOffset,
        const TDesC8& aAPDUData)
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccSbApdu" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CREATESBAPDU, "CMmUiccMessHandler::CreateUiccSbApdu" );

    // UICC_SB_APDU subblock
    TBuf8<KUiccSbApduSize> uiccSbApduBuf( 0 );
    TIsiSubBlock uiccSbApdu(
        uiccSbApduBuf,
        UICC_SB_APDU,
        EIsiSubBlockTypeId16Len16 );

    // Force APDU command
    uiccSbApduBuf.Append( UICC_APDU_CMD_FORCE_NOT_USED );

    // Filler KUiccPadding
    uiccSbApduBuf.Append( KUiccPadding );

    // Length of APDU command data, 16-bit
    TInt length( aAPDUData.Length() );
    uiccSbApduBuf.Append( static_cast<TInt8>( length >> 8 ) );
    uiccSbApduBuf.Append( static_cast<TInt8>( length ) );

    // Data
    uiccSbApduBuf.Append( aAPDUData );

    // Append subblock to ISI message
    aIsiMsg.CopyData( aMsgOffset, uiccSbApdu.CompleteSubBlock() );
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CreateUiccCardReq
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CMmUiccMessHandler::CreateUiccCardReq( const TUiccParamsBase& aParams )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::CreateUiccCardReq" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CREATECARDREQ, "CMmUiccMessHandler::CreateUiccCardReq" );

    TInt ret ( KErrGeneral );
    TInt trId( aParams.trId );
    TInt8 serviceType( aParams.serviceType );

    // If there is the previous request ongoing (pointer was already set for
    // this operation)  we can't handle this request.
    if ( NULL == iMessHandlerPrtList.At( trId ) )
        {
        // Save pointer to message handler, it is needed when receiving
        // respone for this operation
        iMessHandlerPrtList[trId] = aParams.messHandlerPtr;

        // Create UICC_CARD_REQ message
        TIsiSend isiMsg( iPhoNetSender->SendBufferDes() );
        isiMsg.Set8bit( ISI_HEADER_OFFSET_RESOURCEID, PN_UICC );
        isiMsg.Set8bit(
            ISI_HEADER_SIZE + UICC_CARD_REQ_OFFSET_TRANSID,
            trId );
        isiMsg.Set8bit( ISI_HEADER_SIZE + UICC_CARD_REQ_OFFSET_MESSAGEID,
            UICC_CARD_REQ );
        isiMsg.Set8bit( ISI_HEADER_SIZE + UICC_CARD_REQ_OFFSET_SERVICETYPE,
            serviceType );
        isiMsg.Set8bit( ISI_HEADER_SIZE + UICC_CARD_REQ_OFFSET_CARDTYPE,
            iCardType );

        return( iPhoNetSender->Send( isiMsg.Complete() ) );
        }
    else
        {
        ret = KErrServerBusy;
        }
    return ret;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::InitializeSimServiceTableCache
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::InitializeSimServiceTableCache()
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::InitializeSimServiceTableCache" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_INITIALIZESIMSERVICETABLECACHE, "CMmUiccMessHandler::InitializeSimServiceTableCache" );

    // Set parameters for UICC_APPL_CMD_REQ message
    TUiccReadTransparent params;
    params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
    params.trId = ETrIdSstCache;
    params.dataAmount = 0;
    params.dataOffset = 0;
    params.fileId = KElemSimServiceTable;

    // If card type is UICC, we need to read EFust, otherwise EFsst
    // EFust contains SFI identifier (value is 4), but EFsst doesn't
    // contain SFI, so in that case we need to use UICC_SFI_NOT_PRESENT
    params.fileIdSfi = iCardType == UICC_CARD_TYPE_UICC ? 4 : UICC_SFI_NOT_PRESENT;
    params.serviceType = UICC_APPL_READ_TRANSPARENT;

    // File id path
    params.filePath.Append( KMasterFileId >> 8 );
    params.filePath.Append( KMasterFileId );
    params.filePath.Append( GetApplicationFileId() );

    CreateUiccApplCmdReq( params );
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::SimServiceTableCacheResp
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::SimServiceTableCacheResp(
    TInt aStatus,
    const TDesC8& aFileData )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::SimServiceTableCacheResp" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_SIMSERVICETABLECACHERESP, "CMmUiccMessHandler::SimServiceTableCacheResp" );

    if ( UICC_STATUS_OK == aStatus )
        {
        if ( UICC_CARD_TYPE_UICC == iCardType )
            {
            // fill iUstFile
            iUSTFile.Copy( aFileData );
            }
        else if ( UICC_CARD_TYPE_ICC == iCardType )
            {
            // fill iSstFile
            iSSTFile.Copy( aFileData );
            }
        else
            {
TFLOGSTRING("TSY: CMmUiccMessHandler::SimServiceTableCacheResp unknown card type, cache not done" );
OstTrace0( TRACE_NORMAL, DUP1_CMMUICCMESSHANDLER_SIMSERVICETABLECACHERESP, "CMmUiccMessHandler::SimServiceTableCacheResp unknown card type, cache not done" );
            }
        }
    else
        {
TFLOGSTRING2("TSY: CMmUiccMessHandler::SimServiceTableCacheResp: reading failed (0x%x)", aStatus );
OstTrace1( TRACE_NORMAL, DUP2_CMMUICCMESSHANDLER_SIMSERVICETABLECACHERESP, "CMmUiccMessHandler::SimServiceTableCacheResp: reading failed (%x)", aStatus );
        }

    //Complete Notify SIM Ready
    iMessageRouter->Complete(
        EMmTsyBootNotifySimStatusReadyIPC,
        KErrNone );
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetServiceStatus
// (other items were commented in a header).
//
TBool CMmUiccMessHandler::GetServiceStatus( TUint8 aServiceNo )
    {
TFLOGSTRING2("TSY: CMmUiccMessHandler::GetServiceStatus for card: ox%x", iCardType );
OstTrace1( TRACE_NORMAL, CMMUICCMESSHANDLER_GETSERVICESTATUS, "CMmUiccMessHandler::GetServiceStatus for card: ox%x", iCardType );

    TBool ret( EFalse );

    if( UICC_CARD_TYPE_UICC == iCardType )
        {
        // card type UICC, so service status info is in
        // EFust. Service info is coded as one bit,
        // for example first byte contains services 1-8 as:
        // bit:        b8  b7  b6  b5  b4  b3  b2  b1
        // service no: 08  07  06  05  04  03  02  01
        // If bit is 1, service is supported
        // For more info about EFust, see 3GPP spec 31.102

        // let's calculate index to get correct byte
        // which contains info about service requested
        TUint8 index( ( aServiceNo - 1 ) / 8 );

        //let's calculate the bit number which contains
        // service info
        TUint8 bit( ( aServiceNo - 1 ) % 8 );

        // form mask to get is service supported or not
        TUint8 mask( 1<<bit );

        if( iUSTFile.Length() > index )
            {
            // If result is > 0, service is supported
            if( iUSTFile[index] & mask )
                {
TFLOGSTRING2("TSY: CMmUiccMessHandler::GetServiceStatus: UICC service (%d) supported", aServiceNo );
OstTrace1( TRACE_NORMAL, DUP1_CMMUICCMESSHANDLER_GETSERVICESTATUS, "CMmUiccMessHandler::GetServiceStatus: UICC service (%d) supported", aServiceNo );
                ret = ETrue;
                }
            }
        }
    else if( UICC_CARD_TYPE_ICC == iCardType )
        {
        // card type ICC, so service status info is in
        // EFsst. Service info is coded as two bits,
        // for example first byte contains services 1-4 as:
        // bit:        b8  b7  b6  b5  b4  b3  b2  b1
        // service no: 04  04  03  03  02  02  01  01

        // first bit describes is service allocated
        // second bit describes is service activated
        // for example service no 4: first bit is b7
        // and second bit is b8. Both bits needs to be
        // 1 so that service is supported. For more
        // info about EFsst, see 3GPP spec 51.011

        // let's calculate index to get correct byte
        // which contains info about service requested
        TUint8 index( ( aServiceNo - 1 ) / 4 );

        //let's calculate the bit number which contains
        // service info
        TUint8 bit( ( aServiceNo - 1 ) % 4 );

        // form mask to get is service supported or not.
        TUint8 mask( 3<<( bit * 2 ) );

        if( iSSTFile.Length() > index )
            {
            // If both bits are 1, service is supported
            if( ( iSSTFile[index] & mask ) == mask )
                {
TFLOGSTRING2("TSY: CMmUiccMessHandler::GetServiceStatus: ICC service (%d) supported", aServiceNo );
OstTrace1( TRACE_NORMAL, DUP2_CMMUICCMESSHANDLER_GETSERVICESTATUS, "CMmUiccMessHandler::GetServiceStatus: ICC service (%d) supported", aServiceNo );
                ret = ETrue;
                }
            }
        }
    return ret;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::ProcessUiccMsg
// Handles data received from UICC server
// -----------------------------------------------------------------------------
//
TInt CMmUiccMessHandler::ProcessUiccMsg(
    TInt aTraId,
    TInt aStatus,
    const TDesC8& aFileData )
    {
TFLOGSTRING3("TSY: CMmUiccMessHandler::ProcessUiccMsg, transaction ID: %d, status: %d", aTraId, aStatus );
OstTrace1( TRACE_NORMAL, CMMUICCMESSHANDLER_PROCESSUICCMSG, "CMmUiccMessHandler::ProcessUiccMsg, transaction ID: %d", aTraId );
OstTrace1( TRACE_NORMAL, DUP2_CMMUICCMESSHANDLER_PROCESSUICCMSG, "CMmUiccMessHandler::ProcessUiccMsg, status: %d", aStatus );

    TInt ret( KErrNone );

    switch( aTraId )
        {
        case ETrIdSstCache:
            {
            SimServiceTableCacheResp( aStatus, aFileData );
            break;
            }
        case ETrIdCphsCache:
            {
            CphsInformationCacheResp( aStatus, aFileData );
            break;
            }
        default:
            {
TFLOGSTRING("TSY: CMmUiccMessHandler::ProcessUiccMsg, unknown transaction ID" );
OstTrace0( TRACE_NORMAL, DUP1_CMMUICCMESSHANDLER_PROCESSUICCMSG, "CMmUiccMessHandler::ProcessUiccMsg, unknown transaction ID" );
            break;
            }
        }

    return ret;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::StorePinKeyReferences
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::StorePinKeyReferences( const TDesC8& aFileData )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::StorePinKeyReferences" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_STOREPINKEYREFERENCES, "CMmUiccMessHandler::StorePinKeyReferences" );
    // See ETSI TS 102 221 V7.11.0 (2008-07)chapter 9.5.2
    // There is only one PIN1/PIN2/UPIN per application
    TUint8 lengthOfPs( aFileData[3] ); // Number of PS bytes is in index 3

    // Get PS_DO for PIN statuses
    TPtrC8 psDo;
    psDo.Set( aFileData.Mid( 4, lengthOfPs ) );

    // Update index to point the first PIN
    TUint8 index( 4 + lengthOfPs );
    // Copy PIN related data to new buffer
    TPtrC8 pinDataBuffer;
    pinDataBuffer.Set( aFileData.Mid( index ) );
    TInt length( pinDataBuffer.Length() );
    TUint8 pinId( 0 );
    TUint8 orderNum( 0 ); // Used for shifting PIN status byte
    TBool upinExists( EFalse );
    TBool pin1Active( EFalse );

    index = 0; // Start of new buffer
    while( length )
        {
        // Check if usage qualifier exists ( tag '95'). In that case skip it
        if ( 0x95 == pinDataBuffer[index] )
            {
            index += 3;
            length -= 3;
            }
        // PIN key reference
        pinId = pinDataBuffer[index + 2];
        index += 3; // Skip PIN key reference data element
        length -= 3;

        // Store PIN ID
        if ( 1 <= pinId && 8 >= pinId ) // It is PIN1
            {
            iPin1Id = pinId;
            // Check if PIN1 is enabled ( the active PIN )
            if ( 0x80 & ( psDo[0] << orderNum ) )
                {
                iActivePin = RMobilePhone::ESecurityCodePin1;
                pin1Active = ETrue;
                }
            }
        else if ( 0x81 <= pinId && 0x88 >= pinId ) // It is PIN2
            {
            iPin2Id = pinId;
            orderNum++;
            }
        else if ( 0x11 == pinId )
            {
            upinExists = ETrue;
            orderNum++;
            }
        // No else
        }

    // If PIN1 is not set as active and UPIN exists, UPIN is the active PIN
    if ( upinExists && !pin1Active )
        {
        iActivePin = RMobilePhone::ESecurityUniversalPin;
        }
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetPin1KeyReference
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TUint8 CMmUiccMessHandler::GetPin1KeyReference()
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::GetPin1KeyReference" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_GETPIN1KEYREFERENCE, "CMmUiccMessHandler::GetPin1KeyReference" );
    return iPin1Id;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetPin1KeyReference
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TUint8 CMmUiccMessHandler::GetPin2KeyReference()
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::GetPin2KeyReference" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_GETPIN2KEYREFERENCE, "CMmUiccMessHandler::GetPin2KeyReference" );
    return iPin2Id;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetActivePin
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
RMobilePhone::TMobilePhoneSecurityCode CMmUiccMessHandler::GetActivePin()
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::GetActivePin" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_GETACTIVEPIN, "CMmUiccMessHandler::GetActivePin" );
    return iActivePin;
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::ChangeActivePin()
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::ChangeActivePin()
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::ChangeActivePin" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CHANGEACTIVEPIN, "CMmUiccMessHandler::ChangeActivePin" );
    // Change the internal flag indicating which PIN is active
    if ( RMobilePhone::ESecurityCodePin1 == iActivePin )
        {
        iActivePin = RMobilePhone::ESecurityUniversalPin;
        }
    else if ( RMobilePhone::ESecurityUniversalPin == iActivePin )
        {
        iActivePin = RMobilePhone::ESecurityCodePin1;
        }
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::InitializeCphsInformationCache
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::InitializeCphsInformationCache()
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::InitializeCphsInformationCache" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_INITIALIZECPHSINFORMATIONCACHE, "CMmUiccMessHandler::InitializeCphsInformationCache" );

    // CPHS information is read only in case of ICC card
    if( UICC_CARD_TYPE_ICC == iCardType )
        {
        // Set parameters for UICC_APPL_CMD_REQ message
        TUiccReadTransparent params;
        params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
        params.trId = ETrIdCphsCache;
        params.dataAmount = 0;
        params.dataOffset = 0;
        params.fileId = KElemCphsInformation;
        params.fileIdSfi = UICC_SFI_NOT_PRESENT;
        params.serviceType = UICC_APPL_READ_TRANSPARENT;

        // File id path
        params.filePath.Append( KMasterFileId >> 8 );
        params.filePath.Append( KMasterFileId );
        params.filePath.Append( GetApplicationFileId() );

        CreateUiccApplCmdReq( params );
        }
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::CphsInformationCacheResp
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMmUiccMessHandler::CphsInformationCacheResp(
    TInt aStatus,
    const TDesC8& aFileData )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::CphsInformationCacheResp" );
OstTrace0( TRACE_NORMAL, CMMUICCMESSHANDLER_CPHSINFORMATIONCACHERESP, "CMmUiccMessHandler::CphsInformationCacheResp" );

    if ( UICC_STATUS_OK == aStatus )
        {
        // First byte of CPHS information is for CPHS phase, lbut
        // we are interested in only CPHS table, so we skip the 
        // first byte and we just copy the CPHS table data
        TUint8 dataSize( aFileData.Length() - 1 );
        if( KEfCphsInfoSize >= dataSize )
            {
            iCPHSInformation.Copy( aFileData.Mid( 1, dataSize ) );
            }
        else
            {
TFLOGSTRING3("TSY: CMmUiccMessHandler::CphsInformationCacheResp: buffer too small (expected: %d, actual: %d), cannot store CPHS info", dataSize, iCPHSInformation.Length() );
OstTrace0( TRACE_NORMAL, DUP3_CMMUICCMESSHANDLER_CPHSINFORMATIONCACHERESP, "CMmUiccMessHandler::CphsInformationCacheResp: buffer too small, cannot store CPHS info" );
OstTrace1( TRACE_NORMAL, DUP2_CMMUICCMESSHANDLER_CPHSINFORMATIONCACHERESP, "CMmUiccMessHandler::CphsInformationCacheResp: expected size: %d", dataSize );
OstTrace1( TRACE_NORMAL, DUP4_CMMUICCMESSHANDLER_CPHSINFORMATIONCACHERESP, "CMmUiccMessHandler::CphsInformationCacheResp: actual size: %d", iCPHSInformation.Length() );
            }
        }
    else
        {
TFLOGSTRING2("TSY: CMmUiccMessHandler::CphsInformationCacheResp: reading failed (0x%x)", aStatus );
OstTrace1( TRACE_NORMAL, DUP1_CMMUICCMESSHANDLER_CPHSINFORMATIONCACHERESP, "CMmUiccMessHandler::CphsInformationCacheResp: reading failed (0x%x)", aStatus );
        }
    }

// -----------------------------------------------------------------------------
// CMmUiccMessHandler::GetCphsInformationStatus
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CMmUiccMessHandler::GetCphsInformationStatus( TUint8 aServiceNo )
    {
TFLOGSTRING("TSY: CMmUiccMessHandler::GetCphsInformationStatus" );
OstTrace0( TRACE_NORMAL, DUP1_CMMUICCMESSHANDLER_GETCPHSINFORMATIONSTATUS, "CMmUiccMessHandler::GetCphsInformationStatus" );

    TBool ret( EFalse );

    // CPHS info is coded as two bits,
    // for example first byte contains services 1-4 as:
    // bit:        b8  b7  b6  b5  b4  b3  b2  b1
    // service no: 04  04  03  03  02  02  01  01

    // first bit describes is service allocated
    // second bit describes is service activated
    // for example service no 4: first bit is b7
    // and second bit is b8. Both bits needs to be
    // 1 so that service is supported. For more
    // info about CPHS info, see CPHS Phase 2 specification

    // let's calculate index to get correct byte
    // which contains info about service requested
    TUint8 index( ( aServiceNo - 1 ) / 4 );

    // let's calculate the bit number which contains
    // service info
    TUint8 bit( ( aServiceNo - 1 ) % 4 );

    // form mask to get is service supported or not.
    TUint8 mask( 3<<( bit * 2 ) );

    if( iCPHSInformation.Length() > index )
        {
        // If both bits are 1, service is supported
        if( ( iCPHSInformation[index] & mask ) == mask )
            {
TFLOGSTRING2("TSY: CMmUiccMessHandler::GetCphsInformationStatus: CPHS service (%d) supported", aServiceNo );
OstTrace1( TRACE_NORMAL, CMMUICCMESSHANDLER_GETCPHSINFORMATIONSTATUS, "CMmUiccMessHandler::GetCphsInformationStatus: CPHS service (%d) supported", aServiceNo );
            ret = ETrue;
            }
        }
    return ret;
    }


//  End of File