--- /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