adaptationlayer/tsy/nokiatsy_dll/src/cmmphonemesshandler.cpp
changeset 0 63b37f68c1ce
child 5 8ccc39f9d787
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/adaptationlayer/tsy/nokiatsy_dll/src/cmmphonemesshandler.cpp	Fri Nov 06 17:28:23 2009 +0000
@@ -0,0 +1,1217 @@
+/*
+* Copyright (c) 2007-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: 
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "cmmmessagerouter.h"
+#include "cmmphonemesshandler.h"
+#include "cmmphonetsender.h"
+#include "cmmsmsmesshandler.h"
+#include "cmmstaticutility.h"
+#include "cmmsupplservmesshandler.h"
+#include "cmmnetmesshandler.h"
+#include "cmmnetoperatornamehandler.h"
+#include "tsylogger.h"
+#include "cmmuiccmesshandler.h"
+
+#include <call_modemisi.h>
+#include <ctsy/pluginapi/cmmdatapackage.h>
+#include <csdisi.h>
+#include <gpdsisi.h>
+#include <ctsy/serviceapi/gsmerror.h>
+#include <gssisi.h>
+#include <infoisi.h>
+#include <ctsy/serviceapi/mmtsy_ipcdefs.h>
+#include <ctsy/serviceapi/mmtsy_defaults.h>
+#ifdef INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING
+#include <mtcisi.h>
+#else /* INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING */
+#include <mceisi.h>
+#endif /* INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING */
+#include <net_modemisi.h>
+#include <smsisi.h>
+#include <ss_wmisi.h>
+#include <tisi.h>
+#include <uiccisi.h>
+
+#include "osttracedefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "cmmphonemesshandlertraces.h"
+#endif
+
+// EXTERNAL DATA STRUCTURES
+    //None
+
+// EXTERNAL FUNCTION PROTOTYPES
+    //None
+
+// MACROS
+    //None
+
+// LOCAL CONSTANTS AND MACROS
+
+const TUint8 KPhoneTransId = 6; //hard coded transaction ID
+const TUint8 KImsiSize = 8;
+const TUint8 KServiceProviderSize = 36;
+const TUint8 KSpnFileSize = 16;
+
+// ------------------------------------------------------
+// --- Alternate Line Service (ALS)-related constants ---
+// ------------------------------------------------------
+// Consts for mapping the Als Line values, as used in SIMSON's
+// SIM_SERV_DYNAMIC_FLAGS_STR structure.
+const TUint8 KAlsAuxiliaryLine = 0x00; // ALS alternate line
+const TUint8 KAlsPrimaryLine = 0x01;   // ALS primary line
+
+// ----------------------------------------------
+// --- (U)ICC Service Table-related constants ---
+// ----------------------------------------------
+
+const TUint8  KUiccCspCallOfferingCode          ( 0x01 );
+const TUint8  KUiccCspCallRestrictionCode       ( 0x02 );
+const TUint8  KUiccCspOtherSupplServCode        ( 0x03 );
+const TUint8  KUiccCspCallCompletionCode        ( 0x04 );
+const TUint8  KUiccCspTeleServicesCode          ( 0x05 );
+const TUint8  KUiccCspCphsTeleServicesCode      ( 0x06 );
+const TUint8  KUiccCspCphsFeaturesCode          ( 0x07 );
+const TUint8  KUiccCspNumberIdentifCode         ( 0x08 );
+const TUint8  KUiccCspValueAddedServicesCode    ( 0xC0 );
+
+// MODULE DATA STRUCTURES
+    //None
+
+// LOCAL FUNCTION PROTOTYPES
+    //None
+
+// ==================== LOCAL FUNCTIONS =====================================
+    //None
+
+// ================= MEMBER FUNCTIONS =======================================
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::CMmPhoneMessHandler
+// C++ constructor.
+// --------------------------------------------------------------------------
+//
+CMmPhoneMessHandler::CMmPhoneMessHandler()
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler constructed.");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_CMMPHONEMESSHANDLER, "CMmPhoneMessHandler::CMmPhoneMessHandler" );
+
+    iACLIsProgress = EFalse;
+    iAPNList = NULL;
+    iAPNReadOrDeleteIndex = 0;
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::NewL
+// Creates a new PhoneMessageHandler object instance.
+// --------------------------------------------------------------------------
+//
+CMmPhoneMessHandler* CMmPhoneMessHandler::NewL
+        (
+        CMmPhoNetSender* aPhoNetSender,  //a ptr to the phonet sender
+        CMmPhoNetReceiver* aPhoNetReceiver,  //a ptr to the phonet receiver
+        CMmMessageRouter* aMessageRouter, // pointer to the msg router
+        CMmSupplServMessHandler* aSupplServMessHandler,
+        CMmUiccMessHandler* aUiccMessHandler
+        )
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::NewL");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_NEWL, "CMmPhoneMessHandler::NewL" );
+
+    CMmPhoneMessHandler* phoneMessHandler =
+        new ( ELeave ) CMmPhoneMessHandler();
+
+    CleanupStack::PushL( phoneMessHandler );
+    phoneMessHandler->iPhoNetSender = aPhoNetSender;
+    phoneMessHandler->ConstructL( aMessageRouter );
+    phoneMessHandler->iSupplServMessHandler = aSupplServMessHandler;
+    phoneMessHandler->iMmUiccMessHandler = aUiccMessHandler;
+
+    aPhoNetReceiver->RegisterL(
+        phoneMessHandler,
+#ifdef INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING
+        PN_INFO,
+#else /* INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING */
+        PN_MODEM_INFO,
+#endif /* INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING */
+        INFO_SERIAL_NUMBER_READ_RESP );
+
+    CleanupStack::Pop( phoneMessHandler );
+
+    return phoneMessHandler;
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::ConstructL
+// Initialises object attributes.
+// --------------------------------------------------------------------------
+//
+void CMmPhoneMessHandler::ConstructL
+        (
+        CMmMessageRouter* aMessageRouter
+        )
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::ConstructL");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_CONSTRUCTL, "CMmPhoneMessHandler::ConstructL" );
+
+    // Internal pointers, must be nulled before used.
+    iSSTFileData = NULL;
+    iStoreInfo = NULL;
+    iLocIndex = 0;
+
+    iMessageRouter = aMessageRouter;
+
+    iCommonTSYRefreshPending = EFalse;
+    iRefreshError = EFalse;
+
+    iInternalRefreshFiles = 0;
+
+    SubscribeEventsFromPhoNet();
+
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::~CMmPhoneMessHandler
+// C++ destructor.
+// --------------------------------------------------------------------------
+//
+CMmPhoneMessHandler::~CMmPhoneMessHandler()
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler destructed.");
+OstTrace0( TRACE_NORMAL, DUP1_CMMPHONEMESSHANDLER_CMMPHONEMESSHANDLER, "CMmPhoneMessHandler::~CMmPhoneMessHandler" );
+
+    // Delete iStoreInfo and set it to NULL, if it exist.
+    if( iStoreInfo )
+        {
+        delete iStoreInfo;
+        }
+
+    // Delete iSSTFileData and set it to NULL, if it exist.
+    if( iSSTFileData )
+        {
+        // Delete object
+        delete iSSTFileData;
+        }
+
+    if( iAPNList )
+        {
+        iAPNList->Reset();
+        delete iAPNList;
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::SubcribeEventsFromPhonet
+// Subscribes indications from PhoNet. The wanted indications
+// are first added to an array and the array is then passed to the PhoNet.
+// --------------------------------------------------------------------------
+//
+TInt CMmPhoneMessHandler::SubscribeEventsFromPhoNet()
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::SubscribeEventsFromPhoNet");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_SUBSCRIBEEVENTSFROMPHONET, "CMmPhoneMessHandler::SubscribeEventsFromPhoNet" );
+
+    // Cross check requests with PhonetReceiver
+    TUint8 requestArray[] = {
+
+        // CALL SERVER INDICATIONS
+            // PhonetReceiver - PhoneDispatchList
+            PN_MODEM_CALL, CALL_MODEM_DTMF_STATUS_IND,
+            PN_MODEM_CALL, CALL_MODEM_DTMF_TONE_IND,
+
+            // PhonetReceiver - LineDispatchList
+            PN_MODEM_CALL, CALL_MODEM_COMING_IND,
+
+            // PhonetReceiver - CallDispatchList
+            PN_MODEM_CALL, CALL_MODEM_CONTROL_IND,
+            PN_MODEM_CALL, CALL_MODEM_MO_ALERT_IND,
+            PN_MODEM_CALL, CALL_MODEM_RELEASE_IND,
+            PN_MODEM_CALL, CALL_MODEM_STATUS_IND, // used also in SimAtkTSY
+            PN_MODEM_CALL, CALL_MODEM_TERMINATED_IND,
+            PN_MODEM_CALL, CALL_MODEM_NOTIFICATION_IND,
+            PN_MODEM_CALL, CALL_MODEM_SERVICE_DENIED_IND,
+            PN_MODEM_CALL, CALL_MODEM_MESSAGE_IND, // Used also in simatktsy
+            PN_MODEM_CALL, CALL_MODEM_PRESENT_IND, // Used also in simatktsy
+            PN_MODEM_CALL, CALL_MODEM_RESOURCE_IND, // Used also in simatktsy
+            PN_MODEM_CALL, CALL_MODEM_RESOURCE_CONF_IND, // Used only in simatktsy
+
+            //CSD SERVER INDICATIONS
+            PN_CSD, CSD_VIDEO_CALL_STATUS_IND,
+            PN_CSD, CSD_MULTIMEDIA_DATA_RATE_IND,
+
+        // NET SERVER INDICATIONS
+            PN_MODEM_NETWORK, NET_MODEM_REG_STATUS_IND,
+            PN_MODEM_NETWORK, NET_NITZ_NAME_IND,
+            PN_MODEM_NETWORK, NET_CELL_INFO_IND, // used only in SimAtkTSY
+            PN_MODEM_NETWORK, NET_RSSI_IND,
+            PN_MODEM_NETWORK, NET_RAT_IND, // used also in SimAtkTSY
+            PN_MODEM_NETWORK, NET_CIPHERING_IND,
+            PN_MODEM_NETWORK, NET_TIME_IND, // used also in SimAtkTSY
+            PN_MODEM_NETWORK, NET_RADIO_INFO_IND,
+
+        // SS SERVER INDICATIONS
+            PN_SS, SS_SERVICE_COMPLETED_IND,
+            PN_SS, SS_STATUS_IND, // used also in SimAtkTSY
+            PN_SS, SS_RESOURCE_CONTROL_IND, // used in SimAtkTSY
+            PN_SS, SS_RESOURCE_CONF_IND, // used in SimAtkTSY
+
+        // USSD
+            PN_SS, SS_GSM_USSD_RECEIVE_IND,
+
+        // SMS SERVER INDICATIONS
+            PN_SMS, SMS_RECEIVED_SIM_MSG_IND, // used only in SimAtkTSY
+            PN_SMS, SMS_RESOURCE_IND, // used only in SimAtkTSY
+            PN_SMS, SMS_RECEIVED_MSG_IND,
+            PN_SMS, SMS_CB_ROUTING_IND,
+
+        // UICC SERVER INDICATIONS
+            PN_UICC, UICC_CARD_IND,
+            PN_UICC, UICC_IND,
+
+#ifdef INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING
+        // MTC SERVER INDICATIONS
+            PN_MTC, MTC_STATE_INFO_IND,
+#else /* INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING */
+        // MCE SERVER INDICATIONS
+            PN_MODEM_MCE, MCE_MODEM_STATE_IND,
+#endif /* INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING */
+        // GPDS SERVER INDICATIONS
+            PN_GPDS, GPDS_CONTEXT_ID_CREATE_IND,
+            PN_GPDS, GPDS_CONTEXT_ID_DELETE_IND,
+            PN_GPDS, GPDS_CONTEXT_ACTIVATE_IND,
+            PN_GPDS, GPDS_CONTEXT_DEACTIVATE_IND,
+            PN_GPDS, GPDS_CONTEXT_NWI_ACT_REQUEST_IND,
+            PN_GPDS, GPDS_ATTACH_IND,
+            PN_GPDS, GPDS_DETACH_IND,
+            PN_GPDS, GPDS_TRANSFER_STATUS_IND,
+            PN_GPDS, GPDS_CONTEXT_ACTIVATE_FAIL_IND,
+            PN_GPDS, GPDS_CONTEXT_STATUS_IND,
+            PN_GPDS, GPDS_CONTEXT_ACTIVATING_IND,
+            PN_GPDS, GPDS_CONTEXT_DEACTIVATING_IND,
+            PN_GPDS, GPDS_CONFIGURATION_INFO_IND,
+            PN_GPDS, GPDS_CONTEXT_MODIFY_IND,
+            PN_GPDS, GPDS_RADIO_ACTIVITY_IND,
+            PN_GPDS, GPDS_RESOURCE_CONTROL_IND,
+            PN_GPDS, GPDS_RESOURCE_CONF_IND,
+
+        // NVD SERVER INDICATIONS
+
+        // PIPE SERVER INDICATIONS
+
+        // GSS SERVER INDICATIONS
+            PN_GSS, GSS_HSXPA_USER_SETTING_IND,
+
+        };
+
+    TInt ret = iPhoNetSender->SubscribeEvents(
+        TPtr8( &requestArray[0],
+            sizeof( requestArray ),
+            sizeof( requestArray ) ) );
+
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::ExtFuncL
+// Dispatches Etel requests to DOS level handlers
+// --------------------------------------------------------------------------
+//
+TInt CMmPhoneMessHandler::ExtFuncL
+        (
+        TInt aIpc,
+        const CMmDataPackage* aDataPackage // Data package
+        )
+    {
+TFLOGSTRING2("TSY: CMmPhoneMessHandler::ExtFuncL. Licensee specific implemtantion. IPC: %d", aIpc);
+OstTrace1( TRACE_NORMAL, CMMPHONEMESSHANDLER_EXTFUNCL, "CMmPhoneMessHandler::ExtFuncL;Licensee specific implemtantion aIpc=%d", aIpc );
+
+    //*************************************************************//
+    // NOTE.
+    //
+    // LICENSEE SPECIFIC MESSAGE HANDLER IMPLEMENTATION STARTS HERE
+    //
+    //*************************************************************//
+
+    TInt ret( KErrNone );
+    TUint8 transId( KPhoneTransId );
+
+    switch ( aIpc )
+        {
+        case EMobilePhoneGetALSLine:
+            {
+            ret = UiccReadDynamicFlagsReq();
+            break;
+            }
+        case EMobilePhoneSetALSLine:
+            {
+            TUint8 alsLine;
+            aDataPackage->UnPackData( alsLine );
+            ret = UiccWriteDynamicFlagsReq( alsLine );
+            break;
+            }
+        case EMobilePhoneGetCustomerServiceProfile:
+            {
+            ret = UiccCspFileReq();
+            break;
+            }
+        case EMobilePhoneGetPhoneId:
+            {
+            // no packed parameters
+            // read IMEI
+            ret = InfoSerialNumberReadReq( transId, INFO_SN_IMEI_PLAIN );
+            break;
+            }
+        case EMobilePhoneGetSubscriberId:
+            {
+            // read IMSI
+            ret = UiccImsiReq();
+            break;
+            }
+        case EMobilePhoneGetServiceProviderName:
+            {
+            ret = UiccReadServiceProviderName();
+            break;
+            }
+        default:
+            {
+TFLOGSTRING2("TSY: CMmPhoneMessHandler::ExtFuncL - Unknown IPC: %d", aIpc);
+OstTrace1( TRACE_NORMAL, DUP7_CMMPHONEMESSHANDLER_EXTFUNCL, "CMmPhoneMessHandler::ExtFuncL;Unknown aIpc=%d", aIpc );
+            ret = KErrNotSupported;
+            break;
+            }
+        }
+
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::ReceiveMessageL
+// Called by extension message handler when a common ISI
+// message has been received.
+// --------------------------------------------------------------------------
+//
+void CMmPhoneMessHandler::ReceiveMessageL
+        (
+        const TIsiReceiveC &aIsiMessage  // ISI message received
+        )
+    {
+    TInt resource( aIsiMessage.Get8bit( ISI_HEADER_OFFSET_RESOURCEID ) );
+    TInt messageId( aIsiMessage.Get8bit( ISI_HEADER_OFFSET_MESSAGEID ) );
+
+TFLOGSTRING3("TSY: CMmPhoneMessHandler::ReceiveMessageL, Resource: %d, Message: %d", resource, messageId );
+OstTraceExt2( TRACE_NORMAL, CMMPHONEMESSHANDLER_RECEIVEMESSAGEL, "CMmPhoneMessHandler::ReceiveMessageL;resource=%d;messageId=%d", resource, messageId );
+
+    switch( resource )
+        {
+#ifdef INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING
+        case PN_INFO:
+#else /* INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING */
+        case PN_MODEM_INFO:
+#endif /* INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING */
+            {
+            switch( messageId )
+                {
+                case INFO_SERIAL_NUMBER_READ_RESP:
+                    {
+                    InfoSerialNumberReadResp( aIsiMessage );
+                    break;
+                    }
+                default:
+                    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::ReceiveMessageL, switch resource - case PN_MODEM_INFO, switch messageId - default.\n" );
+OstTrace0( TRACE_NORMAL, DUP4_CMMPHONEMESSHANDLER_RECEIVEMESSAGEL, "CMmPhoneMessHandler::ReceiveMessageL, switch resource - case PN_MODEM_INFO, switch messageId - default" );
+                    break;
+                    }
+                }
+            break; // end case PN_MODEM_INFO
+            }
+        default:
+            {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::ReceiveMessageL, switch resource - default.\n" );
+OstTrace0( TRACE_NORMAL, DUP5_CMMPHONEMESSHANDLER_RECEIVEMESSAGEL, "CMmPhoneMessHandler::ReceiveMessageL, switch resource - default" );
+            break;
+            }
+        } // End of switch
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::InfoSerialNumberReadReq
+// Constructs INFO_SERIAL_NUMBER_READ_REQ ISI message..
+// Returns KErrNone on success, other error value on failure.
+// --------------------------------------------------------------------------
+//
+TInt CMmPhoneMessHandler::InfoSerialNumberReadReq
+        (
+        TUint8 aTransactionId, // transaction id
+        TUint8 aTarget // type of requested serial number
+        )
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::InfoSerialNumberReadReq.");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_INFOSERIALNUMBERREADREQ, "CMmPhoneMessHandler::InfoSerialNumberReadReq" );
+
+    TBuf8<1> data;
+    data.Append( aTarget ); // Target identifier ( INFO_SN_IMEI_PLAIN )
+
+    return iPhoNetSender->Send(
+#ifdef INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING
+        PN_INFO,
+#else /* INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING */
+        PN_MODEM_INFO,
+#endif /* INTERNAL_TESTING_OLD_IMPLEMENTATION_FOR_UICC_TESTING */
+        aTransactionId,
+        INFO_SERIAL_NUMBER_READ_REQ,
+        data );
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::InfoSerialNumberReadResp
+// Breaks a INFO_SERIAL_NUMBER_READ_RESP ISI-message.
+// --------------------------------------------------------------------------
+//
+void CMmPhoneMessHandler::InfoSerialNumberReadResp
+        (
+        const TIsiReceiveC& aIsiMessage
+        )
+    {
+    TInt err( KErrNotFound );
+
+    TBuf8<KSerialNumberLength> serialData;
+
+    // Get status
+    TUint8 status( aIsiMessage.Get8bit(
+        ISI_HEADER_SIZE + INFO_SERIAL_NUMBER_READ_RESP_OFFSET_STATUS ) );
+
+TFLOGSTRING2("TSY: CMmPhoneMessHandler::InfoSerialNumberReadResp, status=0x%02x",status);
+OstTraceExt1( TRACE_NORMAL, CMMPHONEMESSHANDLER_INFOSERIALNUMBERREADRESP, "CMmPhoneMessHandler::InfoSerialNumberReadResp;status=%hhx", status );
+
+    // If status is Ok get information from possible sub block(s).
+    if ( INFO_OK == status )
+        {
+        // If sub blocks
+        if ( 0 != aIsiMessage.Get8bit(
+            ISI_HEADER_SIZE +
+            INFO_SERIAL_NUMBER_READ_RESP_OFFSET_SUBBLOCKCOUNT ) )
+            {
+            TUint sbSerialNumberStartOffset( 0 );
+
+            if ( KErrNone == aIsiMessage.FindSubBlockOffsetById(
+                ISI_HEADER_SIZE + SIZE_INFO_SERIAL_NUMBER_READ_RESP,
+                INFO_SB_SN_IMEI_PLAIN,
+                EIsiSubBlockTypeId8Len8,
+                sbSerialNumberStartOffset ) )
+                {
+                // Read the string length - the zero terminator...
+                TUint8 strLength( aIsiMessage.Get8bit(
+                    sbSerialNumberStartOffset +
+                    INFO_SB_SN_IMEI_PLAIN_OFFSET_STRLEN ) - 1 );
+                // ...and compare it to the available buffer size
+                // (50 bytes in etel),
+                // and choose the shorter one strLength =
+                // ( RMobilePhone::KPhoneSerialNumberSize > strLength )?
+                // strLength : RMobilePhone::KPhoneSerialNumberSize;
+
+                TUint8 dataOffset(
+                    sbSerialNumberStartOffset +
+                    INFO_SB_SN_IMEI_PLAIN_OFFSET_IMEIPLAINU8 );
+
+                serialData.Append( aIsiMessage.GetData(
+                    dataOffset,
+                    strLength ).Left( KSerialNumberLength ) );
+
+                err = KErrNone;
+                }
+            }
+        }
+
+    // Complete to CommonTSY, ONLY if all data has already been received
+    // packed parameter: TBuf8<KSerialNumberLength> serialData
+    CMmDataPackage dataPackage;
+    dataPackage.PackData( &serialData );
+    iMessageRouter->Complete( EMobilePhoneGetPhoneId, &dataPackage, err );
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::UiccReadDynamicFlagsReq
+// Read dynamic flags
+// --------------------------------------------------------------------------
+//
+TInt CMmPhoneMessHandler::UiccReadDynamicFlagsReq()
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::UiccReadDynamicFlagsReq");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_UICCREADDYNAMICFLAGSREQ, "CMmPhoneMessHandler::UiccReadDynamicFlagsReq" );
+
+    // Set parameters for UICC_APPL_CMD_REQ message
+    TUiccWriteTransparent params;
+    params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
+    params.trId = ETrIdReadDynamicFlags;
+    params.dataOffset = 0;
+    params.dataAmount = 0;
+    params.fileId = KElemFileDynFlagsOrange;
+    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( KOrangeDedicatedFile >> 8 );
+    params.filePath.Append( KOrangeDedicatedFile );
+
+    return iMmUiccMessHandler->CreateUiccApplCmdReq( params );
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::UiccWriteDynamicFlagsReq
+// Write dynamic flags
+// --------------------------------------------------------------------------
+//
+TInt CMmPhoneMessHandler::UiccWriteDynamicFlagsReq( TUint8 aInfo )
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::UiccWriteDynamicFlagsReq");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_UICCWRITEDYNAMICFLAGSREQ, "CMmPhoneMessHandler::UiccWriteDynamicFlagsReq" );
+
+    TInt ret( KErrNone );
+    TUint8 line( 0 );
+
+    if ( RMobilePhone::EAlternateLinePrimary == aInfo )
+        {
+        line = KAlsPrimaryLine;
+        iAlsLine = RMobilePhone::EAlternateLinePrimary;
+        }
+    else if ( RMobilePhone::EAlternateLineAuxiliary == aInfo )
+        {
+        line = KAlsAuxiliaryLine;
+        iAlsLine = RMobilePhone::EAlternateLineAuxiliary;
+        }
+    else
+        {
+        iAlsLine = RMobilePhone::EAlternateLineUnknown;
+        ret = KErrArgument;
+        }
+
+    if ( KErrNone == ret )
+        {
+        // Set parameters for UICC_APPL_CMD_REQ message
+        TUiccWriteTransparent params;
+        params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
+        params.trId = ETrIdWriteDynamicFlags;
+        params.dataOffset = 0;
+        params.fileId = KElemFileDynFlagsOrange;
+        params.fileIdSfi = UICC_SFI_NOT_PRESENT;
+        params.serviceType = UICC_APPL_UPDATE_TRANSPARENT;
+
+        // File id path
+        params.filePath.Append( KMasterFileId >> 8 );
+        params.filePath.Append( KMasterFileId );
+        params.filePath.Append( KOrangeDedicatedFile >> 8 );
+        params.filePath.Append( KOrangeDedicatedFile );
+
+        params.fileData.Append( line );
+        ret = iMmUiccMessHandler->CreateUiccApplCmdReq( params );
+        }
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::UiccReadDynamicFlagsResp
+// Complete dynamic flags
+// --------------------------------------------------------------------------
+//
+void CMmPhoneMessHandler::UiccReadDynamicFlagsResp(
+    TInt aStatus,
+    const TDesC8& aFileData )
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::UiccReadDynamicFlagsResp");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_UICCREADDYNAMICFLAGSRESP, "CMmPhoneMessHandler::UiccReadDynamicFlagsResp" );
+
+    RMobilePhone::TMobilePhoneALSLine alsLine
+        ( RMobilePhone::EAlternateLineUnknown );
+
+    TInt ret( KErrNone );
+    if ( UICC_STATUS_OK == aStatus )
+        {
+        // Dynamic flags byte: if bit 0 is 1, it is line 1, else line 2
+        if ( aFileData[0] & 0x1 )
+            {
+            alsLine = RMobilePhone::EAlternateLinePrimary;
+            }
+        else
+            {
+            alsLine = RMobilePhone::EAlternateLineAuxiliary;
+            }
+        }
+
+    iSupplServMessHandler->SetVoiceCallForwardLine( alsLine );
+
+    CMmDataPackage dataPackage;
+    dataPackage.PackData ( &alsLine );
+    iMessageRouter->Complete(
+        EMobilePhoneGetALSLine,
+        &dataPackage,
+        ret );
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::UiccWriteDynamicFlagsResp
+// Complete write dynamic flags
+// --------------------------------------------------------------------------
+//
+void CMmPhoneMessHandler::UiccWriteDynamicFlagsResp( TInt aStatus )
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::UiccWriteDynamicFlagsResp");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_UICCWRITEDYNAMICFLAGSRESP, "CMmPhoneMessHandler::UiccWriteDynamicFlagsResp" );
+
+    if ( UICC_STATUS_OK == aStatus )
+        {
+        iSupplServMessHandler->SetVoiceCallForwardLine( iAlsLine );
+        iMessageRouter->Complete( EMobilePhoneSetALSLine, KErrNone );
+        }
+    else
+        {
+        iMessageRouter->Complete( EMobilePhoneSetALSLine, KErrGeneral );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::UiccCspFileReq
+// Read CSP
+// --------------------------------------------------------------------------
+TInt CMmPhoneMessHandler::UiccCspFileReq()
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::UiccCspFileReq");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_UICCCSPFILEREQ, "CMmPhoneMessHandler::UiccCspFileReq" );
+
+    // Set parameters for UICC_APPL_CMD_REQ message
+    TUiccReadTransparent params;
+    params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
+    params.trId = ETrIdReadCsp;
+    params.dataAmount = 18;
+    params.dataOffset = 0; // Read from first byte
+    params.fileId = KElemFileCustomerServiceProfile;
+    params.serviceType = UICC_APPL_READ_TRANSPARENT;
+
+    // File id path
+    params.filePath.Append( KMasterFileId >> 8 );
+    params.filePath.Append( KMasterFileId );
+    params.filePath.Append( iMmUiccMessHandler->GetApplicationFileId() );
+
+    return iMmUiccMessHandler->CreateUiccApplCmdReq( params );
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::UiccCspFileResp
+// Complete CSP
+// --------------------------------------------------------------------------
+void CMmPhoneMessHandler::UiccCspFileResp(
+    TInt aStatus,
+    const TDesC8& aFileData )
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::UiccHandleCallFwdFlagsResp");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_UICCCSPFILERESP, "CMmPhoneMessHandler::UiccCspFileResp" );
+
+    RMobilePhone::TMobilePhoneCspFileV1 cspFileEtel;
+
+    if ( aStatus == KErrNone )
+        {
+        TUint8 i( 0 );
+        // Call offering capabilities
+        if ( KUiccCspCallOfferingCode == aFileData[i++] )
+            {
+            cspFileEtel.iCallOfferingServices = aFileData[i++];
+            }
+
+        // Call restriction capabilities
+        if ( KUiccCspCallRestrictionCode == aFileData[i++] )
+            {
+            cspFileEtel.iCallRestrictionServices = aFileData[i++];
+            }
+
+        // Other supplementary services capabilities
+        if ( KUiccCspOtherSupplServCode == aFileData[i++] )
+            {
+            cspFileEtel.iOtherSuppServices = aFileData[i++];
+            }
+
+        // Call completion capabilities
+        if ( KUiccCspCallCompletionCode == aFileData[i++] )
+            {
+            cspFileEtel.iCallCompletionServices = aFileData[i++];
+            }
+
+        // Teleservices capabilities
+        if ( KUiccCspTeleServicesCode == aFileData[i++] )
+            {
+            cspFileEtel.iTeleservices = aFileData[i++];
+            }
+
+        // CPHS teleservices capabilities
+        if ( KUiccCspCphsTeleServicesCode == aFileData[i++] )
+            {
+            cspFileEtel.iCphsTeleservices = aFileData[i++];
+            }
+
+        // CPHS features capabilities
+        if ( KUiccCspCphsFeaturesCode == aFileData[i++] )
+            {
+            cspFileEtel.iCphsFeatures = aFileData[i++];
+            }
+
+        // Number identification capabilities
+        if ( KUiccCspNumberIdentifCode == aFileData[i++] )
+            {
+            cspFileEtel.iNumberIdentServices = aFileData[i++];
+            }
+
+        // Value added services capabilities
+        if ( KUiccCspValueAddedServicesCode == aFileData[i++] )
+            {
+            cspFileEtel.iValueAddedServices = aFileData[i++];
+            }
+        } // End of if ( aStatus == KErrNone )
+    else
+        {
+        aStatus = KErrNotFound;
+        }
+
+    // Complete with CSP data and error code
+    CMmDataPackage dataPackage;
+    dataPackage.PackData( &cspFileEtel );
+
+    iMessageRouter->Complete(
+        EMobilePhoneGetCustomerServiceProfile,
+        &dataPackage,
+        aStatus );
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::UiccImsiReq
+// Read IMSI
+// --------------------------------------------------------------------------
+//
+TInt CMmPhoneMessHandler::UiccImsiReq( )
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::UiccImsiReq");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_UICCIMSIREQ, "CMmPhoneMessHandler::UiccImsiReq" );
+
+    // Set parameters for UICC_APPL_CMD_REQ message
+    TUiccReadTransparent params;
+    params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
+    params.trId = ETrIdReadImsi;
+    params.dataAmount = 9; // Length + IMSI = 9 bytes
+    params.dataOffset = 0; // Read from first byte
+    params.fileId = KElemFileImsi;
+    params.fileIdSfi = 7;
+    params.serviceType = UICC_APPL_READ_TRANSPARENT;
+
+    // File id path
+    params.filePath.Append( KMasterFileId >> 8 );
+    params.filePath.Append( KMasterFileId );
+    params.filePath.Append( iMmUiccMessHandler->GetApplicationFileId() );
+
+    return iMmUiccMessHandler->CreateUiccApplCmdReq( params );
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::UiccImsiResp
+// Complete IMSI
+// --------------------------------------------------------------------------
+//
+void CMmPhoneMessHandler::UiccImsiResp( TInt aStatus, const TDesC8& aFileData )
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::UiccImsiResp" );
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_UICCIMSIRESP, "CMmPhoneMessHandler::UiccImsiResp" );
+
+    TInt err( KErrNone );
+    TBuf8<RMobilePhone::KIMSISize> imsiData;
+    if ( UICC_STATUS_OK == aStatus )
+        {
+        TUint8 i( 0 );
+        TUint8 valueMSB( 0 );
+        TUint8 valueLSB( 0 );
+        // Get length of IMSI (the first byte)
+        TUint8 lengthOfImsi( aFileData[0] );
+        // Get the first IMSI number: MSB semioctet of byte 2
+        valueMSB = static_cast<TUint8>( aFileData[1] >> 4 );
+        // Check the validity
+        if ( KImsiSize >= lengthOfImsi && 10 > valueMSB  )
+            {
+            imsiData.AppendNum( valueMSB, EDecimal);
+            }
+        else
+            {
+            err = KErrCorrupt;
+            }
+
+        if ( KErrNone == err )
+            {
+            // Check and append the rest of IMSI numbers
+            for ( i = 2; i <= lengthOfImsi; i++ )
+                {
+                valueLSB = static_cast<TUint8>( aFileData[i] & 0x0F );
+                valueMSB = static_cast<TUint8>( aFileData[i] >> 4 );
+
+                // If both values are valid
+                if ( 10 > valueLSB && 10 > valueMSB )
+                    {
+                    imsiData.AppendNum( valueLSB, EDecimal);
+                    imsiData.AppendNum( valueMSB, EDecimal);
+                    }
+                // Last nibble is unused
+                else if( 10 > valueLSB && 0xF == valueMSB )
+                    {
+                    imsiData.AppendNum( valueLSB, EDecimal);
+                    break;
+                    }
+                // Either is invalid
+                else
+                    {
+                    err = KErrCorrupt;
+                    break;
+                    }
+                }
+            }
+        }
+    else
+        {
+        err = KErrNotFound;
+        }
+
+    // Complete with packed parameter
+    CMmDataPackage dataPackage;
+    dataPackage.PackData( &imsiData );
+
+    iMessageRouter->Complete(
+        EMobilePhoneGetSubscriberId,
+        &dataPackage,
+        err );
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::UiccReadServiceProviderName
+// Read service provider name
+// --------------------------------------------------------------------------
+//
+TInt CMmPhoneMessHandler::UiccReadServiceProviderName()
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::UiccReadServiceProviderName");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_UICCREADSERVICEPROVIDERNAME, "CMmPhoneMessHandler::UiccReadServiceProviderName" );
+
+    // Read SIM file '6F46', Service Provider Name
+    // Set parameters for UICC_APPL_CMD_REQ message
+    TUiccReadTransparent params;
+    params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
+    params.trId = ETrIdReadServiceProviderName;
+    // Read all 17 bytes
+    params.dataAmount = 17;
+    params.dataOffset = 0;
+    params.fileId = KElemFileServiceProviderName;
+    params.serviceType = UICC_APPL_READ_TRANSPARENT;
+
+    // File id path
+    params.filePath.Append( KMasterFileId >> 8 );
+    params.filePath.Append( KMasterFileId );
+    params.filePath.Append( iMmUiccMessHandler->GetApplicationFileId() );
+
+    return iMmUiccMessHandler->CreateUiccApplCmdReq( params );
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::UiccReadServiceProviderNameResp
+// Complete service provider name
+// --------------------------------------------------------------------------
+//
+void CMmPhoneMessHandler::UiccReadServiceProviderNameResp(
+    TInt aStatus,
+    const TDesC8& aFileData )
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::UiccReadServiceProviderNameResp");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_UICCREADSERVICEPROVIDERNAMERESP, "CMmPhoneMessHandler::UiccReadServiceProviderNameResp" );
+
+    TInt ret( KErrNone );
+    if ( KErrNone == aStatus )
+        {
+        // Store data and read SPN display info
+        ret = UiccProcessServiceTypeCheck( aFileData );
+        }
+
+    if ( KErrNone != aStatus || KErrNone != ret )
+        {
+        // Complete error without data
+        iMessageRouter->Complete(
+            EMobilePhoneGetServiceProviderName,
+            KErrNotFound );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMmPhoneMessHandler::ProcessUiccMsg
+// Handles data received from UICC server
+// -----------------------------------------------------------------------------
+//
+TInt CMmPhoneMessHandler::ProcessUiccMsg(
+    TInt aTraId,
+    TInt aStatus,
+    const TDesC8& aFileData )
+    {
+TFLOGSTRING3("TSY: CMmPhoneMessHandler::ProcessUiccMsg, transaction ID: %d, status %d", aTraId, aStatus );
+OstTraceExt2( TRACE_NORMAL, CMMPHONEMESSHANDLER_PROCESSUICCMSG, "CMmPhoneMessHandler::ProcessUiccMsg;aTraId=%d;aStatus=%d", aTraId, aStatus );
+
+switch( aTraId )
+        {
+        case ETrIdReadImsi:
+            {
+            UiccImsiResp( aStatus, aFileData );
+            break;
+            }
+        case ETrIdReadServiceProviderName:
+            {
+            UiccReadServiceProviderNameResp( aStatus, aFileData );
+            break;
+            }
+        case ETrIdReadServiceProviderDisplayInfo:
+            {
+            UiccProcessSpnNameInfo( aStatus, aFileData );
+            break;
+            }
+        case ETrIdReadCsp:
+            {
+            UiccCspFileResp( aStatus, aFileData );
+            }
+        case ETrIdReadDynamicFlags:
+            {
+            UiccReadDynamicFlagsResp( aStatus, aFileData );
+            break;
+            }
+        case ETrIdWriteDynamicFlags:
+            {
+            UiccWriteDynamicFlagsResp( aStatus );
+            break;
+            }
+        default:
+            {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::ProcessUiccMsg - unknown transaction ID" );
+OstTrace0( TRACE_NORMAL, DUP1_CMMPHONEMESSHANDLER_PROCESSUICCMSG, "CMmPhoneMessHandler::ProcessUiccMsg - unknown transaction ID" );
+            break;
+            }
+        }
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::UiccProcessServiceTypeCheck
+// Process service type checking response
+// --------------------------------------------------------------------------
+//
+TInt CMmPhoneMessHandler::UiccProcessServiceTypeCheck(
+    const TDesC8& aFileData )
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::UiccProcessServiceTypeCheck");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_UICCPROCESSSERVICETYPECHECK, "CMmPhoneMessHandler::UiccProcessServiceTypeCheck" );
+
+    // Copy service provider name, starting from byte 2
+    TBuf8<KSpnFileSize> spnBuffer( aFileData.Mid( 1 ) );
+    TBuf8<KServiceProviderSize> spnOutputBuffer;
+    CMmStaticUtility::ConvertGsmDataToUcs2(
+        spnBuffer,
+        KSpnFileSize,
+        spnOutputBuffer );
+
+    // Get the display condition ( 1st byte )
+    const TUint8 displayCondition( aFileData[0] );
+
+    // From TS 31.102:
+    // b1=1: display of registered PLMN name required when registered PLMN is
+    // either HPLMN or a PLMN in the service provider PLMN list.
+    if ( displayCondition & 0x01 )
+        {
+        iServiceProviderName.iDisplayReq = RMobilePhone::KDisplayPLMNRequired;
+        }
+    else
+        {
+        iServiceProviderName.iDisplayReq =
+            RMobilePhone::KDisplayPLMNNotRequired;
+        }
+
+    // Set iSecondDisplayCondition as not required by default
+    iSecondDisplayCondition = RMobilePhone::KDisplaySPNNotRequired;
+
+    // From TS 31.102:
+    // b2=0:  Display of the service provider name is required when
+    // registered PLMN is neither HPLMN nor a PLMN in the service provider
+    // PLMN list
+    if ( 0 == ( displayCondition & 0x02 ) )
+        {
+        iSecondDisplayCondition = RMobilePhone::KDisplaySPNRequired;
+        }
+
+    // PLMN and SPN control information summed up to iDisplayReq field
+    iServiceProviderName.iDisplayReq =
+        iServiceProviderName.iDisplayReq + iSecondDisplayCondition;
+TFLOGSTRING2("TSY: CMmPhoneMessHandler::UiccProcessServiceTypeCheck - display condition: %d", (TUint8)iServiceProviderName.iDisplayReq);
+
+    // Buffer for service provider name
+    TBuf16<KSpnFileSize> tempBuf;
+    TIsiUtility::CopyFromBigEndian( spnOutputBuffer, tempBuf );
+    // Copy service provider name
+    iServiceProviderName.iSPName.Copy( tempBuf );
+TFLOGSTRING2("TSY: CMmPhoneMessHandler::UiccProcessServiceTypeCheck - SPN Name: %S", &iServiceProviderName.iSPName);
+
+
+    // We still need to get the PLMN list to complete the information.
+    // Read the SIM file EF SPDI ('6FCD')
+    // Set parameters for UICC_APPL_CMD_REQ message
+    TUiccReadTransparent params;
+    params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
+    params.trId = ETrIdReadServiceProviderDisplayInfo;
+    // Read all the data
+    params.dataAmount = 0;
+    params.dataOffset = 0;
+    params.fileId = KElemFileServiceProviderDisplayInfo;
+    params.fileIdSfi = 0x1B;
+    params.serviceType = UICC_APPL_READ_TRANSPARENT;
+
+    // File id path
+    params.filePath.Append( KMasterFileId >> 8 );
+    params.filePath.Append( KMasterFileId );
+    params.filePath.Append( iMmUiccMessHandler->GetApplicationFileId() );
+
+    return iMmUiccMessHandler->CreateUiccApplCmdReq( params );
+    }
+
+// --------------------------------------------------------------------------
+// CMmPhoneMessHandler::UiccProcessSpnNameInfo
+// Processes SPN name info response
+// --------------------------------------------------------------------------
+//
+void CMmPhoneMessHandler::UiccProcessSpnNameInfo(
+    TInt aStatus,
+    const TDesC8& aFileData)
+    {
+TFLOGSTRING("TSY: CMmPhoneMessHandler::UiccProcessSpnNameInfo");
+OstTrace0( TRACE_NORMAL, CMMPHONEMESSHANDLER_UICCPROCESSSPNNAMEINFO, "CMmPhoneMessHandler::UiccProcessSpnNameInfo" );
+
+    TInt numOfPlmns( 0 );
+    TInt lengthOfDataInBytes( 0 );
+    TInt i( 0 ); // Index used of data extracting
+    if ( KErrNone == aStatus )
+        {
+        TInt lengthOfLengthInBytes( 0 );
+
+        // Display info is coded in TLV format in USIM.
+        // Check the tag
+        if ( 0xA3 == aFileData[i] )
+            {
+            i++;
+            // If bit8 is set, rest of bits tell the number of bytes used for
+            // length
+            if ( aFileData[i] & 0x80 )
+                {
+                lengthOfLengthInBytes = aFileData[i] & 0x7F;
+                i += lengthOfLengthInBytes;
+                }
+            i++;
+
+            // Check the tag
+            if ( 0x80 == aFileData[i] )
+                {
+                // Check how many bytes are used for length field
+                i++;
+                if ( 0 ==  ( aFileData[i] & 0x80 ) )
+                    {
+                    lengthOfDataInBytes = aFileData[i] & 0x7F;
+                    numOfPlmns = lengthOfDataInBytes / 3;
+                    i++; // Data starting point
+                    }
+                else
+                    {
+                    lengthOfLengthInBytes = aFileData[i] & 0x7F;
+                    i++; // Skip length tag
+                    if ( 1 == lengthOfLengthInBytes )
+                        {
+                        lengthOfDataInBytes = aFileData[i];
+                        numOfPlmns = lengthOfDataInBytes / 3;
+                        i++; // Data starting point
+                        }
+                    else // Length is in two bytes
+                        {
+                        lengthOfDataInBytes =
+                            ( aFileData[i] << 8 ) | aFileData[i+1];
+                        numOfPlmns = lengthOfDataInBytes / 3;
+                        i += 2; // Data starting point
+                        }
+                    }
+                }
+            else // Incorrect tag
+                {
+                aStatus = KErrGeneral;
+                }
+            }
+        else // Incorrect tag
+            {
+            aStatus = KErrGeneral;
+            }
+        }
+
+    // Copy PLMNs and complete
+    if ( KErrNone == aStatus )
+        {
+        // Number of PLMNs cannot exceed 170
+        if ( 170 < numOfPlmns )
+            {
+            numOfPlmns = 170;
+            }
+
+        // At first append number of PLMNs and second display condition
+        TUint16 word( static_cast<TUint16>(
+                numOfPlmns << 8 | iSecondDisplayCondition ) );
+        iServiceProviderName.iPLMNField.Append( word );
+
+        // Copy PLMNs to 16 bit buffer
+        for ( TUint8 j( 0 ); j < lengthOfDataInBytes / 2; j++, i += 2 )
+            {
+            // PLMN entries are copied to 16-bit buffer as follows:
+            // 1st byte to 8 LSB bits of 16-bit buffer
+            // 2nd byte to 8 MSB bits of 16-bit buffer
+            word = static_cast<TUint16>(
+                ( aFileData[i+1] << 8 ) | aFileData[i] );
+            iServiceProviderName.iPLMNField.Append( word );
+            }
+        // Last word is added
+        iServiceProviderName.iPLMNField.Append( ( 0xFF << 8 ) | aFileData[i] );
+
+        // Complete SPN info
+        CMmDataPackage dataPackage;
+        dataPackage.PackData( &iServiceProviderName );
+        iMessageRouter->Complete(
+            EMobilePhoneGetServiceProviderName,
+            &dataPackage,
+            KErrNone );
+        }
+    else // Complete error without data
+        {
+        iMessageRouter->Complete(
+             EMobilePhoneGetServiceProviderName,
+             KErrNotFound );
+        }
+
+    // Reset iServiceProviderName for next time.
+    iServiceProviderName.iSPName.Zero();
+    iServiceProviderName.iPLMNField.Zero();
+    }
+
+// End of file