adaptationlayer/tsy/nokiatsy_dll/src/cmmsmsmesshandler.cpp
changeset 0 63b37f68c1ce
child 5 8ccc39f9d787
equal deleted inserted replaced
-1:000000000000 0:63b37f68c1ce
       
     1 /*
       
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 //  EXTERNAL RESOURCES
       
    21 
       
    22 //  Include Files
       
    23 #include <ctsy/serviceapi/mmtsy_ipcdefs.h>
       
    24 #include <ctsy/pluginapi/cmmdatapackage.h>
       
    25 // Temporarily removed for Bridge camp!
       
    26 //#include <ctsy/serviceapi/ctsysatmessagingbase.h>
       
    27 #include <etelsat.h>  // for sat mo sm control error values
       
    28 #include <ctsy/serviceapi/gsmerror.h> // for sat mo sm control error values
       
    29 #include <etelmmerr.h>
       
    30 #include <tisi.h>
       
    31 #include <smsisi.h>
       
    32 #include <gsmuelem.h> // for tsmsfirstoctet
       
    33 #include <ctsy/rmmcustomapi.h>
       
    34 #include "cmmsmsmesshandler.h"
       
    35 #include "cmmnetmesshandler.h"
       
    36 #include "cmmsmsgsmaddress.h"
       
    37 #include "cmmstaticutility.h"
       
    38 #include "cmmmessagerouter.h"
       
    39 #include "cmmphonemesshandler.h"
       
    40 #include "tsylogger.h"
       
    41 #include "cmmphonetsender.h"
       
    42 #include "osttracedefinitions.h"
       
    43 #ifdef OST_TRACE_COMPILER_IN_USE
       
    44 #include "cmmsmsmesshandlertraces.h"
       
    45 #endif
       
    46 
       
    47 //  External Data Structures
       
    48 //  none
       
    49 
       
    50 //  External Function Prototypes
       
    51 //  none
       
    52 
       
    53 //  LOCAL CONSTANTS AND MACROS
       
    54 const TUint8 KSmsPadding( 0x00 ); // Filler byte for ISI messages
       
    55 // const TUint8 KUnicodeCharLength( 2 ); Compiler warning removal
       
    56 
       
    57 // The following constanst are for extracting information from TPDU
       
    58 // See 3GPP 23.040.
       
    59 
       
    60 // For submit and command types
       
    61 const TUint8 KTpduIndexMessageParameters( 0 );
       
    62 const TUint8 KTpduIndexMessageReference( 1 );
       
    63 
       
    64 // SMS submit type specific costanst
       
    65 const TUint8 KTpduSubmitIndexDestinationAddressLength( 2 );
       
    66 const TUint8 KTpduSubmitIndexProtocolIdentifier( 4 );
       
    67 const TUint8 KTpduSubmitIndexDataCodingScheme( 5 );
       
    68 const TUint8 KTpduSubmitIndexValidityperiod( 6 );
       
    69 // User data length index when no validity period
       
    70 const TUint8 KTpduSubmitIndexUserDataLengthIfNoTpVp( 6 );
       
    71 // User data length index when validity period length is 1
       
    72 const TUint8 KTpduSubmitIndexUserDataLengthVpfRelative( 7 );
       
    73 // User data length index when validity period length is 7
       
    74 const TUint8 KTpduSubmitIndexUserDataLengthVpfAbsoluteEnchanced( 13 );
       
    75 
       
    76 // SMS command type specific constants
       
    77 const TUint8 KTpduCommandIndexProtocolIdentifier( 2 );
       
    78 const TUint8 KTpduCommandIndexType( 3 );
       
    79 const TUint8 KTpduCommandIndexMessageNumber( 4 );
       
    80 const TUint8 KTpduCommandIndexDestinationAddressLength( 5 );
       
    81 const TUint8 KTpduCommandIndexUserDataLength( 7 );
       
    82 
       
    83 // const TUint8 KSizeOfAlphaTag( 34 ); Compiler warning removal
       
    84 const TUint8 KSmsScTimeStampMaxLength( 7 );
       
    85 
       
    86 //  MODULE DATA STRUCTURES
       
    87 
       
    88 //  Local Data Structures
       
    89 //  none
       
    90 
       
    91 //  Local Function Prototypes
       
    92 //  none
       
    93 
       
    94 //  LOCAL FUNCTIONS
       
    95 //  none
       
    96 
       
    97 //  MEMBER FUNCTIONS
       
    98 
       
    99 //=============================================================================
       
   100 
       
   101 
       
   102 // -----------------------------------------------------------------------------
       
   103 // CMmSmsMessHandler::CMmSmsMessHandler
       
   104 // C++ default constructor
       
   105 // -----------------------------------------------------------------------------
       
   106 //
       
   107 CMmSmsMessHandler::CMmSmsMessHandler()
       
   108     {
       
   109 TFLOGSTRING("TSY: CMmSmsMessHandler::CMmSmsMessHandler: constructor.");
       
   110 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_CMMSMSMESSHANDLER, "CMmSmsMessHandler::CMmSmsMessHandler" );
       
   111     }
       
   112 
       
   113 // -----------------------------------------------------------------------------
       
   114 // CMmSmsMessHandler::CMmSmsMessHandler
       
   115 // C++ default destructor
       
   116 // -----------------------------------------------------------------------------
       
   117 //
       
   118 CMmSmsMessHandler::~CMmSmsMessHandler()
       
   119     {
       
   120 TFLOGSTRING("TSY: CMmSmsMessHandler::CMmSmsMessHandler: destructor.");
       
   121 OstTrace0( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_CMMSMSMESSHANDLER, "CMmSmsMessHandler::~CMmSmsMessHandler" );
       
   122     // Delete arrays
       
   123     if( iSmsListArray )
       
   124         {
       
   125         iSmsListArray->ResetAndDestroy();
       
   126         delete iSmsListArray;
       
   127         }
       
   128 
       
   129     if( iSmspListArray )
       
   130         {
       
   131         iSmspListArray->ResetAndDestroy();
       
   132         delete iSmspListArray;
       
   133         }
       
   134     }
       
   135 
       
   136 // -----------------------------------------------------------------------------
       
   137 // CMmSmsMessHandler::NewL
       
   138 // Creates a new Gsm specific SmsMessageHandler object instance
       
   139 // -----------------------------------------------------------------------------
       
   140 //
       
   141 CMmSmsMessHandler* CMmSmsMessHandler::NewL(
       
   142     CMmPhoNetSender* aPhoNetSender,      // pointer to PhoNet sender
       
   143     CMmPhoNetReceiver* aPhoNetReceiver,  // pointer to PhoNet receiver
       
   144     CMmMessageRouter* aMessageRouter,    // pointer to Message router
       
   145     CMmUiccMessHandler* aUiccMessHandler // pointer to UICC message handler
       
   146     )
       
   147     {
       
   148 TFLOGSTRING("TSY: CMmSmsMessHandler::NewL");
       
   149 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_NEWL, "CMmSmsMessHandler::NewL" );
       
   150     CMmSmsMessHandler* smsMessHandler = new ( ELeave ) CMmSmsMessHandler();
       
   151 
       
   152     CleanupStack::PushL( smsMessHandler );
       
   153     smsMessHandler->iPhoNetSender = aPhoNetSender;
       
   154     smsMessHandler->iMessageRouter = aMessageRouter;
       
   155     smsMessHandler->iMmUiccMessHandler = aUiccMessHandler;
       
   156     smsMessHandler->ConstructL();
       
   157     aPhoNetReceiver->RegisterL( smsMessHandler, PN_SMS );
       
   158     CleanupStack::Pop( smsMessHandler );
       
   159 
       
   160     return smsMessHandler;
       
   161     }
       
   162 
       
   163 // -----------------------------------------------------------------------------
       
   164 // CMmSmsMessHandler::ConstructL
       
   165 // Initialises object attributes
       
   166 // -----------------------------------------------------------------------------
       
   167 //
       
   168 void CMmSmsMessHandler::ConstructL()
       
   169     {
       
   170 TFLOGSTRING("TSY: CMmSmsMessHandler::ConstructL");
       
   171 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_CONSTRUCTL, "CMmSmsMessHandler::ConstructL" );
       
   172     iSmsListArray = new ( ELeave ) CArrayPtrFlat<TSmsMsg>( 1 );
       
   173     iSmspListArray = new ( ELeave ) CArrayPtrFlat<TSmsParameters>( 1 );
       
   174 
       
   175     iReceivedClass2ToBeReSent = EFalse;
       
   176     // default bearer setting is "CS preferred"
       
   177     iMobileSmsBearer = RMobileSmsMessaging::ESmsBearerCircuitPreferred;
       
   178     }
       
   179 
       
   180 // -----------------------------------------------------------------------------
       
   181 // CMmSmsMessHandler::ReceiveMessageL
       
   182 // Called by PhonetReceiver when an ISI message has been received
       
   183 // -----------------------------------------------------------------------------
       
   184 //
       
   185 void CMmSmsMessHandler::ReceiveMessageL( const TIsiReceiveC& aIsiMessage )
       
   186     {
       
   187     TUint8 resource( aIsiMessage.Get8bit( ISI_HEADER_OFFSET_RESOURCEID ) );
       
   188     TUint8 messageId( aIsiMessage.Get8bit( ISI_HEADER_OFFSET_MESSAGEID ) );
       
   189 
       
   190 TFLOGSTRING3("TSY: CMmSmsMessHandler::ReceiveMessageL - resource: %d, msgId: %d", resource, messageId);
       
   191 OstTraceExt2( TRACE_NORMAL, CMMSMSMESSHANDLER_RECEIVEMESSAGEL,"CMmSmsMessHandler::ReceiveMessageL;resource=%hhu;messageId=%hhu", resource, messageId );
       
   192 
       
   193     switch ( resource )
       
   194         {
       
   195         case PN_SMS:
       
   196             {
       
   197             switch( messageId )
       
   198                 {
       
   199                 case SMS_MESSAGE_SEND_RESP:
       
   200                     {
       
   201                     // check transaction id type
       
   202                     TUint8 traId( aIsiMessage.Get8bit(
       
   203                         ISI_HEADER_OFFSET_TRANSID ) );
       
   204                     if ( ESmsMessagingSendMessage == traId )
       
   205                         {
       
   206                         // SMS Messaging-originated SendSMS
       
   207                         SmsMessageSendResp( aIsiMessage,
       
   208                             EMobileSmsMessagingSendMessage );
       
   209                         }
       
   210                     else if ( ESmsMessagingSendNoFdnMessage == traId )
       
   211                         {
       
   212                         SmsMessageSendResp( aIsiMessage,
       
   213                             EMobileSmsMessagingSendMessageNoFdnCheck );
       
   214                         }
       
   215                     else if ( ESmsMessagingSendSatMessage == traId )
       
   216                         {
       
   217                         // SAT-originated SendSMS
       
   218                         SmsMessageSendResp( aIsiMessage,
       
   219                             EMmTsySmsSendSatMessage );
       
   220                         }
       
   221                     else
       
   222                         {
       
   223 TFLOGSTRING2("TSY:CMmSmsMessHandler::ReceiveMessageL:Unexpected transId=%d in SMS_MESSAGE_SEND_RESP.",traId);
       
   224 OstTraceExt1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_RECEIVEMESSAGEL, "CMmSmsMessHandler::ReceiveMessageL;traId=%hhu", traId );
       
   225                         }
       
   226                     break;
       
   227                     }
       
   228                 case SMS_RECEIVE_MESSAGE_RESP:
       
   229                     {
       
   230                     SmsReceiveMessageResp( aIsiMessage );
       
   231                     break;
       
   232                     }
       
   233                 case SMS_RECEIVED_MSG_IND:
       
   234                     {
       
   235                     SmsReceivedMsgInd( aIsiMessage );
       
   236                     break;
       
   237                     }
       
   238                 case SMS_RECEIVED_MSG_REPORT_RESP:
       
   239                     {
       
   240                     SmsReceivedMsgReportResp( aIsiMessage );
       
   241                     break;
       
   242                     }
       
   243                 case SMS_SETTINGS_UPDATE_RESP :
       
   244                     {
       
   245                     SmsSettingsUpdateResp( aIsiMessage );
       
   246                     break;
       
   247                     }
       
   248                 default:
       
   249                     {
       
   250 TFLOGSTRING2("TSY: CMmSmsMessHandler::ReceiveMessageL - PN_SMS - unknown msgId: %d", messageId);
       
   251 OstTraceExt1( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_RECEIVEMESSAGEL, "CMmSmsMessHandler::ReceiveMessageL;messageId=%hhu", messageId );
       
   252                     // No handler methods for ISI-message found.
       
   253                     break;
       
   254                     }
       
   255                 }
       
   256             break;
       
   257             }
       
   258         default:
       
   259             {
       
   260 TFLOGSTRING2("TSY: CMmSmsMessHandler::ReceiveMessageL - unknown resource: %d", resource);
       
   261 OstTraceExt1( TRACE_NORMAL, DUP6_CMMSMSMESSHANDLER_RECEIVEMESSAGEL, "CMmSmsMessHandler::ReceiveMessageL;resource=%hhu", resource );
       
   262             // No handler methods for ISI-message found.
       
   263             break;
       
   264             }
       
   265         }
       
   266     }
       
   267 
       
   268 // -----------------------------------------------------------------------------
       
   269 // CMmSmsMessHandler::SmsMessageSendReq
       
   270 // Creates request for SMS message sending
       
   271 // -----------------------------------------------------------------------------
       
   272 //
       
   273 TInt CMmSmsMessHandler::SmsMessageSendReq(
       
   274     TUint8 aTransactionId,              // Transaction ID
       
   275     const CMmDataPackage* aDataPackage, // Packed data
       
   276     TBool aSmsCheckDisableFdn )         // Add SMS_SB_CHECK_INFO with
       
   277                                         // SMS_CHECK_DISABLE_FDN
       
   278 
       
   279     {
       
   280 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsMessageSendReq. Transaction ID: %d", aTransactionId);
       
   281 OstTraceExt1( TRACE_NORMAL,DUP18_CMMSMSMESSHANDLER_SMSMESSAGESENDREQ,"CMmSmsMessHandler::SmsMessageSendReq;aTransactionId=%hhu", aTransactionId );
       
   282 
       
   283     TInt ret( KErrNone );
       
   284     TUint8 subBlockId( 0 );
       
   285 
       
   286     // Structure for all SMS parameters and user data
       
   287     TSendSmsDataAndAttributes sendData;
       
   288     // Structure for message attributes
       
   289     RMobileSmsMessaging::TMobileSmsSendAttributesV1* msgAttr;
       
   290     // Buffer for TPDU
       
   291     TBuf8<RMobileSmsMessaging::KGsmTpduSize> msgData;
       
   292 
       
   293     aDataPackage->UnPackData( sendData );
       
   294     msgAttr = sendData.iAttributes;
       
   295 
       
   296     // Check TPDU length
       
   297     if ( RMobileSmsMessaging::KGsmTpduSize >= sendData.iMsgData->Length() )
       
   298         {
       
   299         msgData.Append( *sendData.iMsgData );
       
   300         }
       
   301     else
       
   302         {
       
   303         // TPDU too long
       
   304         ret = CMmStaticUtility::EpocErrorCode(
       
   305             KErrArgument,
       
   306             KErrGsmSMSTpduNotSupported );
       
   307 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsMessageSendReq. Error! TPDU too long: %d", sendData.iMsgData->Length());
       
   308 OstTrace1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_SMSMESSAGESENDREQ, "CMmSmsMessHandler::SmsMessageSendReq.Error! TPDU too long;sendData.iMsgData->Length()=%d", sendData.iMsgData->Length() );
       
   309         }
       
   310 
       
   311     // Check the format of TPDU and data buffer
       
   312     if ( ! ( RMobileSmsMessaging::KSmsDataFormat & msgAttr->iFlags &&
       
   313         RMobileSmsMessaging::EFormatGsmTpdu & msgAttr->iDataFormat ) )
       
   314         {
       
   315         ret = CMmStaticUtility::EpocErrorCode(
       
   316             KErrArgument,
       
   317             KErrGsmSMSTpduNotSupported );
       
   318 TFLOGSTRING3("TSY: CMmSmsMessHandler::SmsMessageSendReq. Error! Invalid TPDU format (%d) or data buffer format (%d)", msgAttr->iFlags, msgAttr->iDataFormat );
       
   319 OstTraceExt2( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_SMSMESSAGESENDREQ, "CMmSmsMessHandler::SmsMessageSendReq.Error!;msgAttr->iFlags=%d;msgAttr->iDataFormat=%hhu", msgAttr->iFlags, msgAttr->iDataFormat );
       
   320         }
       
   321 
       
   322     // Get TP-MTI (TP-Message-Type-Indicator) from first octet of TPDU
       
   323     TUint8 tpMti( msgData[KTpduIndexMessageParameters] &
       
   324         TSmsFirstOctet::ESmsMTIMask );
       
   325     if ( TSmsFirstOctet::ESmsMTISubmitOrSubmitReport == tpMti )
       
   326         {
       
   327         subBlockId = SMS_SB_SUBMIT;
       
   328         }
       
   329     else if ( TSmsFirstOctet::ESmsMTIStatusReportOrCommand == tpMti )
       
   330         {
       
   331         subBlockId = SMS_SB_COMMAND;
       
   332         }
       
   333     else // Message type not supported
       
   334         {
       
   335         ret = CMmStaticUtility::EpocErrorCode(
       
   336             KErrArgument,
       
   337             KErrGsmSMSTpduNotSupported );
       
   338 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsMessageSendReq. Error! SMS type not supported: %d", tpMti);
       
   339 OstTraceExt1( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_SMSMESSAGESENDREQ, "CMmSmsMessHandler::SmsMessageSendReq.Error! SMS type not supported;tpMti=%hhu", tpMti );
       
   340         }
       
   341 
       
   342 #if (NCP_COMMON_S60_VERSION_SUPPORT>S60_VERSION_32)
       
   343     // Check whether there is SMS sending ongoing.
       
   344     if ( iSMSSendingOngoing )
       
   345         {
       
   346         ret = KErrServerBusy;
       
   347 TFLOGSTRING("TSY: CMmSmsMessHandler::SmsMessageSendReq. SMS sending failed, server busy!" );
       
   348 OstTrace0( TRACE_NORMAL, DUP17_CMMSMSMESSHANDLER_SMSMESSAGESENDREQ, "CMmSmsMessHandler::SmsMessageSendReq. SMS sending failed, server busy!" );
       
   349         }
       
   350 #endif // NCP_COMMON_S60_VERSION_SUPPORT
       
   351 
       
   352     if ( KErrNone == ret )
       
   353         {
       
   354         // Create and send SMS_MESSAGE_SEND_REQ message with needed subblocks
       
   355         ret = CreateSmsMessageSendReq(
       
   356             aTransactionId,
       
   357             msgAttr,
       
   358             msgData,
       
   359             subBlockId,
       
   360             aSmsCheckDisableFdn );
       
   361         }
       
   362 
       
   363     return ret;
       
   364     }
       
   365 
       
   366 
       
   367 // -----------------------------------------------------------------------------
       
   368 // CMmSmsMessHandler::CreateSmsMessageSendReq
       
   369 // Construct a SMS_MESSAGE_SEND_REQ ISI message with needed subblocks
       
   370 // for SMS message send request to SMS server
       
   371 // -----------------------------------------------------------------------------
       
   372 //
       
   373 TInt CMmSmsMessHandler::CreateSmsMessageSendReq(
       
   374     TUint8 aTransactionId,
       
   375     RMobileSmsMessaging::TMobileSmsSendAttributesV1* aMsgAttr,
       
   376     const TDesC8& aMsgData,
       
   377     TUint8 aSubblockId,
       
   378     TBool aSmsCheckDisableFdn )         // Add SMS_SB_CHECK_INFO with
       
   379                                         // SMS_CHECK_DISABLE_FDN
       
   380 
       
   381     {
       
   382     // Structure of the message, depending on the TP-MTI:
       
   383     // SMS_MESSAGE_SEND_REQ (8 bytes + sub blocks, total max. 212)
       
   384     //  |
       
   385     //  |- SMS_SB_SUBMIT (mandatory, 8 bytes)
       
   386     //  |
       
   387     //  |- SMS_SB_ADDRESS (destination address, mandatory, max. 20 bytes)
       
   388     //  |
       
   389     //  |- SMS_SB_ADDRESS (service center address, mandatory, max. 20 bytes)
       
   390     //  |
       
   391     //  |- SMS_SB_USER_DATA (optional, max. 148 bytes)
       
   392     //  |
       
   393     //  |- SMS_SB_VALIDITY_PERIOD (optional, max. 12 bytes)
       
   394     //
       
   395     // or
       
   396     //
       
   397     // SMS_MESSAGE_SEND_REQ (8 bytes + sub blocks, total max. 220)
       
   398     //  |
       
   399     //  |- SMS_SB_COMMAND (mandatory, 12 bytes)
       
   400     //  |
       
   401     //  |- SMS_SB_ADDRESS (destination address, mandatory, max. 20 bytes)
       
   402     //  |
       
   403     //  |- SMS_SB_ADDRESS (service center address, mandatory, max. 20 bytes)
       
   404     //  |
       
   405     //  |- SMS_SB_USER_DATA (optional, max. 174 bytes)
       
   406 
       
   407 TFLOGSTRING2("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. Subblock ID: %d", aSubblockId);
       
   408 OstTraceExt1( TRACE_NORMAL, DUP9_CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq;aSubblockId=%hhu", aSubblockId );
       
   409 
       
   410     TInt ret( KErrNone );
       
   411     TUint8 addressLength( 0 );
       
   412     ret = GetDestAddressLength( aMsgData, aSubblockId, addressLength );
       
   413 
       
   414     // Destination address is OK. Create ISI message and needed subblocks
       
   415     if ( KErrNone == ret )
       
   416         {
       
   417         TUint8 moreMsgToSend( 0 );
       
   418         TUint8 smsRoute( SMS_ROUTE_DEFAULT );
       
   419         TUint8 tpVpLength( 0 );
       
   420         TUint8 tpVpf( 0 );
       
   421         TUint8 tpVpSubblockLength( SIZE_SMS_SB_VALIDITY_PERIOD );
       
   422         TUint8 tpUdl( 0 );
       
   423         TUint8 tpUserDataLengthIndex( KTpduSubmitIndexUserDataLengthIfNoTpVp );
       
   424         TUint8 tpUserDataIndex( 0 );
       
   425         TUint8 tpDaIndex( KTpduSubmitIndexDestinationAddressLength );
       
   426         TUint8 tpDcs( 0 );
       
   427         TUint8 msgOffset( ISI_HEADER_SIZE + SIZE_SMS_MESSAGE_SEND_REQ );
       
   428         TUint8 numOfSubblocks( 3 ); // 3 mandatory subblocks
       
   429         TUint8 lengthOfAddressSb( 0 );
       
   430         TUint8 lengthOfSMSUserDataSb( 0 );
       
   431         TBool defaultAlphabet( EFalse ); // Data coding type, true if 7-bit
       
   432 
       
   433         // Check if more to send parameter is included
       
   434         if ( RMobileSmsMessaging::KMoreToSend & aMsgAttr->iFlags )
       
   435             {
       
   436             moreMsgToSend = static_cast<TUint8>( aMsgAttr->iMore );
       
   437             }
       
   438 
       
   439         // Set the bearer
       
   440         if ( RMobileSmsMessaging::ESmsBearerPacketOnly == iMobileSmsBearer )
       
   441             {
       
   442             smsRoute = SMS_ROUTE_PS;
       
   443             }
       
   444         else if ( RMobileSmsMessaging::ESmsBearerCircuitOnly ==
       
   445             iMobileSmsBearer )
       
   446             {
       
   447             smsRoute = SMS_ROUTE_CS;
       
   448             }
       
   449         // No else. SMS_ROUTE_DEFAULT is used. The route is used that is
       
   450         // available and preferred by PP-bits or prior client settings
       
   451 
       
   452         // Create SMS_MESSAGE_SEND_REQ message
       
   453         TIsiSend isiMsg( iPhoNetSender->SendBufferDes() );
       
   454         isiMsg.Set8bit( ISI_HEADER_OFFSET_RESOURCEID, PN_SMS );
       
   455         isiMsg.Set8bit(
       
   456             ISI_HEADER_SIZE + SMS_MESSAGE_SEND_REQ_OFFSET_TRANSID,
       
   457             aTransactionId );
       
   458         isiMsg.Set8bit(
       
   459             ISI_HEADER_SIZE + SMS_MESSAGE_SEND_REQ_OFFSET_MESSAGEID,
       
   460             SMS_MESSAGE_SEND_REQ );
       
   461         isiMsg.Set8bit(
       
   462             ISI_HEADER_SIZE + SMS_MESSAGE_SEND_REQ_OFFSET_MOREMESSAGESTOSEND,
       
   463             moreMsgToSend );
       
   464         isiMsg.Set8bit(
       
   465             ISI_HEADER_SIZE + SMS_MESSAGE_SEND_REQ_OFFSET_SMSROUTE,
       
   466             smsRoute );
       
   467         // Set repeatedMessage to FALSE. Tsy doesn't know if message is tried
       
   468         // to send first or second time.
       
   469         isiMsg.Set8bit(
       
   470             ISI_HEADER_SIZE + SMS_MESSAGE_SEND_REQ_OFFSET_REPEATEDMESSAGE,
       
   471             EFalse );
       
   472         // Filler, two bytes
       
   473         isiMsg.Set16bit(
       
   474             ISI_HEADER_SIZE + SMS_MESSAGE_SEND_REQ_OFFSET_FILLERBYTE1,
       
   475             0 );
       
   476 
       
   477 TFLOGSTRING2("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_MESSAGE_SEND_REQ created. Message offset: %d", msgOffset );
       
   478 TFLOGSTRING2("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. More messages to be sent: %d", moreMsgToSend);
       
   479 TFLOGSTRING2("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. SMS route: %d", smsRoute);
       
   480 OstTraceExt3( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq;msgOffset=%hhu;moreMsgToSend=%hhu;smsRoute=%hhu", msgOffset, moreMsgToSend, smsRoute );
       
   481 
       
   482         // Create SMS_SB_SUBMIT subblock
       
   483         if ( SMS_SB_SUBMIT == aSubblockId )
       
   484             {
       
   485             BuildSmsSbSubmit( aMsgData, isiMsg, msgOffset, addressLength );
       
   486             msgOffset += SIZE_SMS_SB_SUBMIT;
       
   487 TFLOGSTRING2("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_SUBMIT created. Message offset: %d", msgOffset );
       
   488 OstTraceExt1( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_SUBMIT created.;msgOffset=%hhu", msgOffset );
       
   489             // Set needed TPDU index values that depends on SMS type, VP existence
       
   490             // and destination address length. Those parameters are needed when
       
   491             // creating subblocks SMS_DESTINATION_ADDRESS, SMS_SB_VALIDITY_PERIOD
       
   492             // and SMS_SB_USER_DATA.
       
   493             // TP-VPF is LSB bits 3 and 4 from the first octect of TPDU
       
   494             tpVpf = ( aMsgData[KTpduIndexMessageParameters] >> 3 ) & 3;
       
   495             if ( tpVpf )
       
   496                 {
       
   497                 // Relative format (tpVpf == 2).
       
   498                 // Subblock length SIZE_SMS_SB_VALIDITY_PERIOD by default
       
   499                 if ( 2 == tpVpf)
       
   500                     {
       
   501                     tpVpLength = SMS_VPF_RELATIVE;
       
   502                     tpUserDataLengthIndex =
       
   503                         KTpduSubmitIndexUserDataLengthVpfRelative;
       
   504                     }
       
   505                 // Absolute or enhanced format, subblock length is 12
       
   506                 else
       
   507                     {
       
   508                     tpVpLength = SMS_VPF_ABSOLUTE_OR_ENHANCED;
       
   509                     tpVpSubblockLength = 12;
       
   510                     tpUserDataLengthIndex =
       
   511                         KTpduSubmitIndexUserDataLengthVpfAbsoluteEnchanced;
       
   512                     }
       
   513                 }
       
   514                 // No else. If no TP-VP, User data length index was set to
       
   515                 // 'KTpduSubmitIndexUserDataLengthIfNoTpVp' by default
       
   516             }
       
   517         else // Create SMS_SB_COMMAND subblock
       
   518             {
       
   519             BuildSmsSbCommand( aMsgData, isiMsg, msgOffset );
       
   520             msgOffset += SIZE_SMS_SB_COMMAND;
       
   521 TFLOGSTRING2("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_COMMAND created. Message offset: %d", msgOffset );
       
   522 OstTraceExt1( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_COMMAND created.;msgOffset=%hhu", msgOffset );
       
   523 
       
   524             tpDaIndex = KTpduCommandIndexDestinationAddressLength;
       
   525             tpUserDataLengthIndex = KTpduCommandIndexUserDataLength;
       
   526             }
       
   527 
       
   528 TFLOGSTRING2("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. Validity period format: %d", tpVpf);
       
   529 TFLOGSTRING2("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. User data length index: %d", tpUserDataLengthIndex);
       
   530 OstTraceExt2( TRACE_NORMAL, CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq;tpVpf=%hhu;tpUserDataLengthIndex=%hhu", tpVpf, tpUserDataLengthIndex );
       
   531 
       
   532         // Create SMS_SB_ADDRESS subblock for destination address
       
   533         // TP-DA length = Length (1 byte) + TON/NPI (1 byte) + address data
       
   534         TPtrC8 addressData( aMsgData.Mid( tpDaIndex, ( addressLength + 2 ) ) );
       
   535         lengthOfAddressSb = BuildSmsSbAddress(
       
   536             addressData,
       
   537             isiMsg,
       
   538             SMS_DESTINATION_ADDRESS,
       
   539             msgOffset );
       
   540         msgOffset += lengthOfAddressSb;
       
   541 TFLOGSTRING2("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_ADDRESS created for destination address. Message offset: %d", msgOffset );
       
   542 OstTraceExt1( TRACE_NORMAL, DUP4_CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_ADDRESS created for destination address.;msgOffset=%hhu", msgOffset );
       
   543 
       
   544         // Create SMS_SB_ADDRESS subblock for service center address
       
   545         TBuf8<SMS_ADDRESS_MAX_LEN> scAddr;
       
   546         BuildScAddress( aMsgAttr->iGsmServiceCentre, scAddr );
       
   547         lengthOfAddressSb =
       
   548             BuildSmsSbAddress( scAddr, isiMsg, SMS_SMSC_ADDRESS, msgOffset );
       
   549         msgOffset += lengthOfAddressSb;
       
   550 TFLOGSTRING2("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_ADDRESS created for SC address. Message offset: %d", msgOffset );
       
   551 OstTraceExt1( TRACE_NORMAL, DUP5_CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq.SMS_SB_ADDRESS created for SC address.;msgOffset=%hhu", msgOffset );
       
   552 
       
   553         // Create SMS_SB_VALIDITY_PERIOD subblock (optional, used only in
       
   554         // case of SMS_SB_SUBMIT)
       
   555         if ( SMS_SB_SUBMIT == aSubblockId && tpVpf )
       
   556             {
       
   557             TUint8 tpVpIndex(
       
   558                 KTpduSubmitIndexValidityperiod + addressLength );
       
   559             BuildSmsSbValidityPeriod(
       
   560                 aMsgData,
       
   561                 isiMsg,
       
   562                 tpVpIndex,
       
   563                 tpVpLength,
       
   564                 msgOffset );
       
   565             // Udate message offset according to validity period length
       
   566             msgOffset += tpVpSubblockLength;
       
   567             numOfSubblocks++;
       
   568 TFLOGSTRING2("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_VALIDITY_PERIOD created. Message offset: %d", msgOffset );
       
   569 OstTraceExt1( TRACE_NORMAL, DUP6_CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq.SMS_SB_VALIDITY_PERIOD created.;msgOffset=%hhu", msgOffset );
       
   570             }
       
   571 
       
   572         // Create SMS_SB_USER_DATA subblock if user data exists
       
   573         // Destination address length must be added to get user data
       
   574         // length index
       
   575         tpUserDataLengthIndex += addressLength;
       
   576         tpUdl = aMsgData[tpUserDataLengthIndex];
       
   577 TFLOGSTRING2("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. User data length from TPDU: %d", tpUdl);
       
   578 OstTrace1( TRACE_NORMAL, DUP10_CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq;tpUdl=%d", tpUdl );
       
   579 
       
   580         if ( tpUdl )
       
   581             {
       
   582             // Actual user data is next index from TP-UDL position
       
   583             tpUserDataIndex = tpUserDataLengthIndex + 1;
       
   584             if ( SMS_SB_SUBMIT == aSubblockId )
       
   585                 {
       
   586                 tpDcs = aMsgData[ KTpduSubmitIndexDataCodingScheme + addressLength ];
       
   587                 defaultAlphabet = IsDataCodingScheme7Bit( tpDcs );
       
   588                 }
       
   589             lengthOfSMSUserDataSb = BuildSmsSbUserData(
       
   590                 aMsgData,
       
   591                 isiMsg,
       
   592                 tpUdl,
       
   593                 tpUserDataIndex,
       
   594                 defaultAlphabet,
       
   595                 msgOffset
       
   596                 );
       
   597             numOfSubblocks++;
       
   598             msgOffset += lengthOfSMSUserDataSb + 1; // Add one byte to put offset into
       
   599                                                     // next free position.
       
   600 TFLOGSTRING("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_USER_DATA created." );
       
   601 OstTrace0( TRACE_NORMAL, DUP7_CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_USER_DATA created." );
       
   602             }
       
   603 
       
   604         // Create SMS_SB_CHECK_INFO subblock if user data exists
       
   605         // Destination address length must be added to get user data
       
   606         // length index
       
   607         if ( aSmsCheckDisableFdn )
       
   608             {
       
   609             BuildSmsCheckInfo(
       
   610                 isiMsg,
       
   611                 msgOffset );
       
   612             numOfSubblocks++;
       
   613 TFLOGSTRING("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_CHECK_INFO created." );
       
   614 OstTrace0( TRACE_NORMAL, DUP11_CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_SB_CHECK_INFO created." );
       
   615             }
       
   616 
       
   617 
       
   618 #if (NCP_COMMON_S60_VERSION_SUPPORT>S60_VERSION_32)
       
   619         iSMSSendingOngoing = ETrue;
       
   620 #endif //NCP_COMMON_S60_VERSION_SUPPORT
       
   621 
       
   622         // Set number of subblocks and then send message via phonet
       
   623         isiMsg.Set8bit(
       
   624             ISI_HEADER_SIZE + SMS_MESSAGE_SEND_REQ_OFFSET_SUBBLOCKCOUNT,
       
   625             numOfSubblocks );
       
   626         ret = iPhoNetSender->Send( isiMsg.Complete() );
       
   627 
       
   628 TFLOGSTRING3("TSY: CMmSmsMessHandler::CreateSmsMessageSendReq. SMS_MESSAGE_SEND_REQ was sent. Number of subblocks in message: %d, ret = %d", numOfSubblocks, ret  );
       
   629 OstTraceExt2( TRACE_NORMAL, DUP8_CMMSMSMESSHANDLER_CREATESMSMESSAGESENDREQ, "CMmSmsMessHandler::CreateSmsMessageSendReq.SMS_MESSAGE_SEND_REQ was sent.;numOfSubblocks=%hhu;ret=%d", numOfSubblocks, ret );
       
   630         } // End of if destination address is OK
       
   631 
       
   632     return ret;
       
   633     }
       
   634 
       
   635 
       
   636 // -----------------------------------------------------------------------------
       
   637 // CMmSmsMessHandler::SmsReceiveMessageReq
       
   638 // Construct a SMS_RECEIVE_MESSAGE_REQ ISI message for activating SMS receiving
       
   639 // and send it to SMS server
       
   640 // -----------------------------------------------------------------------------
       
   641 //
       
   642 TInt CMmSmsMessHandler::SmsReceiveMessageReq( TUint8 aAction )
       
   643     {
       
   644 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsReceiveMessageReq. Action = %d",aAction );
       
   645 OstTraceExt1( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSRECEIVEMESSAGEREQ, "CMmSmsMessHandler::SmsReceiveMessageReq;aAction=%hhu", aAction );
       
   646 
       
   647     TUint8 trId( 0 );
       
   648     if ( SMS_RECEPTION_STORAGE_STATUS_UPDATE == aAction )
       
   649         {
       
   650         trId = ESmsMessagingResumeSmsReception;
       
   651         }
       
   652     TIsiSend isiMsg( iPhoNetSender->SendBufferDes() );
       
   653     isiMsg.Set8bit( ISI_HEADER_OFFSET_RESOURCEID, PN_SMS );
       
   654     isiMsg.Set8bit(
       
   655         ISI_HEADER_SIZE + SMS_RECEIVE_MESSAGE_REQ_OFFSET_TRANSID, trId );
       
   656     isiMsg.Set8bit(
       
   657         ISI_HEADER_SIZE + SMS_RECEIVE_MESSAGE_REQ_OFFSET_MESSAGEID,
       
   658         SMS_RECEIVE_MESSAGE_REQ );
       
   659     isiMsg.Set8bit(
       
   660         ISI_HEADER_SIZE + SMS_RECEIVE_MESSAGE_REQ_OFFSET_ACTION, aAction );
       
   661     isiMsg.Set8bit(
       
   662         ISI_HEADER_SIZE + SMS_RECEIVE_MESSAGE_REQ_OFFSET_FILLERBYTE1,
       
   663         KSmsPadding );
       
   664 
       
   665     return iPhoNetSender->Send( isiMsg.Complete() );
       
   666     }
       
   667 
       
   668 // --------------------------------------------------------------------------
       
   669 // CMmSmsMessHandler::SmsReceivedMsgReportReq
       
   670 // Construct a SMS_RECEIVED_MSG_REPORT_REQ ISI message sub block for received
       
   671 // SMS report request to the SMS server
       
   672 // -----------------------------------------------------------------------------
       
   673 //
       
   674 TInt CMmSmsMessHandler::SmsReceivedMsgReportReq(
       
   675     TUint8 aTransactionId,      // Transaction identifier
       
   676     const TDesC8* aMsgData,     // A pointer to the message data
       
   677     TInt aRpCause )             // RP cause value
       
   678     {
       
   679     // Structure of the message:
       
   680     // SMS_RECEIVED_MSG_REPORT_REQ (8 bytes + sub blocks. Max. total 204 bytes)
       
   681     //  |
       
   682     //  |- SMS_SB_DELIVER_REPORT (optional, included in NACK case
       
   683     //  |                         8 bytes )
       
   684     //  |- SMS_SB_PARAM_INDICATOR (optional, included if PDU (aMsgData) is not
       
   685     //  |                          empty. Max. 20 bytes)
       
   686     //  |- SMS_SB_USER_DATA (optional, included if PDU contains user data.
       
   687     //                       Max. 8  + SMS_GSM_DELIVER_ACK_UD_MAX_LEN
       
   688     //                       + padding = 168 bytes)
       
   689 
       
   690 TFLOGSTRING3("TSY: CMmSmsMessHandler::SmsReceivedMsgReportReq - traId: %d, RP cause value: %d", aTransactionId, aRpCause);
       
   691 OstTraceExt2( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSRECEIVEDPPREPORTREQ, "CMmSmsMessHandler::SmsReceivedMsgReportReq;aTransactionId=%hhu;aRpCause=%d", aTransactionId, aRpCause );
       
   692 
       
   693     TInt ret( KErrNone );
       
   694     TUint8 numOfSubblocks( 0 ); // All subblocks are optional
       
   695     TUint8 tpFailureCause( 0 );
       
   696     TUint8 causeType( 0 ); // SMS_CAUSE_TYPE_COMMON
       
   697     TUint8 smsCause( 0 ); // SMS_CAUSE_OK
       
   698     TUint8 messageParameters( 0 ); // Default message parameters
       
   699     TUint8 sbOffset( ISI_HEADER_SIZE + SIZE_SMS_RECEIVED_MSG_REPORT_REQ );
       
   700     TUint8 paramIndSbLength( SIZE_SMS_SB_PARAM_INDICATOR );
       
   701     TBool userDataIncluded( EFalse );
       
   702 
       
   703     // Create SMS_SB_DELIVER_REPORT. Buffer size must be 168
       
   704     // (subblock size + user data). This subblock is added to message only
       
   705     // in NACK case.
       
   706     TBuf8<SIZE_SMS_SB_DELIVER_REPORT> deliverReportBuf;
       
   707     TIsiSubBlock deliverReportSb(
       
   708         deliverReportBuf,
       
   709         SMS_SB_DELIVER_REPORT,
       
   710         EIsiSubBlockTypeId16Len16 );
       
   711 
       
   712     // Create SMS_SB_USER_DATA. This subblock is added to message only if
       
   713     // user data exists
       
   714     TBuf8<SIZE_SMS_SB_USER_DATA + SMS_DELIVER_ACK_UD_MAX_LEN>
       
   715         userDataBuf;
       
   716     TIsiSubBlock userDataSb(
       
   717         userDataBuf,
       
   718         SMS_SB_USER_DATA,
       
   719         EIsiSubBlockTypeId16Len16 );
       
   720 
       
   721     // Create SMS_SB_PARAM_INDICATOR. This subblock is added to message only
       
   722     // if user data exists
       
   723     TBuf8<20> paramIndicatorBuf;
       
   724     TIsiSubBlock paramIndicatorSb(
       
   725          paramIndicatorBuf,
       
   726          SMS_SB_PARAM_INDICATOR,
       
   727          EIsiSubBlockTypeId16Len16 );
       
   728 
       
   729     // If RP Cause value is other than KErrNone, values of the cause type and the
       
   730     // SMS cause must be defined. In this case we also include subblock
       
   731     // SMS_SB_DELIVER_REPORT.
       
   732     if ( KErrNone != aRpCause )
       
   733         {
       
   734         causeType = SMS_CAUSE_TYPE_EXT;
       
   735         smsCause = SmsMapCause( aRpCause );
       
   736         numOfSubblocks++;
       
   737         }
       
   738 
       
   739     // If message data is available
       
   740     if ( NULL != aMsgData && 0 < aMsgData->Length() )
       
   741         {
       
   742 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsReceivedMsgReportReq. Message data availabe, length %d", aMsgData->Length());
       
   743 OstTrace1( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSRECEIVEDMSGREPORTREQ, "CMmSmsMessHandler::SmsReceivedMsgReportReq;aMsgData->Length()=%d", aMsgData->Length() );
       
   744 
       
   745         TUint8 ind( 0 );
       
   746 
       
   747         // Message parameters = 1st byte of deliver report
       
   748         messageParameters = ( *aMsgData )[ind++];
       
   749 
       
   750         // Message type indicator is 2 LSB in message parameters.
       
   751         TUint8 tpMti( messageParameters & 0x03 );
       
   752 
       
   753         // If both bits in the TP_MTI are 0, message type is
       
   754         // SMS DELIVER REPORT (3GPP 23.040 chapter 9.2.3.1)
       
   755         if ( 0 == tpMti )
       
   756             {
       
   757             TUint8 protocolInd( 0 );
       
   758             TUint8 dcs( 0 );
       
   759             TUint8 tpUdl( 0 );
       
   760             TPtrC8 userData( 0, 0 );
       
   761 
       
   762             if ( 0 != aRpCause )
       
   763                 {
       
   764                 tpFailureCause = ( *aMsgData )[ind++];
       
   765                 }
       
   766 
       
   767             // Lets find out how many parameter indicators are there
       
   768             TBuf8<SMS_PARAM_INDICATOR_MAX_LEN> paramIndicator;
       
   769             TUint8 paramIndCount( 1 ); // There is at least one TP-PI
       
   770             TUint8 paramInd( 0 );
       
   771             TBool moreParamInd( ETrue );
       
   772 
       
   773             while ( moreParamInd )
       
   774                 {
       
   775                 paramInd = ( *aMsgData )[ind++];
       
   776                 paramIndicator.Append( paramInd );
       
   777                 paramInd = paramInd >> 7;
       
   778 
       
   779                 // If true, another TP-PI octet follows immediately afterwards
       
   780                 if ( KSmsDelRepParamIndExtensionBit == paramInd )
       
   781                     {
       
   782                     paramIndCount++;
       
   783                     }
       
   784                 else
       
   785                     {
       
   786                     moreParamInd = EFalse;
       
   787                     }
       
   788 
       
   789                 // Too many TP-PI octets -> this PDU is corrupted.
       
   790                 if ( SMS_PARAM_INDICATOR_MAX_LEN < paramIndCount )
       
   791                     {
       
   792 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsReceivedMsgReportReq. Error! Too mamy TP-PI parameters: %d", paramIndCount );
       
   793 OstTraceExt1( TRACE_NORMAL, DUP4_CMMSMSMESSHANDLER_SMSRECEIVEDMSGREPORTREQ, "CMmSmsMessHandler::SmsReceivedMsgReportReq. Error!;paramIndCount=%hhu", paramIndCount );
       
   794                     ret = KErrArgument;
       
   795                     moreParamInd = EFalse;
       
   796                     }
       
   797                 }
       
   798 
       
   799             // Calculate final length of SMS_SB_PARAM_INDICATOR, depends on
       
   800             // number of param indicators. Must be divisible by 4.
       
   801             if ( paramIndCount > 1)
       
   802                 {
       
   803                 // One param indicator has already counted
       
   804                 paramIndSbLength += ( --paramIndCount );
       
   805                 while( paramIndSbLength % 4 )
       
   806                     {
       
   807                     paramIndSbLength++;
       
   808                     }
       
   809                 }
       
   810 
       
   811             // Lets take first TP-PI and check what fields this PDU includes
       
   812             paramInd = paramIndicator[0];
       
   813             TInt paramask( KSmsParametersIndMask & paramInd ); // Mask bits
       
   814 
       
   815             // Gather data from PDU using parameter indicator information
       
   816             if ( KSmsParametersIndProtocolId & paramask )
       
   817                 {
       
   818                 protocolInd = ( *aMsgData )[ind++];
       
   819                 }
       
   820             if ( KSmsParametersIndDataCodingScheme & paramask )
       
   821                 {
       
   822                 dcs = ( *aMsgData )[ind++];
       
   823                 }
       
   824             if ( KSmsParametersIndUserData & paramask )
       
   825                 {
       
   826                 tpUdl = ( *aMsgData )[ind++];
       
   827                 }
       
   828 TFLOGSTRING4("TSY: CMmSmsMessHandler::SmsReceivedMsgReportReq. protocolInd: %d, dcs: %d, tpUdl: %d", protocolInd, dcs, tpUdl );
       
   829 OstTraceExt3( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_SMSRECEIVEDMSGREPORTREQ, "CMmSmsMessHandler::SmsReceivedMsgReportReq;protocolInd=%hhu;dcs=%hhu;tpUdl=%hhu", protocolInd, dcs, tpUdl );
       
   830 
       
   831             // If user data exists, fill SMS_SB_USER_DATA and
       
   832             // SMS_SB_PARAM_INDICATOR subblocks
       
   833             if ( 0 < tpUdl )
       
   834                 {
       
   835                 TUint8 userDataLengthInBytes( 0 );
       
   836                 userDataIncluded = ETrue;
       
   837                 numOfSubblocks += 2;
       
   838 
       
   839                 TBool defaultAlphabet( IsDataCodingScheme7Bit( dcs ) );
       
   840                 // If data is 7bit, then TP-UDL is integer reprentation of
       
   841                 // the number of septets within the TP-UD field.
       
   842                 if ( defaultAlphabet )
       
   843                     {
       
   844                     // Data length in bytes
       
   845                     userDataLengthInBytes = ( ( tpUdl + 1 ) * 7 ) / 8 ;
       
   846                     }
       
   847                 else
       
   848                     {
       
   849                     userDataLengthInBytes = tpUdl;
       
   850                     }
       
   851 
       
   852                 // Append filler + user data length in bytes
       
   853                 userDataBuf.Append( KSmsPadding );
       
   854                 userDataBuf.Append( userDataLengthInBytes );
       
   855                 // Append filler + amount of characters in user data
       
   856                 userDataBuf.Append( KSmsPadding );
       
   857                 userDataBuf.Append( tpUdl );
       
   858                 // Append user data
       
   859                 userData.Set( aMsgData->Mid( ind, userDataLengthInBytes ) );
       
   860                 userDataBuf.Append( userData );
       
   861 
       
   862                 paramIndicatorBuf.Append( protocolInd );
       
   863                 paramIndicatorBuf.Append( dcs );
       
   864                 paramIndicatorBuf.Append( paramIndicator.Length() );
       
   865                 paramIndicatorBuf.Append( paramIndicator );
       
   866                 } // End of if ( 0 < tpUdl )
       
   867             } // end of if ( 0 == tpMti )
       
   868         else
       
   869         // TP-MTI is other than SMS_GSM_DELIVER_REPORT, message is not sent
       
   870             {
       
   871 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsReceivedMsgReportReq. Error! Invalid message type indicator: %d", tpMti);
       
   872 OstTraceExt1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_SMSRECEIVEDMSGREPORTREQ, "CMmSmsMessHandler::SmsReceivedMsgReportReq;tpMti=%hhu", tpMti );
       
   873             ret = KErrArgument;
       
   874             }
       
   875         } // end of if ( NULL != aMsgData && 0 < aMsgData->Length() )
       
   876     else
       
   877         {
       
   878 TFLOGSTRING("TSY: CMmSmsMessHandler::SmsReceivedMsgReportReq. No message data availabe!");
       
   879 OstTrace0( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_SMSRECEIVEDMSGREPORTREQ, "CMmSmsMessHandler::SmsReceivedMsgReportReq. No message data available" );
       
   880         // If memory capacity exceeded -> gsmTpfailureCause is 0
       
   881         if ( 0 != aRpCause && SMS_EXT_ERR_MEMORY_CAPACITY_EXC != smsCause  )
       
   882             {
       
   883             // 0xAF is unspecified TP-command error
       
   884             tpFailureCause = 0xAF;
       
   885             }
       
   886         }
       
   887 
       
   888     // Send SMS_RECEIVED_MSG_REPORT_REQ
       
   889     if ( KErrNone == ret )
       
   890         {
       
   891         // Create SMS_RECEIVED_MSG_REPORT_REQ message
       
   892         TIsiSend isiMsg( iPhoNetSender->SendBufferDes() );
       
   893         isiMsg.Set8bit( ISI_HEADER_OFFSET_RESOURCEID, PN_SMS );
       
   894         isiMsg.Set8bit(
       
   895             ISI_HEADER_SIZE + SMS_RECEIVED_MSG_REPORT_REQ_OFFSET_TRANSID,
       
   896             aTransactionId );
       
   897         isiMsg.Set8bit(
       
   898             ISI_HEADER_SIZE + SMS_RECEIVED_MSG_REPORT_REQ_OFFSET_MESSAGEID,
       
   899             SMS_RECEIVED_MSG_REPORT_REQ );
       
   900         isiMsg.Set8bit(
       
   901             ISI_HEADER_SIZE + SMS_RECEIVED_MSG_REPORT_REQ_OFFSET_CAUSETYPE,
       
   902             causeType );
       
   903         isiMsg.Set8bit(
       
   904             ISI_HEADER_SIZE + SMS_RECEIVED_MSG_REPORT_REQ_OFFSET_SMSCAUSE,
       
   905             smsCause );
       
   906         isiMsg.Set8bit( ISI_HEADER_SIZE +
       
   907             SMS_RECEIVED_MSG_REPORT_REQ_OFFSET_FILLERBYTE1,
       
   908             KSmsPadding );
       
   909         isiMsg.Set8bit( ISI_HEADER_SIZE +
       
   910             SMS_RECEIVED_MSG_REPORT_REQ_OFFSET_SUBBLOCKCOUNT,
       
   911             numOfSubblocks );
       
   912 
       
   913         // Add SMS_SB_DELIVER_REPORT if needed
       
   914         if ( 0 != aRpCause )
       
   915             {
       
   916             deliverReportBuf.Append( messageParameters );
       
   917             deliverReportBuf.Append( tpFailureCause);
       
   918             // Add SMS_SB_DELIVER_REPORT subblock
       
   919             isiMsg.CopyData( sbOffset, deliverReportSb.CompleteSubBlock() );
       
   920             sbOffset += SIZE_SMS_SB_DELIVER_REPORT;
       
   921             }
       
   922 
       
   923         // Add SMS_SB_PARAM_INDICATOR & SMS_SB_USER_DATA subblocks if needed
       
   924         if ( userDataIncluded )
       
   925             {
       
   926             // Add SMS_SB_PARAM_INDICATOR subblock
       
   927             isiMsg.CopyData( sbOffset, paramIndicatorSb.CompleteSubBlock() );
       
   928             // Add SMS_SB_USER_DATA subblock
       
   929             sbOffset += paramIndSbLength;
       
   930             isiMsg.CopyData( sbOffset, userDataSb.CompleteSubBlock() );
       
   931             }
       
   932 
       
   933         ret = iPhoNetSender->Send( isiMsg.Complete() );
       
   934         }
       
   935 
       
   936     return ret;
       
   937     }
       
   938 
       
   939 // --------------------------------------------------------------------------
       
   940 // Maps RP cause value to SMS cause value.
       
   941 // --------------------------------------------------------------------------
       
   942 TUint8 CMmSmsMessHandler::SmsMapCause ( TInt aRpCause )
       
   943     {
       
   944 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsReceivedPpReportReq - aRpCause: %d", aRpCause);
       
   945 OstTrace1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_SMSMAPCAUSE, "CMmSmsMessHandler::SmsMapCause;aRpCause=%d", aRpCause );
       
   946 
       
   947     //initialization of the Sms Cause value is 0x00 (SMS_CAUSE_OK)
       
   948     TUint8 retSmsCause( 0 );
       
   949 
       
   950     switch ( aRpCause )
       
   951         {
       
   952         case KErrGsmSMSMemoryCapacityExceeded:
       
   953             {
       
   954             retSmsCause = SMS_EXT_ERR_MEMORY_CAPACITY_EXC;
       
   955             break;
       
   956             }
       
   957 
       
   958         //Try to find matching RP cause value from GSM 04.11
       
   959 
       
   960         case KErrGsmSMSInvalidShortMessageTransferReferenceValue:
       
   961             {
       
   962             retSmsCause = SMS_EXT_ERR_INVALID_REFERENCE;
       
   963             break;
       
   964             }
       
   965 
       
   966         case KErrGsmSMSNonExistentMessageType:
       
   967             {
       
   968             retSmsCause = SMS_EXT_ERR_INCORRECT_MESSAGE;
       
   969             break;
       
   970             }
       
   971 
       
   972         case KErrGsmSMSInvalidMandatoryInformation:
       
   973             {
       
   974             retSmsCause = SMS_EXT_ERR_INVALID_MAND_INFO;
       
   975             break;
       
   976             }
       
   977 
       
   978         case KErrGsmSMSIncompatibleMessageWithSmsProtocolState:
       
   979             {
       
   980             retSmsCause = SMS_EXT_ERR_MSG_NOT_COMP_WITH_ST;
       
   981             break;
       
   982             }
       
   983 
       
   984         case KErrGsmSMSInformationElementNotImplemented:
       
   985             {
       
   986             retSmsCause = SMS_EXT_ERR_INVALID_INFO_ELEMENT;
       
   987             break;
       
   988             }
       
   989 
       
   990         case KErrGsmSMSUnspecifiedInvalidMessage:
       
   991             {
       
   992             retSmsCause = SMS_EXT_ERR_INVALID_MSG_TYPE;
       
   993             break;
       
   994             }
       
   995 
       
   996         case KErrGsmSMSUnspecifiedProtocolError:
       
   997             {
       
   998             retSmsCause = SMS_EXT_ERR_PROTOCOL_ERROR;
       
   999             break;
       
  1000             }
       
  1001 
       
  1002         default:
       
  1003             {
       
  1004 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsReceivedPpReportReq - unknown RpCause: %d", aRpCause);
       
  1005 OstTrace1( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSMAPCAUSE, "CMmSmsMessHandler::SmsMapCause;unknown aRpCause=%d", aRpCause );
       
  1006             retSmsCause = SMS_EXT_ERR_PROTOCOL_ERROR;
       
  1007             break;
       
  1008             }
       
  1009         }
       
  1010 
       
  1011     return retSmsCause;
       
  1012     }
       
  1013 
       
  1014 // -----------------------------------------------------------------------------
       
  1015 // CMmSmsMessHandler::SmsMessageSendResp
       
  1016 // Breaks a ISI-message and get possible TP-Failure-Cause from
       
  1017 // ISI-message.
       
  1018 // -----------------------------------------------------------------------------
       
  1019 //
       
  1020 void CMmSmsMessHandler::SmsMessageSendResp(
       
  1021     const TIsiReceiveC& aIsiMsg,
       
  1022     TInt aIpc )
       
  1023     {
       
  1024 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsMessageSendResp - IPC: %d", aIpc);
       
  1025 OstTrace1( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSMESSAGESENDRESP, "CMmSmsMessHandler::SmsMessageSendResp;aIpc=%d", aIpc );
       
  1026 
       
  1027     TInt epocCause( KErrNone );
       
  1028     TUint16 msgRef( 0 );
       
  1029     TUint8 tpFailureCause( 0 );
       
  1030 
       
  1031     // Cause type and cause value
       
  1032     TUint8 smsServerCauseType( aIsiMsg.Get8bit(
       
  1033         ISI_HEADER_SIZE + SMS_MESSAGE_SEND_RESP_OFFSET_CAUSETYPE ) );
       
  1034     TUint8 smsServerCauseValue = aIsiMsg.Get8bit(
       
  1035         ISI_HEADER_SIZE + SMS_MESSAGE_SEND_RESP_OFFSET_SMSCAUSE );
       
  1036 
       
  1037     if ( SMS_OK != smsServerCauseValue )
       
  1038         {
       
  1039         if ( SMS_CAUSE_TYPE_COMMON == smsServerCauseType )
       
  1040             {
       
  1041             if ( SMS_ERR_RC_REJECTED  == smsServerCauseValue )
       
  1042                 {
       
  1043                 if ( EMobileSmsMessagingSendMessage == aIpc )
       
  1044                     {
       
  1045 TFLOGSTRING("TSY: CMmSmsMessHandler::SmsMessageSendResp - server cause: SMS_ERR_RC_REJECTED");
       
  1046 OstTrace0( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_SMSMESSAGESENDRESP, "CMmSmsMessHandler::SmsMessageSendResp, server cause: SMS_ERR_RC_REJECTED" );
       
  1047                     // This is an ETel MM-initiated SMS, barred by SAT.
       
  1048                     epocCause = CMmStaticUtility::EpocErrorCode(
       
  1049                         KErrAccessDenied,
       
  1050                         KErrSatControl );
       
  1051                     }
       
  1052                 else if (  EMmTsySmsSendSatMessage == aIpc )
       
  1053                     {
       
  1054 TFLOGSTRING("TSY: CMmSmsMessHandler::SmsMessageSendResp - server cause: SMS_ERR_RC_REJECTED");
       
  1055 OstTrace0( TRACE_NORMAL, DUP4_CMMSMSMESSHANDLER_SMSMESSAGESENDRESP, "CMmSmsMessHandler::SmsMessageSendResp, server cause: SMS_ERR_RC_REJECTED" );
       
  1056                     // This is a SAT-initiated SMS, barred by SAT.
       
  1057                     epocCause = KErrSatMoSmControlBarred;
       
  1058                     }
       
  1059                 }
       
  1060              else
       
  1061                 {
       
  1062                 epocCause = CMmStaticUtility::CSCauseToEpocError(
       
  1063                     PN_SMS,
       
  1064                     SMS_CAUSE_TYPE_COMMON,
       
  1065                     smsServerCauseValue );
       
  1066                 }
       
  1067             }
       
  1068         else if ( SMS_CAUSE_TYPE_EXT == smsServerCauseType )
       
  1069             {
       
  1070             epocCause = CMmStaticUtility::CSCauseToEpocError(
       
  1071                 PN_SMS,
       
  1072                 SMS_CAUSE_TYPE_EXT,
       
  1073                 smsServerCauseValue );
       
  1074             }
       
  1075         else // Invalid cause type
       
  1076             {
       
  1077 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsMessageSendResp: Unknown cause type %d.", smsServerCauseType );
       
  1078 OstTraceExt1( TRACE_NORMAL, DUP5_CMMSMSMESSHANDLER_SMSMESSAGESENDRESP, "CMmSmsMessHandler::SmsMessageSendResp;smsServerCauseType=%hhu", smsServerCauseType );
       
  1079 TF_ASSERT_NOT_REACHED();
       
  1080             }
       
  1081         }
       
  1082     else // Sending was OK
       
  1083         {
       
  1084         msgRef = aIsiMsg.Get8bit( ISI_HEADER_SIZE +
       
  1085             SMS_MESSAGE_SEND_RESP_OFFSET_REFERENCEFORMESSAGE );
       
  1086         }
       
  1087 
       
  1088     TUint smsSbSubmitReportOffset( 0 );
       
  1089     if ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
       
  1090         ISI_HEADER_SIZE + SIZE_SMS_MESSAGE_SEND_RESP,
       
  1091         SMS_SB_SUBMIT_REPORT,
       
  1092         EIsiSubBlockTypeId16Len16,
       
  1093         smsSbSubmitReportOffset ) )
       
  1094         {
       
  1095         // SMS_SB_SUBMIT_REPORT subblock exists.
       
  1096         // SMS server sets TP-Failure-Cause to zero in OK case.
       
  1097         tpFailureCause = aIsiMsg.Get8bit(
       
  1098             smsSbSubmitReportOffset
       
  1099             + SMS_SB_SUBMIT_REPORT_OFFSET_TPFAILURECAUSE );
       
  1100         }
       
  1101 
       
  1102     // Response for send SMS request
       
  1103     if ( EMobileSmsMessagingSendMessage == aIpc
       
  1104         || EMobileSmsMessagingSendMessageNoFdnCheck == aIpc )
       
  1105         {
       
  1106         TBuf8<RMobileSmsMessaging::KGsmTpduSize> pdu;
       
  1107 
       
  1108         // Create default SMS SUBMIT REPORT. Some operators may send
       
  1109         // some information inside of this pdu. SMS stack refuses
       
  1110         // to handle submit report that doesn't follow GSM 24.040 & 23.038
       
  1111         // specifications.
       
  1112         pdu.Append( KSmsMTISubmitOrSubmitReport ); // TP-MSG-Parameters
       
  1113 
       
  1114         if ( KErrNone == epocCause )
       
  1115             {
       
  1116             tpFailureCause = 0;
       
  1117             }
       
  1118         else if ( 0 == tpFailureCause )
       
  1119             {
       
  1120             tpFailureCause = 0xFF; // Unspecified error
       
  1121             }
       
  1122 
       
  1123         pdu.Append( tpFailureCause ); // TP Failure Cause
       
  1124         pdu.Append( 0x00 ); // TP Parameter Indicator
       
  1125 
       
  1126         TBuf8<KSmsScTimeStampMaxLength> timeStamp;
       
  1127         TUint8 tsBuffer[KSmsScTimeStampMaxLength] =
       
  1128             { 0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
       
  1129         timeStamp.Append( &tsBuffer[0], sizeof( tsBuffer ) );
       
  1130         pdu.Append( timeStamp ); // TP Service Centre Time Stamp
       
  1131 
       
  1132         // Create package and pack data
       
  1133         CMmDataPackage data;
       
  1134         data.PackData( &msgRef, &pdu );
       
  1135 
       
  1136         //complete the request
       
  1137         if ( EMobileSmsMessagingSendMessage == aIpc )
       
  1138             {
       
  1139             iMessageRouter->Complete(
       
  1140                 EMobileSmsMessagingSendMessage,
       
  1141                 &data,
       
  1142                 epocCause );
       
  1143             }
       
  1144         else
       
  1145             {
       
  1146             iMessageRouter->Complete(
       
  1147                 EMobileSmsMessagingSendMessageNoFdnCheck,
       
  1148                 &data,
       
  1149                 epocCause );
       
  1150             }
       
  1151 
       
  1152 #if (NCP_COMMON_S60_VERSION_SUPPORT>S60_VERSION_32)
       
  1153         iSMSSendingOngoing = EFalse;
       
  1154 #endif // NCP_COMMON_S60_VERSION_SUPPORT
       
  1155         }
       
  1156     // Response for send SAT SMS request
       
  1157     else if ( EMmTsySmsSendSatMessage == aIpc )
       
  1158         {
       
  1159         //complete the request
       
  1160         #if (NCP_COMMON_S60_VERSION_SUPPORT==S60_VERSION_32)
       
  1161         iMessageRouter->Complete( EMmTsySmsSendSatMessage, epocCause );
       
  1162         #else
       
  1163 #ifdef __WINSCW__
       
  1164             // for simatktsy testtool
       
  1165             // Temporarily removed for Bridge camp!
       
  1166       /*if ( iMessageRouter->iSatMessaging )
       
  1167                 {
       
  1168                 iMessageRouter->iSatMessaging->CompleteSendSmsMessage ( epocCause );
       
  1169                 }
       
  1170             // for nokiatsy testtool
       
  1171       */
       
  1172             iMessageRouter->Complete ( EMmTsySmsSendSatMessage, epocCause );
       
  1173 #else // __WINSCW__
       
  1174         // Temporarily removed for Bridge camp!
       
  1175     //iMessageRouter->iSatMessaging->CompleteSendSmsMessage ( epocCause );
       
  1176 #endif // __WINSCW__
       
  1177         iSMSSendingOngoing = EFalse;
       
  1178 #endif //NCP_COMMON_S60_VERSION_SUPPORT
       
  1179         }
       
  1180     else
       
  1181         {
       
  1182 TFLOGSTRING2("TSY:CMmSmsMessHandler::SmsMessageSendResp:Unexpected IPC %d.",aIpc);
       
  1183 OstTrace1( TRACE_NORMAL, DUP6_CMMSMSMESSHANDLER_SMSMESSAGESENDRESP, "CMmSmsMessHandler::SmsMessageSendResp;aIpc=%d", aIpc );
       
  1184         }
       
  1185     }
       
  1186 
       
  1187 // -----------------------------------------------------------------------------
       
  1188 // CMmSmsMessHandler::SmsReceiveMessageResp
       
  1189 // Breaks a SMS_RECEIVE_MESSAGE_RESP ISI-message and
       
  1190 // completes for SMS receiving request.
       
  1191 // -----------------------------------------------------------------------------
       
  1192 //
       
  1193 void CMmSmsMessHandler::SmsReceiveMessageResp( const TIsiReceiveC& aIsiMsg )
       
  1194     {
       
  1195 TFLOGSTRING("TSY: CMmSmsMessHandler::SmsReceiveMessageResp");
       
  1196 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSPPROUTINGRESP, "CMmSmsMessHandler::SmsReceiveMessageResp" );
       
  1197 
       
  1198     // Get transaction ID for completing with correct IPC
       
  1199     TUint8 trId( aIsiMsg.Get8bit(
       
  1200         ISI_HEADER_SIZE + SMS_RECEIVE_MESSAGE_RESP_OFFSET_TRANSID ) );
       
  1201     // Get reception status
       
  1202     TUint8 receptionStatus( aIsiMsg.Get8bit(
       
  1203         ISI_HEADER_SIZE + SMS_RECEIVE_MESSAGE_RESP_OFFSET_STATUS ) );
       
  1204 
       
  1205     // Get cause type and cause value. SMS_SB_CAUSE is mandatory subblock
       
  1206     TUint8 smsServerCauseType( aIsiMsg.Get8bit(
       
  1207         ISI_HEADER_SIZE + SIZE_SMS_RECEIVE_MESSAGE_RESP
       
  1208         + SMS_SB_CAUSE_OFFSET_CAUSETYPE ) );
       
  1209     TUint8 smsServerCauseValue( aIsiMsg.Get8bit(
       
  1210         ISI_HEADER_SIZE + SIZE_SMS_RECEIVE_MESSAGE_RESP
       
  1211         + SMS_SB_CAUSE_OFFSET_SMSCAUSE ) );
       
  1212 
       
  1213     TInt epocError( CMmStaticUtility::CSCauseToEpocError(
       
  1214         PN_SMS,
       
  1215         smsServerCauseType,
       
  1216         smsServerCauseValue ) );
       
  1217 
       
  1218     // Compete active reception status
       
  1219     if ( SMS_RECEPTION_ACTIVE == receptionStatus )
       
  1220         {
       
  1221         if ( 0 == trId ) // SMS receiving activated
       
  1222             {
       
  1223             CMmDataPackage package;
       
  1224             package.PackData( &receptionStatus );
       
  1225             iMessageRouter->Complete(
       
  1226                 EMmTsyActivateSmsRouting,
       
  1227                 &package,
       
  1228                 epocError );
       
  1229             }
       
  1230         else if ( ESmsMessagingResumeSmsReception == trId ) // Receive resumed
       
  1231             {
       
  1232             iMessageRouter->Complete(
       
  1233                 EMobileSmsMessagingResumeSmsReception,
       
  1234                 epocError );
       
  1235             }
       
  1236         // No else
       
  1237         }
       
  1238     else // SMS_RECEPTION_INACTIVE
       
  1239         {
       
  1240         CMmDataPackage package;
       
  1241         package.PackData( &receptionStatus );
       
  1242         iMessageRouter->Complete(
       
  1243             EMmTsyDeactivateSmsRouting,
       
  1244             &package,
       
  1245             epocError );
       
  1246         }
       
  1247     return;
       
  1248     }
       
  1249 
       
  1250 // -----------------------------------------------------------------------------
       
  1251 // CMmSmsMessHandler::IsSmsClass2
       
  1252 // Check if the class of the received sms is Class2 or not
       
  1253 // -----------------------------------------------------------------------------
       
  1254 //
       
  1255 TBool CMmSmsMessHandler::IsSmsClass2(
       
  1256     const TIsiReceiveC& aIsiMsg, //Isi Msg
       
  1257     TUint8& aSmsClass2ReplaceTpPid ) // TP-PID to replace (set by this function)
       
  1258     {
       
  1259 TFLOGSTRING("TSY: CMmSmsMessHandler::IsSmsClass2");
       
  1260 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_ISSMSCLASS2, "CMmSmsMessHandler::IsSmsClass2" );
       
  1261     TBool smsClass2( EFalse );
       
  1262     TBool cphsCase( EFalse );
       
  1263 
       
  1264     // If received Class 2 SMS is a "replace type" message, contains
       
  1265     // the TP-PID value, else value is zero.
       
  1266     // See 3GPP TS 23.040 "Technical realization of Short Message
       
  1267     // Service (SMS)", version V6.2.0 (2003-09), chapter 9.2.3.9
       
  1268     // "TP Protocol Identifier (TP PID)"
       
  1269     aSmsClass2ReplaceTpPid = 0;
       
  1270 
       
  1271     TUint tpduOffset( 0 );
       
  1272     if ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
       
  1273         ISI_HEADER_SIZE + SIZE_SMS_RECEIVED_MSG_IND,
       
  1274         SMS_SB_TPDU,
       
  1275         EIsiSubBlockTypeId16Len16,
       
  1276         tpduOffset ) )
       
  1277         {
       
  1278         TUint8 userDataLength( aIsiMsg.Get8bit(
       
  1279             tpduOffset + SMS_SB_TPDU_OFFSET_DATALENGTH ) );
       
  1280         TPtrC8 sms( aIsiMsg.GetData(
       
  1281             tpduOffset + SMS_SB_TPDU_OFFSET_DATABYTES,
       
  1282             userDataLength ) );
       
  1283 
       
  1284         if ( 0 < sms.Length() )
       
  1285             {
       
  1286             // Begin CPHS special case handling
       
  1287             // "CPHS Version 4.2, B.4.2.1 Voice Message Waiting Indicator":
       
  1288             // An MT Class 2 ((U)SIM-specific) SMS with
       
  1289             // - TP-Originating-Address coded as a Voice Message Waiting
       
  1290             //   Indicator message
       
  1291             // - User data a single space is not saved into EF_SMS.
       
  1292             const TUint8 KCphsAddressLength( 4 );     // 00000100
       
  1293             const TUint8 KCphsTypeOfAddress( 0xD0 );  // 11010000
       
  1294             const TUint8 KCphsSpaceCharacter( 0x20 ); // 01000000
       
  1295             // Skip message parameters (1 byte)
       
  1296             TUint8 oaLen( sms[1] );
       
  1297             if ( KCphsAddressLength == oaLen )
       
  1298                 {
       
  1299                 TUint8 typeOfAddress( sms[2] );
       
  1300                 TUint8 addressValueChar1( sms[3] );
       
  1301                 TUint8 addressValueChar2( sms[4] );
       
  1302                 if ( ( KCphsTypeOfAddress == typeOfAddress )
       
  1303                      && ( 0x10 == ( 0x7E & addressValueChar1 ) )  //x001000x
       
  1304                      && ( 0x00 == ( 0x7E & addressValueChar2 ) ) )//x000000x
       
  1305                     {
       
  1306                     // Skip PID(1 byte), skip DCS(1 byte), skip SCTS(7 bytes)
       
  1307                     TUint8 udl( sms[14] );
       
  1308                     if ( 1 == udl )
       
  1309                         {
       
  1310                         TUint8 ud( sms[15] );
       
  1311                         if ( KCphsSpaceCharacter == ud )
       
  1312                             {
       
  1313                             // This is a CPHS message indicator. No further
       
  1314                             // check of DCS and PID necessary.
       
  1315                             cphsCase = ETrue;
       
  1316                             smsClass2 = EFalse;
       
  1317 TFLOGSTRING("TSY: CMmSmsMessHandler::IsSmsClass2: CPHS message");
       
  1318 OstTrace0( TRACE_NORMAL, DUP4_CMMSMSMESSHANDLER_ISSMSCLASS2, "CMmSmsMessHandler::IsSmsClass2. CPHS message" );
       
  1319                             }
       
  1320                         }
       
  1321                     }
       
  1322                 }
       
  1323             // End CPHS special case handling
       
  1324 
       
  1325             // No CPHS case, continue checking
       
  1326             if ( ! cphsCase )
       
  1327                 {
       
  1328                 // Check type of received SMS message
       
  1329                 TUint8 messageParams( sms[0] );
       
  1330                 messageParams &= 0x03;
       
  1331                 if ( KSmsMTIDeliverOrDeliverReport == messageParams )
       
  1332                     {
       
  1333                     TUint8 protocolId( 0 );
       
  1334                     // To retrieve the TP-DCS, we have to find the right index
       
  1335                     // See 3GPP TS 23.040 "Technical realization of Short
       
  1336                     // Message Service (SMS)", version V6.2.0 (2003-09),
       
  1337                     // chapter 9.2.2.1 "SMS Deliver Type"
       
  1338 
       
  1339                     TUint8 index( 1 ); // Skip the first byte (message params)
       
  1340                     TUint8 addressLength( sms[index] );
       
  1341                     // Address is coded in semi-octets in TPDU->divide by two.
       
  1342                     // Add two mandatory bytes of TP-OA
       
  1343                     addressLength = ( addressLength + 1 ) / 2 + 2;
       
  1344                     index += addressLength;
       
  1345                     protocolId = sms[index++];
       
  1346 
       
  1347                     // Check if this class 2 SMS is a "replace type" message
       
  1348                     // See 3GPP TS 23.040 "Technical realization of Short
       
  1349                     // Message Service (SMS)", version V6.2.0 (2003-09),
       
  1350                     // chapter 9.2.3.9 "TP Protocol Identifier (TP PID)"
       
  1351                     if ( ( 0x41 <= protocolId ) && ( 0x47 >= protocolId ) )
       
  1352                         {
       
  1353                         // Yes, this is a "replace type" message
       
  1354 TFLOGSTRING2("TSY: CMmSmsMessHandler::IsSmsClass2: Replace type message, protocol ID: %d", protocolId );
       
  1355 OstTraceExt1( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_ISSMSCLASS2, "CMmSmsMessHandler::IsSmsClass2. Replace type message;protocolId=%hhu", protocolId );
       
  1356                         aSmsClass2ReplaceTpPid = protocolId;
       
  1357                         }
       
  1358 
       
  1359                     // TP-DCS tells us the class of the SMS
       
  1360                     TUint8 dataCodingScheme( sms[index++] );
       
  1361                     // Copy TP-DCS to get the stronger bits later
       
  1362                     TUint8 strongerBitsDCS( dataCodingScheme );
       
  1363 
       
  1364                     // Received message is of Class2 if dataCodingScheme
       
  1365                     // contains either bits 00x1xx10 or 1111xx10.
       
  1366                     // Gets the lower bits.
       
  1367                     // See 3GPP TS 23.038 "Technical Specification Group
       
  1368                     // Terminals; Alphabets and language-specific information"
       
  1369                     // version V6.0.0 (2003-09), chapter 4 "SMS Data Coding
       
  1370                     // Scheme"
       
  1371                     dataCodingScheme &= 0x03;
       
  1372 
       
  1373                     // Gets the stronger bits
       
  1374                     strongerBitsDCS >>= 4;
       
  1375                     if (  ( 2 == dataCodingScheme ) &&
       
  1376                         ( ( 1 == strongerBitsDCS ) ||
       
  1377                         ( 3 == strongerBitsDCS ) ||
       
  1378                         ( 15 == strongerBitsDCS ) ) )
       
  1379                         {
       
  1380                         // SMS is from Class2
       
  1381                         smsClass2 = ETrue;
       
  1382                         }
       
  1383                     } // End of if KSmsMTIDeliverOrDeliverReport==messageParams
       
  1384                 } // End of if ( ! cphsCase )
       
  1385             } // End of if ( 0 < sms.Length() )
       
  1386         } // End of if SMS_SB_USER_DATA found
       
  1387 
       
  1388     // We are only interested in TP-PID "replace", if message is Class 2
       
  1389     // (TP-PID "replace" for class 1 messages is handled by upper layers)
       
  1390     if ( 0 != aSmsClass2ReplaceTpPid )
       
  1391         {
       
  1392         if ( smsClass2 )
       
  1393             {
       
  1394 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsClass: Received class 2 message has TP-PID 0x%x", aSmsClass2ReplaceTpPid);
       
  1395 OstTraceExt1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_ISSMSCLASS2, "CMmSmsMessHandler::IsSmsClass2;aSmsClass2ReplaceTpPid=%hhx", aSmsClass2ReplaceTpPid );
       
  1396             }
       
  1397         else
       
  1398             {
       
  1399             aSmsClass2ReplaceTpPid = 0;
       
  1400             }
       
  1401         }
       
  1402     return smsClass2;
       
  1403     }
       
  1404 
       
  1405 // -----------------------------------------------------------------------------
       
  1406 // CMmSmsMessHandler::SmsReceivedMsgInd
       
  1407 // Breaks SMS_RECEIVED_MSG_IND ISI-message that contains incoming
       
  1408 // SMS message. SMS message is not acknowledged to the network
       
  1409 // -----------------------------------------------------------------------------
       
  1410 //
       
  1411 void CMmSmsMessHandler::SmsReceivedMsgInd( const TIsiReceiveC& aIsiMsg )
       
  1412     {
       
  1413 TFLOGSTRING("TSY: CMmSmsMessHandler::SmsReceivedMsgInd");
       
  1414 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSPPROUTINGNTF, "CMmSmsMessHandler::SmsReceivedMsgInd" );
       
  1415     TInt ret( KErrNone );
       
  1416     // Create a package
       
  1417     CMmDataPackage package;
       
  1418 
       
  1419     TUint8 replaceTpPid( 0 ); // IsSmsClass2 also fills this
       
  1420     TBool receivedSmsClass2( IsSmsClass2( aIsiMsg, replaceTpPid ) );
       
  1421 
       
  1422     // SIM SMS cache: incoming class 2 SMS
       
  1423     if ( receivedSmsClass2 )
       
  1424         {
       
  1425         ret = SmsClass2ReceivedMsgInd( aIsiMsg, replaceTpPid );
       
  1426         }
       
  1427     // Received SMS is not a class 2 SMS (it is a normal SMS)
       
  1428     else
       
  1429         {
       
  1430         ret = SmsClass1ReceivedMsgInd( aIsiMsg );
       
  1431         }
       
  1432     // There was an error, complete to upper level
       
  1433     if ( KErrNone != ret )
       
  1434         {
       
  1435 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsReceivedMsgInd;ret=%d", ret);
       
  1436 OstTrace1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_SMSPPROUTINGNTF, "CMmSmsMessHandler::SmsReceivedMsgInd;ret=%d", ret );
       
  1437         TBool smsInd( ETrue );
       
  1438         TSmsMsg* nullSms = NULL;
       
  1439 
       
  1440         package.PackData( &smsInd, &nullSms );
       
  1441 
       
  1442         // Complete request to client
       
  1443         iMessageRouter->Complete(
       
  1444             EMobileSmsMessagingReceiveMessage,
       
  1445             &package,
       
  1446             ret );
       
  1447         }
       
  1448     }
       
  1449 
       
  1450 // -----------------------------------------------------------------------------
       
  1451 // CMmSmsMessHandler::SmsReceivedMsgReportResp
       
  1452 // Breaks a ISI-message, gets GSM specific sub blocks and
       
  1453 // response for Sms gsm received pp report request
       
  1454 // -----------------------------------------------------------------------------
       
  1455 //
       
  1456 void CMmSmsMessHandler::SmsReceivedMsgReportResp( const TIsiReceiveC& aIsiMsg )
       
  1457     {
       
  1458     TUint8 traId( aIsiMsg.Get8bit( ISI_HEADER_SIZE
       
  1459         + SMS_RECEIVED_MSG_REPORT_RESP_OFFSET_TRANSID ) );
       
  1460     TUint8 cause( aIsiMsg.Get8bit( ISI_HEADER_SIZE
       
  1461         + SMS_RECEIVED_MSG_REPORT_RESP_OFFSET_SMSCAUSE ) );
       
  1462 
       
  1463 TFLOGSTRING3("TSY: CMmSmsMessHandler::SmsReceivedPpReportResp - traId: %d, cause: %d", traId, cause);
       
  1464 OstTraceExt2( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSRECEIVEDPPREPORTRESP, "CMmSmsMessHandler::SmsReceivedPpReportResp;traId=%hhu;cause=%hhu", traId, cause );
       
  1465 
       
  1466     // Response for SmsReceivedPpReportReq (Ack)
       
  1467     if ( ESmsMessagingAckSmsStored == traId )
       
  1468         {
       
  1469         iMessageRouter->Complete(
       
  1470             EMobileSmsMessagingAckSmsStored,
       
  1471             CMmStaticUtility::CSCauseToEpocError(
       
  1472                 PN_SMS,
       
  1473                 SMS_CAUSE_TYPE_COMMON,
       
  1474                 cause ) );
       
  1475         }
       
  1476     // Response for SmsReceivedPpReportReq (Nack)
       
  1477     else if ( ESmsMessagingNackSmsStored == traId )
       
  1478         {
       
  1479         iMessageRouter->Complete(
       
  1480             EMobileSmsMessagingNackSmsStored,
       
  1481             CMmStaticUtility::CSCauseToEpocError(
       
  1482                 PN_SMS,
       
  1483                 SMS_CAUSE_TYPE_COMMON,
       
  1484                 cause ) );
       
  1485         }
       
  1486     else
       
  1487         {
       
  1488 TFLOGSTRING2("TSY:CMmSmsMessHandler::SmsReceivedPpReportResp:Unexpected transaction ID %d.",traId);
       
  1489 OstTraceExt1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_SMSRECEIVEDPPREPORTRESP, "CMmSmsMessHandler::SmsReceivedPpReportResp;Unexpected  transaction ID=%hhu", traId );
       
  1490         }
       
  1491 
       
  1492     if ( KErrNone != cause )
       
  1493         {
       
  1494         //Acknowledging failed.
       
  1495         //Complete possible receive message request with KErrGeneral and
       
  1496         //set routing activity to false. SMS Stack makes new ReceiveMessage
       
  1497         //request.
       
  1498         TBool smsInd( EFalse );
       
  1499         TSmsMsg* nullSms = NULL;
       
  1500 
       
  1501         //Complete request to client
       
  1502         CMmDataPackage package;
       
  1503         package.PackData( &smsInd, &nullSms );
       
  1504         iSmsSlotLocation = 0;
       
  1505 
       
  1506         // ISI message construction failed or phonet sender
       
  1507         // returned error
       
  1508         iMessageRouter->Complete(
       
  1509             EMobileSmsMessagingReceiveMessage,
       
  1510             &package,
       
  1511             KErrGeneral );
       
  1512         }
       
  1513     }
       
  1514 
       
  1515 // -----------------------------------------------------------------------------
       
  1516 // CMmSmsMessHandler::BuildScAddress
       
  1517 // Build Service Centre Address
       
  1518 // -----------------------------------------------------------------------------
       
  1519 //
       
  1520 void CMmSmsMessHandler::BuildScAddress(
       
  1521     RMobilePhone::TMobileAddress const & scPtr, //Pointer to Service center
       
  1522     TDes8 &aScAddress ) const                  //Service center address
       
  1523     {
       
  1524 TFLOGSTRING("TSY: CMmSmsMessHandler::BuildScAddress");
       
  1525 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_BUILDSCADDRESS, "CMmSmsMessHandler::BuildScAddress" );
       
  1526     //get type of number from attributes
       
  1527     RMobilePhone::TMobileTON ton( scPtr.iTypeOfNumber );
       
  1528     //map type of number from TMobileTON to TUint8
       
  1529     TUint8 typeOfNumber( CMmSmsGsmAddress::GsmMapTonToTUint8( ton ) );
       
  1530     //get numbering plan identification from attributes
       
  1531     RMobilePhone::TMobileNPI npi( scPtr.iNumberPlan );
       
  1532     //map numbering plan identification from TMobileTON to TUint8
       
  1533     TUint8 numberPlan( CMmSmsGsmAddress::GsmMapNpiToTUint8( npi ) );
       
  1534     //return service center address
       
  1535     TPtrC16 telNumber( scPtr.iTelNumber );
       
  1536 
       
  1537     //build Gsm 04.11 type of address structure
       
  1538     CMmSmsGsmAddress::GsmConvUnicodeTo0411Addr(
       
  1539         typeOfNumber,
       
  1540         numberPlan,
       
  1541         aScAddress,
       
  1542         telNumber );
       
  1543     }
       
  1544 
       
  1545 // -----------------------------------------------------------------------------
       
  1546 // CMmSmsMessHandler::BuildDeAddress
       
  1547 // Build Destination Address
       
  1548 // -----------------------------------------------------------------------------
       
  1549 //
       
  1550 void CMmSmsMessHandler::BuildDeAddress(
       
  1551     RMobilePhone::TMobileAddress const & scPtr,  // Service centre pointer
       
  1552     TDes8 &aDeAddress ) const                    // Destination address
       
  1553     {
       
  1554 TFLOGSTRING("TSY: CMmSmsMessHandler::BuildDeAddress");
       
  1555 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_BUILDDEADDRESS, "CMmSmsMessHandler::BuildDeAddress" );
       
  1556     //get type of number from attributes
       
  1557     RMobilePhone::TMobileTON ton( scPtr.iTypeOfNumber );
       
  1558 
       
  1559     //map type of number from TMobileTON to TUint8
       
  1560     TUint8 typeOfNumber( CMmSmsGsmAddress::GsmMapTonToTUint8( ton ) );
       
  1561 
       
  1562     //get numbering plan identification from attributes
       
  1563     RMobilePhone::TMobileNPI npi( scPtr.iNumberPlan );
       
  1564 
       
  1565     //map numbering plan identification from TMobileTON to TUint8
       
  1566     TUint8 numberPlan( CMmSmsGsmAddress::GsmMapNpiToTUint8( npi ) );
       
  1567 
       
  1568     //return service center address
       
  1569     TPtrC16 telNumber( scPtr.iTelNumber );
       
  1570 
       
  1571     //build Gsm 03.40 type of address structure
       
  1572     CMmSmsGsmAddress::GsmConvUnicodeTo0340Addr(
       
  1573         typeOfNumber,
       
  1574         numberPlan,
       
  1575         aDeAddress,
       
  1576         telNumber );
       
  1577     }
       
  1578 
       
  1579 // -----------------------------------------------------------------------------
       
  1580 // CMmSmsMessHandler::DataCodingScheme
       
  1581 // Check if message data is coded using 7bit alphabet
       
  1582 // (other items were commented in header)
       
  1583 // -----------------------------------------------------------------------------
       
  1584 //
       
  1585 TBool CMmSmsMessHandler::IsDataCodingScheme7Bit( TUint8 aDcs ) const
       
  1586     {
       
  1587 TFLOGSTRING("TSY: CMmSmsMessHandler::IsDataCodingScheme7Bit");
       
  1588 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_ISDATACODINGSCHEME7BIT, "CMmSmsMessHandler::IsDataCodingScheme7Bit" );
       
  1589     TUint8 codingGroup( static_cast<TUint8>( 0xf0 & aDcs ) );  // 11110000
       
  1590     TUint8 lowerBits( static_cast<TUint8>( 0x0f & aDcs ) );    // 00001111
       
  1591 
       
  1592     // See 3GPP TS 23.038 "Technical Specification Group Terminals;
       
  1593     //Alphabets and language-specific information"
       
  1594     // version V6.0.0 (2003-09), chapter 4 "SMS Data Coding Scheme"
       
  1595     // 00XX General data coding indication
       
  1596     // 01XX Message Marked for Automation Deletion Group
       
  1597     if ( codingGroup >> 6 == 0x00 || codingGroup >> 6 == 0x01 )
       
  1598         {
       
  1599         // 00XX Default alphabet, 11XX Reserved
       
  1600         if ( ( lowerBits >> 2 == 0x00 ) || ( lowerBits >> 2 == 0x03 ) )
       
  1601             {
       
  1602             return ETrue;
       
  1603             }
       
  1604         else
       
  1605             {
       
  1606             return EFalse;
       
  1607             }
       
  1608         }
       
  1609     // 1100 Message Waiting Indication Group: Discard Message
       
  1610     // 1101 Message Waiting Indication Group: Store Message
       
  1611     else if ( codingGroup >> 4 == 0x0C || codingGroup >> 4 == 0x0D )
       
  1612         {
       
  1613         return ETrue;
       
  1614         }
       
  1615     // 1110 Message Waiting Indication Group: Store Message (UCS2)
       
  1616     else if ( codingGroup >> 4 == 0x0E )
       
  1617         {
       
  1618         return EFalse;
       
  1619         }
       
  1620     // 1111 Data coding/message class
       
  1621     else if ( codingGroup >> 4 == 0x0F )
       
  1622         {
       
  1623         lowerBits&= 0x04;
       
  1624         // X0XX Default alphabet
       
  1625         if ( lowerBits == 0 )
       
  1626             {
       
  1627             return ETrue;
       
  1628             }
       
  1629         else
       
  1630             {
       
  1631             return EFalse;
       
  1632             }
       
  1633         }
       
  1634     // 1000..1011 Reserved coding groups
       
  1635     else
       
  1636         {
       
  1637         // Any reserved codings shall be assumed to be the GSM default alphabet
       
  1638         return ETrue;
       
  1639         }
       
  1640     }
       
  1641 
       
  1642 // -----------------------------------------------------------------------------
       
  1643 // CMmSmsMessHandler::CalculateNumberOfCharsInUserData
       
  1644 // Calculate number of characters in 7-bit user data
       
  1645 // -----------------------------------------------------------------------------
       
  1646 //
       
  1647 TUint8 CMmSmsMessHandler::CalculateNumberOfCharsInUserData(
       
  1648     TUint8 aCharacterAmount,           //Character amount (from ISI message)
       
  1649     TUint8 aDataLength,                //Data length in bytes (from ISI message)
       
  1650     TPtrC8 const & aUserData ) const   //User data
       
  1651     {
       
  1652 TFLOGSTRING3("TSY: CMmSmsMessHandler::CalculateNumberOfCharsInUserData - char amount (from ISI): %d, data length (from ISI): %d", aCharacterAmount, aDataLength);
       
  1653 OstTraceExt2( TRACE_NORMAL, CMMSMSMESSHANDLER_CALCULATENUMBEROFCHARSINUSERDATA, "CMmSmsMessHandler::CalculateNumberOfCharsInUserData;aCharacterAmount=%hhu;aDataLength=%hhu", aCharacterAmount, aDataLength );
       
  1654 
       
  1655     TUint16 characterAmount;
       
  1656 
       
  1657     // This calculation is only needed if the number of characters is
       
  1658     // not provided in the aCharacterAmount parameter. Seems to be some
       
  1659     // old backwards-compatibility issue or so ...
       
  1660     if ( ( 0 != aCharacterAmount ) && ( 0xff != aCharacterAmount ) )
       
  1661         {
       
  1662         characterAmount = aCharacterAmount;
       
  1663         }
       
  1664     else
       
  1665         {
       
  1666         //we have to calculate number of characters in user data, when
       
  1667         //7-bit chars are used.
       
  1668         characterAmount = static_cast<TUint16>(  ( aDataLength * 8 ) / 7 );
       
  1669         if ( ( 0 == ( ( aDataLength * 8 ) % 7 ) ) && characterAmount )
       
  1670             {
       
  1671             if ( 0 == ( aUserData[aDataLength-1] & 0xFE ) )
       
  1672                 {
       
  1673                 //LSB in user data's last byte is zero -> number of characters
       
  1674                 //is characterAmount-1
       
  1675                 characterAmount--;
       
  1676                 }
       
  1677             }
       
  1678         }
       
  1679     return static_cast<TUint8>( characterAmount );
       
  1680     }
       
  1681 
       
  1682 // -----------------------------------------------------------------------------
       
  1683 // CMmSmsMessHandler::ExtFuncL
       
  1684 // Dispatches Etel requests to DOS level handlers
       
  1685 // -----------------------------------------------------------------------------
       
  1686 //
       
  1687 TInt CMmSmsMessHandler::ExtFuncL(
       
  1688     TInt aIpc,                           // IPC number
       
  1689     const CMmDataPackage* aDataPackage ) // Data package
       
  1690     {
       
  1691 TFLOGSTRING2("TSY: CMmSmsMessHandler::ExtFuncL: IPC: %d", aIpc);
       
  1692 OstTrace1( TRACE_NORMAL, CMMSMSMESSHANDLER_EXTFUNCL, "CMmSmsMessHandler::ExtFuncL;aIpc=%d", aIpc );
       
  1693 
       
  1694     TInt ret( KErrNone );
       
  1695 
       
  1696     switch ( aIpc )
       
  1697         {
       
  1698         case EMobileSmsMessagingGetMessageStoreInfo:
       
  1699         case EMobilePhoneStoreGetInfo:
       
  1700             {
       
  1701             ret = GetSmsStoreInfo( aIpc );
       
  1702             break;
       
  1703             }
       
  1704         case EMmTsyActivateSmsRouting:
       
  1705             {
       
  1706 #if defined( INTERNAL_TESTING_SMS_WITH_EMULATOR )  && ( ! defined( __WINS__ ) )
       
  1707 TFLOGSTRING("TSY: CMmSmsMessHandler::ExtFuncL: SMS routing deactivated with flag INTERNAL_TESTING_SMS_WITH_EMULATOR");
       
  1708 OstTrace0( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_EXTFUNCL, "CMmSmsMessHandler::ExtFuncL, SMS routing deactivated with flag INTERNAL_TESTING_SMS_WITH_EMULATOR" );
       
  1709 #else
       
  1710             ret = SmsReceiveMessageReq( SMS_RECEPTION_ACTIVATE );
       
  1711 #endif // defined( INTERNAL_TESTING_SMS_WITH_EMULATOR ) && ( ! defined( __WINS__ ) )
       
  1712             break;
       
  1713             }
       
  1714         case EMmTsyDeactivateSmsRouting:
       
  1715             {
       
  1716             //Release the SMS_PP_ROUTING
       
  1717             ret = SmsReceiveMessageReq( SMS_RECEPTION_DEACTIVATE );
       
  1718             break;
       
  1719             }
       
  1720         case EMobileSmsMessagingSendMessage:
       
  1721             {
       
  1722             ret = SmsMessageSendReq(
       
  1723                 ESmsMessagingSendMessage,
       
  1724                 aDataPackage,
       
  1725                 EFalse );
       
  1726             break;
       
  1727             }
       
  1728         case EMobileSmsMessagingSendMessageNoFdnCheck:
       
  1729             {
       
  1730             ret = SmsMessageSendReq(
       
  1731                 ESmsMessagingSendNoFdnMessage,
       
  1732                 aDataPackage,
       
  1733                 ETrue );
       
  1734             break;
       
  1735             }
       
  1736         case EMmTsySmsSendSatMessage:
       
  1737             {
       
  1738             ret = SmsMessageSendReq(
       
  1739                 ESmsMessagingSendSatMessage,
       
  1740                 aDataPackage,
       
  1741                 ETrue );
       
  1742             break;
       
  1743             }
       
  1744         case EMobileSmsMessagingResumeSmsReception:
       
  1745             {
       
  1746             ret = SmsReceiveMessageReq( SMS_RECEPTION_STORAGE_STATUS_UPDATE );
       
  1747             break;
       
  1748             }
       
  1749         case EMobileSmsMessagingGetSmspListPhase1:
       
  1750             {
       
  1751             // Lets delete TSY's internal temporary SMSP storage
       
  1752             iSmspListArray->ResetAndDestroy();
       
  1753             break;
       
  1754             }
       
  1755         case EMobileSmsMessagingStoreSmspList:
       
  1756             {
       
  1757             break;
       
  1758             }
       
  1759         case EMobileSmsMessagingAckSmsStored:
       
  1760             {
       
  1761             TDesC8* data;
       
  1762             //unpack data
       
  1763             aDataPackage->UnPackData( data );
       
  1764 
       
  1765             TBuf8<RMobileSmsMessaging::KGsmTpduSize>* msgData =
       
  1766                 reinterpret_cast<TBuf8<RMobileSmsMessaging::KGsmTpduSize> *> ( data );
       
  1767 
       
  1768             if ( NULL == msgData )
       
  1769                 {
       
  1770 TFLOGSTRING("TSY: CMmSmsMessHandler::ExtFuncL.Internal Ack handling started" );
       
  1771 OstTrace0( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_EXTFUNCL, "CMmSmsMessHandler::ExtFuncL, Internal Ack handling started" );
       
  1772                 }
       
  1773             ret = SmsReceivedMsgReportReq(
       
  1774                 ESmsMessagingAckSmsStored,
       
  1775                 msgData,
       
  1776                 KErrNone );
       
  1777             break;
       
  1778             }
       
  1779         case EMobileSmsMessagingNackSmsStored:
       
  1780             {
       
  1781             TInt rpCause( 0 );
       
  1782             TBuf8<RMobileSmsMessaging::KGsmTpduSize>* msgData;
       
  1783 
       
  1784             //unpack data
       
  1785             aDataPackage->UnPackData( msgData, rpCause );
       
  1786 
       
  1787             if ( NULL == msgData )
       
  1788                 {
       
  1789 TFLOGSTRING("TSY: CMmSmsMessHandler::ExtFuncL.Internal Nack handling started" );
       
  1790 OstTrace0( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_EXTFUNCL, "CMmSmsMessHandler::ExtFuncL, Internal Nack handling started" );
       
  1791                 }
       
  1792 
       
  1793             ret = SmsReceivedMsgReportReq(
       
  1794                 ESmsMessagingNackSmsStored,
       
  1795                 msgData,
       
  1796                 rpCause );
       
  1797             break;
       
  1798             }
       
  1799         case EMobilePhoneStoreDelete:
       
  1800             {
       
  1801             ret = DeleteSms( aDataPackage );
       
  1802             break;
       
  1803             }
       
  1804         case EMobilePhoneStoreDeleteAll:
       
  1805             {
       
  1806             ret = DeleteAllSms();
       
  1807             break;
       
  1808             }
       
  1809         case EMobilePhoneStoreRead:
       
  1810             {
       
  1811             ret = ReadSms( aDataPackage );
       
  1812             break;
       
  1813             }
       
  1814         case EMobilePhoneStoreReadAllPhase1:
       
  1815             {
       
  1816             ret = ReadAllSmsL();
       
  1817             break;
       
  1818             }
       
  1819         case EMobilePhoneStoreWrite:
       
  1820             {
       
  1821             TInt index( 0 );
       
  1822             TDesC8* data;
       
  1823 
       
  1824             // unpacked index is not used since the index to write to
       
  1825             // can also be taken from smsData
       
  1826             aDataPackage->UnPackData( data, index );
       
  1827 
       
  1828             //typecast for aEntry
       
  1829             RMobileSmsStore::TMobileGsmSmsEntryV1Pckg* entryPckg =
       
  1830                 reinterpret_cast<RMobileSmsStore::TMobileGsmSmsEntryV1Pckg*>(
       
  1831                 const_cast<TDesC8*>( data ) );
       
  1832             RMobileSmsStore::TMobileGsmSmsEntryV1& entry = ( *entryPckg )();
       
  1833             iSMSClass2Write = EFalse;
       
  1834             ret = WriteSms( entry, index );
       
  1835            break;
       
  1836             }
       
  1837         case ECustomSetSimMessageStatusReadIPC:
       
  1838             {
       
  1839 TFLOGSTRING("TSY: CMmSmsMessHandler::ExtFuncL - ECustomSetSimMessageStatusReadIPC starts.");
       
  1840 OstTrace0( TRACE_NORMAL, DUP4_CMMSMSMESSHANDLER_EXTFUNCL, "CMmSmsMessHandler::ExtFuncL, ECustomSetSimMessageStatusReadIPC starts" );
       
  1841             TTime scTime;
       
  1842             TInt timezoneDiff;
       
  1843             aDataPackage->UnPackData( scTime, timezoneDiff );
       
  1844 
       
  1845             // start searching for a SIM message with this timestamp
       
  1846             TUint8 totalSlots( static_cast<TUint8>(
       
  1847                 iSmsCache.TotalEntries() ) );
       
  1848             TUint8 currentSlot( 1 );
       
  1849             while ( currentSlot <= totalSlots )
       
  1850                 {
       
  1851                 RMobileSmsStore::TMobileGsmSmsEntryV1* smsFromCache =
       
  1852                     iSmsCache.GetEntry( currentSlot );
       
  1853 
       
  1854                 if ( smsFromCache )
       
  1855                     {
       
  1856                     delete smsFromCache;
       
  1857                     }
       
  1858                 currentSlot++;
       
  1859                 }
       
  1860 TFLOGSTRING("TSY: CMmSmsMessHandler::ExtFuncL - ECustomSetSimMessageStatusReadIPC done.");
       
  1861 OstTrace0( TRACE_NORMAL, DUP5_CMMSMSMESSHANDLER_EXTFUNCL, "CMmSmsMessHandler::ExtFuncL, ECustomSetSimMessageStatusReadIPC done" );
       
  1862             ret = KErrNone;
       
  1863             break;
       
  1864             }
       
  1865         case EMobileSmsMessagingSetMoSmsBearer:
       
  1866             {
       
  1867             RMobileSmsMessaging::TMobileSmsBearer bearer;
       
  1868             aDataPackage->UnPackData( bearer );
       
  1869             ret = SmsSettingsUpdateReq( bearer );
       
  1870             break;
       
  1871             }
       
  1872         default:
       
  1873             {
       
  1874 TFLOGSTRING2("TSY: CMmSmsMessHandler::ExtFuncL - Unknown IPC: %d", aIpc);
       
  1875 OstTrace1( TRACE_NORMAL, DUP6_CMMSMSMESSHANDLER_EXTFUNCL, "CMmSmsMessHandler::ExtFuncL;Unknown aIpc=%d", aIpc );
       
  1876             ret = KErrArgument;
       
  1877             break;
       
  1878             }
       
  1879         }
       
  1880     return ret;
       
  1881     }
       
  1882 
       
  1883 // -----------------------------------------------------------------------------
       
  1884 // CMmSmsMessHandler::InternalRetrieveSmspListL
       
  1885 // Complete SmsParametersReadREQuest and call GetSmspList
       
  1886 // or CompleteReadSmsp method
       
  1887 // (other items were commented in header)
       
  1888 // -----------------------------------------------------------------------------
       
  1889 //
       
  1890 void CMmSmsMessHandler::InternalRetrieveSmspListL( TSmsParameters* aParameters )
       
  1891     {
       
  1892 TFLOGSTRING("TSY: CMmSmsMessHandler::InternalRetrieveSmspListL");
       
  1893 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_INTERNALRETRIEVESMSPLISTL, "CMmSmsMessHandler::InternalRetrieveSmspListL" );
       
  1894     // Add parameter sets information to the TSY's internal storage
       
  1895     iSmspListArray->AppendL( aParameters );
       
  1896 
       
  1897     // Lets read next SMSP set
       
  1898     if ( iLocationOfSmspSet <= iAmountOfSmspSets )
       
  1899         {
       
  1900         iLocationOfSmspSet++;
       
  1901         }
       
  1902     else    // All SMSP sets read
       
  1903         {
       
  1904         //Pack data
       
  1905         CMmDataPackage package;
       
  1906         package.PackData( iSmspListArray );
       
  1907 
       
  1908         //complete the request,
       
  1909         iMessageRouter->Complete(
       
  1910             EMobileSmsMessagingGetSmspListPhase1,
       
  1911             &package,
       
  1912             KErrNone );
       
  1913 
       
  1914         //Delete array
       
  1915         iSmspListArray->ResetAndDestroy();
       
  1916         }
       
  1917     }
       
  1918 
       
  1919 // -----------------------------------------------------------------------------
       
  1920 // CMmSmsMessHandler::CheckTpPidAndSenderAndServiceCenter
       
  1921 // Compares TP-PID, sender number and SC number of the received class 2
       
  1922 // SMS in aReceivedSmsIsiMsg, and the SMS read from SIM in aReadSmsIsiMsg.
       
  1923 // -----------------------------------------------------------------------------
       
  1924 //
       
  1925 TBool CMmSmsMessHandler::CheckTpPidAndSenderAndServiceCenter(
       
  1926     TUint8 aReceivedTpPid,                             //received TP-PID
       
  1927     const TIsiReceiveC&  aReceivedSmsIsiMsg,           //received isi msg
       
  1928     RMobileSmsStore::TMobileGsmSmsEntryV1* aSMSOnSIM ) //SMS stored on SIM
       
  1929     {
       
  1930 TFLOGSTRING2("TSY: CMmSmsMessHandler::CheckTpPidAndSenderAndServiceCenter, aReceivedTpPid = %d", aReceivedTpPid);
       
  1931 OstTraceExt1( TRACE_NORMAL, CMMSMSMESSHANDLER_CHECKTPPIDANDSENDERANDSERVICECENTER, "CMmSmsMessHandler::CheckTpPidAndSenderAndServiceCenter;aReceivedTpPid=%hhu", aReceivedTpPid );
       
  1932 
       
  1933     TBool matchFound( EFalse );
       
  1934 
       
  1935     // Get protocol id from stored SMS
       
  1936 
       
  1937     TInt offset( 1 ); // Set offset to message reference in TPDU
       
  1938     TUint8 messageReference( aSMSOnSIM->iMsgData[offset] );
       
  1939 
       
  1940     // Destination address length is integer representation
       
  1941     // of the number of useful semi-octets of address field
       
  1942     messageReference = ( messageReference + 1 ) / 2;
       
  1943     offset += messageReference;
       
  1944     offset += 2; // Set offset to Protocol Id
       
  1945     TUint8 protocolId( aSMSOnSIM->iMsgData[offset] );
       
  1946     if ( protocolId == aReceivedTpPid )
       
  1947         {
       
  1948         // this message has the same TP-PID. Now check if it also has
       
  1949         // same sender number and service center number
       
  1950         TBuf<KMaxAddressBufferSize> receivedMsgServiceCentre;
       
  1951         RMobilePhone::TMobileTON receivedMsgMobileScTON(
       
  1952             RMobilePhone::EUnknownNumber );
       
  1953         RMobilePhone::TMobileNPI receivedMsgMobileScNPI(
       
  1954             RMobilePhone::EUnknownNumberingPlan );
       
  1955 
       
  1956         TBuf<KMaxAddressBufferSize> receivedMsgOriginatorAdress;
       
  1957         RMobilePhone::TMobileTON receivedMsgMobileOaTON(
       
  1958             RMobilePhone::EUnknownNumber );
       
  1959         RMobilePhone::TMobileNPI receivedMsgMobileOaNPI(
       
  1960             RMobilePhone::EUnknownNumberingPlan );
       
  1961 
       
  1962         TBuf<KMaxAddressBufferSize> readMsgOriginatorAdress;
       
  1963         RMobilePhone::TMobileTON readMsgMobileOaTON(
       
  1964             RMobilePhone::EUnknownNumber );
       
  1965         RMobilePhone::TMobileNPI readMsgMobileOaNPI(
       
  1966             RMobilePhone::EUnknownNumberingPlan );
       
  1967 
       
  1968         // 1. Get service center address from received message
       
  1969         TUint smsAddressOffset( 0 );
       
  1970         if ( KErrNone == aReceivedSmsIsiMsg.FindSubBlockOffsetById(
       
  1971             ISI_HEADER_SIZE + SIZE_SMS_RECEIVED_MSG_IND,
       
  1972             SMS_SB_ADDRESS,
       
  1973             EIsiSubBlockTypeId16Len16,
       
  1974             smsAddressOffset ) )
       
  1975             {
       
  1976             if ( SMS_SMSC_ADDRESS == aReceivedSmsIsiMsg.Get8bit(
       
  1977                 smsAddressOffset + SMS_SB_ADDRESS_OFFSET_ADDRESSTYPE ) )
       
  1978                 {
       
  1979                 // Convert service centre address (SC Address 04.11)
       
  1980                 TUint8 addressDataLength( aReceivedSmsIsiMsg.Get8bit(
       
  1981                     smsAddressOffset +
       
  1982                     SMS_SB_ADDRESS_OFFSET_ADDRESSDATALENGTH ) );
       
  1983                 TPtrC8 scA( aReceivedSmsIsiMsg.GetData(
       
  1984                     smsAddressOffset + SMS_SB_ADDRESS_OFFSET_ADDRESSDATA,
       
  1985                     addressDataLength ) );
       
  1986                 CMmSmsGsmAddress::GsmConv0411AddrToUnicode(
       
  1987                     receivedMsgServiceCentre,
       
  1988                     scA,
       
  1989                     receivedMsgMobileScTON,
       
  1990                     receivedMsgMobileScNPI );
       
  1991                 }
       
  1992             }
       
  1993         else // could not extract data from received message
       
  1994             {
       
  1995 TFLOGSTRING("TSY: CMmSmsMessHandler::CheckTpPidAndSenderAndServiceCenter: Could not extract data from received message");
       
  1996             OstTrace0( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_CHECKTPPIDANDSENDERANDSERVICECENTER, "CMmSmsMessHandler::CheckTpPidAndSenderAndServiceCenter: Could not extract data from received message" );
       
  1997             return EFalse;
       
  1998             }
       
  1999 
       
  2000         // 2. Get sender address from received message
       
  2001         TUint smsUserDataOffset( 0 );
       
  2002         if ( KErrNone == aReceivedSmsIsiMsg.FindSubBlockOffsetById(
       
  2003             ISI_HEADER_SIZE + SIZE_SMS_RECEIVED_MSG_IND,
       
  2004             SMS_SB_TPDU,
       
  2005             EIsiSubBlockTypeId16Len16,
       
  2006             smsUserDataOffset ) )
       
  2007             {
       
  2008             TUint8 userDataLength( aReceivedSmsIsiMsg.Get8bit(
       
  2009                 smsUserDataOffset + SMS_SB_TPDU_OFFSET_DATALENGTH ) );
       
  2010             TPtrC8 sms( aReceivedSmsIsiMsg.GetData(
       
  2011                 smsUserDataOffset + SMS_SB_TPDU_OFFSET_DATABYTES,
       
  2012                 userDataLength ) );
       
  2013 
       
  2014             if ( 0 < sms.Length() )
       
  2015                 {
       
  2016                 // Check type of received SMS message
       
  2017                 TUint8 messageParams( sms[0] );
       
  2018                 // Extract the least 2 bits to get SMS message type
       
  2019                 messageParams &= 0x03;
       
  2020                 if ( KSmsMTIDeliverOrDeliverReport == messageParams )
       
  2021                     {
       
  2022                     TPtrC8 tpOa( sms.Mid( 1 ) );
       
  2023                     CMmSmsGsmAddress::GsmConv0340AddrToUnicode(
       
  2024                         receivedMsgOriginatorAdress,
       
  2025                         tpOa,
       
  2026                         receivedMsgMobileOaTON,
       
  2027                         receivedMsgMobileOaNPI );
       
  2028                     }
       
  2029                 }
       
  2030             }
       
  2031         else // Could not extract data from received message
       
  2032             {
       
  2033 TFLOGSTRING("TSY: CMmSmsMessHandler::CheckTpPidAndSenderAndServiceCenter: Could not extract data from received message");
       
  2034 OstTrace0( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_CHECKTPPIDANDSENDERANDSERVICECENTER, "CMmSmsMessHandler::CheckTpPidAndSenderAndServiceCenter - Could not extract data from received message" );
       
  2035             return EFalse;
       
  2036             }
       
  2037 
       
  2038         // 3. Get sender number from stored message
       
  2039 
       
  2040         TPtrC8 tpOa( aSMSOnSIM->iMsgData.Mid ( 1 ) );
       
  2041         CMmSmsGsmAddress::GsmConv0340AddrToUnicode(
       
  2042             readMsgOriginatorAdress,
       
  2043             tpOa,
       
  2044             readMsgMobileOaTON,
       
  2045             readMsgMobileOaNPI );
       
  2046 
       
  2047         // 4. Compare
       
  2048         if ( ( receivedMsgMobileOaTON == readMsgMobileOaTON )
       
  2049             && ( receivedMsgMobileOaNPI == readMsgMobileOaNPI )
       
  2050             && ( 0 == receivedMsgOriginatorAdress.Compare(
       
  2051             readMsgOriginatorAdress ) )
       
  2052 
       
  2053             && ( receivedMsgMobileScTON == aSMSOnSIM->iServiceCentre.iTypeOfNumber )
       
  2054             && ( receivedMsgMobileScNPI == aSMSOnSIM->iServiceCentre.iNumberPlan )
       
  2055             && ( 0 == receivedMsgServiceCentre.Compare(
       
  2056                  aSMSOnSIM->iServiceCentre.iTelNumber ) ) )
       
  2057             {
       
  2058             matchFound = ETrue;
       
  2059             }
       
  2060         }
       
  2061     return matchFound;
       
  2062     }
       
  2063 
       
  2064 // -----------------------------------------------------------------------------
       
  2065 // CMmSmsMessHandler::GetSmsStoreInfo
       
  2066 // ETel requests EMobileSmsMessagingGetMessageStoreInfo and
       
  2067 // EMobilePhoneStoreGetInfo
       
  2068 // -----------------------------------------------------------------------------
       
  2069 //
       
  2070 TInt CMmSmsMessHandler::GetSmsStoreInfo( TInt aIpc )
       
  2071     {
       
  2072 TFLOGSTRING2("TSY: CMmSmsMessHandler::GetSmsStoreInfo - IPC: %d", aIpc);
       
  2073 OstTrace1( TRACE_NORMAL, CMMSMSMESSHANDLER_GETSMSSTOREINFO, "CMmSmsMessHandler::GetSmsStoreInfo;aIpc=%d", aIpc );
       
  2074     TInt ret( KErrNone );
       
  2075     // SIM SMS cache:
       
  2076     // -- EMobileSmsMessagingGetMessageStoreInfo/EMobilePhoneStoreGetInfo
       
  2077     if ( KErrNone == iSmsCache.Status() )
       
  2078         {
       
  2079 TFLOGSTRING("TSY: CMmSmsMessHandler::GetSmsStoreInfo -- completed immediatedly");
       
  2080 OstTrace0( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_GETSMSSTOREINFO, "CMmSmsMessHandler::GetSmsStoreInfo, completed immediatedly" );
       
  2081         TUint8 numOfLoc( TUint8( iSmsCache.TotalEntries() ) );
       
  2082         TInt usedEntries( iSmsCache.UsedEntries() );
       
  2083         CMmDataPackage data;
       
  2084         data.PackData( &numOfLoc, &usedEntries );
       
  2085         iMessageRouter->Complete( aIpc, &data, KErrNone );
       
  2086         }
       
  2087     // try to recover from out of memory condition
       
  2088     else if ( KErrNoMemory == iSmsCache.Status() )
       
  2089         {
       
  2090 TFLOGSTRING("TSY: CMmSmsMessHandler::GetSmsStoreInfo -- recovering from OOM");
       
  2091 OstTrace0( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_GETSMSSTOREINFO, "CMmSmsMessHandler::GetSmsStoreInfo, recovering from OOM" );
       
  2092         InitializeSmsCache();
       
  2093         }
       
  2094     // cache is not ready, start waiting
       
  2095     else if ( KErrNotReady == iSmsCache.Status() )
       
  2096         {
       
  2097 TFLOGSTRING("TSY: CMmSmsMessHandler::GetSmsStoreInfo -- waiting");
       
  2098 OstTrace0( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_GETSMSSTOREINFO, "CMmSmsMessHandler::GetSmsStoreInfo, waiting" );
       
  2099         }
       
  2100     // some other, error return error value
       
  2101     else
       
  2102         {
       
  2103 TFLOGSTRING("TSY: CMmSmsMessHandler::GetSmsStoreInfo -- failed");
       
  2104 OstTrace0( TRACE_NORMAL, DUP4_CMMSMSMESSHANDLER_GETSMSSTOREINFO, "CMmSmsMessHandler::GetSmsStoreInfo, failed" );
       
  2105         ret = iSmsCache.Status();
       
  2106         }
       
  2107     return ret;
       
  2108     }
       
  2109 
       
  2110 // -----------------------------------------------------------------------------
       
  2111 // CMmSmsMessHandler::DeleteSms
       
  2112 // Delete SMS from SIM
       
  2113 // -----------------------------------------------------------------------------
       
  2114 //
       
  2115 TInt CMmSmsMessHandler::DeleteSms( const CMmDataPackage* aDataPackage )
       
  2116     {
       
  2117 TFLOGSTRING("TSY: CMmSmsMessHandler::DeleteSms");
       
  2118 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_DELETESMS, "CMmSmsMessHandler::DeleteSms" );
       
  2119     // SIM SMS cache: -- EMobilePhoneStoreDelete
       
  2120     TInt ret( KErrNone );
       
  2121 
       
  2122     // Symbian sms stack will try to delete received SMS2 from SIM if it can't
       
  2123     // save it to filesystem, so deletion should be possible in out of memory
       
  2124     // state..
       
  2125     if ( KErrNone == iSmsCache.Status() || KErrNoMemory == iSmsCache.Status() )
       
  2126         {
       
  2127         TInt index( 0 );
       
  2128         //unpack data
       
  2129         aDataPackage->UnPackData( index );
       
  2130         iSmsCache.SetDeleteLocation( index );
       
  2131         }
       
  2132     else
       
  2133         {
       
  2134 TFLOGSTRING("TSY: CMmSmsMessHandler::DeleteSms, cache not ready/failed");
       
  2135 OstTrace0( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_DELETESMS, "CMmSmsMessHandler::DeleteSms, cache not ready/failed" );
       
  2136         ret = iSmsCache.Status();
       
  2137         }
       
  2138     return ret;
       
  2139     }
       
  2140 
       
  2141 // -----------------------------------------------------------------------------
       
  2142 // CMmSmsMessHandler::DeleteAllSms
       
  2143 // Delete all SMS's from sim
       
  2144 // -----------------------------------------------------------------------------
       
  2145 //
       
  2146 TInt CMmSmsMessHandler::DeleteAllSms()
       
  2147     {
       
  2148 TFLOGSTRING("TSY: CMmSmsMessHandler::DeleteAllSms");
       
  2149 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_DELETEALLSMS, "CMmSmsMessHandler::DeleteAllSms" );
       
  2150     TInt ret( KErrNone );
       
  2151     // SIM SMS cache: -- EMobilePhoneStoreDeleteAll
       
  2152     if ( KErrNone == iSmsCache.Status() )
       
  2153         {
       
  2154         }
       
  2155     else
       
  2156         {
       
  2157 TFLOGSTRING("TSY: CMmSmsMessHandler::DeleteAllSms, cache not ready/failed");
       
  2158 OstTrace0( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_DELETEALLSMS, "CMmSmsMessHandler::DeleteAllSms, cache not ready/failed" );
       
  2159         ret = iSmsCache.Status();
       
  2160         }
       
  2161     return ret;
       
  2162     }
       
  2163 
       
  2164 // -----------------------------------------------------------------------------
       
  2165 // CMmSmsMessHandler::ReadSms
       
  2166 // Read SMS's from SIM
       
  2167 // -----------------------------------------------------------------------------
       
  2168 //
       
  2169 TInt CMmSmsMessHandler::ReadSms( const CMmDataPackage* aDataPackage )
       
  2170     {
       
  2171 TFLOGSTRING("TSY: CMmSmsMessHandler::ReadSms");
       
  2172 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_READSMS, "CMmSmsMessHandler::ReadSms" );
       
  2173 
       
  2174     TInt ret( KErrNone );
       
  2175 
       
  2176     TInt location( 0 );
       
  2177     //unpack data
       
  2178     aDataPackage->UnPackData( location );
       
  2179 
       
  2180     // SIM SMS cache: -- EMobilePhoneStoreRead
       
  2181     if ( KErrNone == iSmsCache.Status() )
       
  2182         {
       
  2183          // Find sms from cache
       
  2184         RMobileSmsStore::TMobileGsmSmsEntryV1* smsData(
       
  2185             iSmsCache.GetEntry( location ) );
       
  2186 
       
  2187         if ( smsData )
       
  2188             {
       
  2189             TSmsMsg smsMsg;
       
  2190             smsMsg.iLocation = location;
       
  2191             smsMsg.iMessageStatus = smsData->iMsgStatus;
       
  2192             smsMsg.iMobileScNPI = smsData->iServiceCentre.iNumberPlan;
       
  2193             smsMsg.iMobileScTON = smsData->iServiceCentre.iTypeOfNumber;
       
  2194             smsMsg.iServiceCentre = smsData->iServiceCentre.iTelNumber;
       
  2195             smsMsg.iSmsClass2 = ETrue;
       
  2196             smsMsg.iSmsMsg = smsData->iMsgData;
       
  2197 
       
  2198             CMmDataPackage data;
       
  2199             data.PackData( &smsMsg );
       
  2200             iMessageRouter->Complete(
       
  2201                 EMobilePhoneStoreRead,
       
  2202                 &data,
       
  2203                 KErrNone );
       
  2204 
       
  2205             ret = KErrNone;
       
  2206             }
       
  2207         else
       
  2208             {
       
  2209             ret = KErrNotFound;
       
  2210             }
       
  2211         }
       
  2212     else
       
  2213         {
       
  2214 TFLOGSTRING("TSY: CMmSmsMessHandler::ReadSms, cache not ready/failed");
       
  2215 OstTrace0( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_READSMS, "CMmSmsMessHandler::ReadSms, cache not ready/failed" );
       
  2216         ret = iSmsCache.Status();
       
  2217         }
       
  2218     return ret;
       
  2219     }
       
  2220 
       
  2221 // -----------------------------------------------------------------------------
       
  2222 // CMmSmsMessHandler::ReadAllSmsL
       
  2223 // Read SMS's from SIM
       
  2224 // -----------------------------------------------------------------------------
       
  2225 //
       
  2226 TInt CMmSmsMessHandler::ReadAllSmsL()
       
  2227     {
       
  2228 TFLOGSTRING("TSY: CMmSmsMessHandler::ReadAllSms");
       
  2229 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_READALLSMSL, "CMmSmsMessHandler::ReadAllSmsL" );
       
  2230     TInt ret( KErrNone );
       
  2231 
       
  2232     // SIM SMS cache: -- EMobilePhoneStoreReadAllPhase1
       
  2233     if ( KErrNone == iSmsCache.Status() )
       
  2234         {
       
  2235         // reads all sms's from SIM to a list and returns
       
  2236         // the list to commontsy.
       
  2237 
       
  2238         iSmsListArray->ResetAndDestroy();
       
  2239 
       
  2240         // process & copy SMS's to iSmsListArray..
       
  2241         for ( TInt i( 1 ); i <= iSmsCache.TotalEntries(); i++ )
       
  2242             {
       
  2243             // Add read SMS to the TSY's internal storage
       
  2244             // Find sms from cache
       
  2245             RMobileSmsStore::TMobileGsmSmsEntryV1* smsData(
       
  2246                 iSmsCache.GetEntry( i ) );
       
  2247 
       
  2248             TSmsMsg* smsMsg = new ( ELeave )TSmsMsg();
       
  2249             CleanupDeletePushL( smsMsg );
       
  2250 
       
  2251             if ( smsData )
       
  2252                 {
       
  2253                 smsMsg->iLocation = i;
       
  2254                 smsMsg->iMessageStatus = smsData->iMsgStatus;
       
  2255                 smsMsg->iMobileScNPI = smsData->iServiceCentre.iNumberPlan;
       
  2256                 smsMsg->iMobileScTON = smsData->iServiceCentre.iTypeOfNumber;
       
  2257                 smsMsg->iServiceCentre = smsData->iServiceCentre.iTelNumber;
       
  2258                 smsMsg->iSmsClass2 = ETrue;
       
  2259                 smsMsg->iSmsMsg = smsData->iMsgData;
       
  2260 
       
  2261                 iSmsListArray->AppendL( smsMsg );
       
  2262                 CleanupStack::Pop( smsMsg );
       
  2263                 }
       
  2264             else
       
  2265                 {
       
  2266                 CleanupStack::PopAndDestroy( smsMsg );
       
  2267                 }
       
  2268             }
       
  2269 
       
  2270         // complete immediatedly...
       
  2271         CMmDataPackage package;
       
  2272         package.PackData( &iSmsListArray, &iReceivedClass2ToBeReSent );
       
  2273         iMessageRouter->Complete(
       
  2274             EMobilePhoneStoreReadAllPhase1,
       
  2275             &package,
       
  2276             KErrNone );
       
  2277 
       
  2278         //Delete array
       
  2279         iSmsListArray->ResetAndDestroy();
       
  2280         iReceivedClass2ToBeReSent = EFalse;
       
  2281         }
       
  2282     else
       
  2283         {
       
  2284 TFLOGSTRING("TSY: CMmSmsMessHandler::ReadAllSms --- cache not ready/failed");
       
  2285 OstTrace0( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_READALLSMSL, "CMmSmsMessHandler::ReadAllSmsL, cache not ready/failed" );
       
  2286         iSmsListArray->ResetAndDestroy();
       
  2287         CMmDataPackage package;
       
  2288         package.PackData( &iSmsListArray, &iReceivedClass2ToBeReSent );
       
  2289         iMessageRouter->Complete(
       
  2290             EMobilePhoneStoreReadAllPhase1,
       
  2291             &package,
       
  2292             iSmsCache.Status() );
       
  2293         iReceivedClass2ToBeReSent = EFalse;
       
  2294         }
       
  2295     return ret;
       
  2296     }
       
  2297 
       
  2298 // -----------------------------------------------------------------------------
       
  2299 // CMmSmsMessHandler::WriteSms
       
  2300 // Write SMS to SIM
       
  2301 // -----------------------------------------------------------------------------
       
  2302 //
       
  2303 TInt CMmSmsMessHandler::WriteSms(
       
  2304     const RMobileSmsStore::TMobileGsmSmsEntryV1& aEntry,
       
  2305     TInt aIndex)
       
  2306     {
       
  2307     TInt ret( KErrNone );
       
  2308 
       
  2309 TFLOGSTRING("TSY: CMmSmsMessHandler::WriteSms");
       
  2310 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_WRITESMS, "CMmSmsMessHandler::WriteSms" );
       
  2311 
       
  2312     // SIM SMS cache: -- EMobilePhoneStoreWrite
       
  2313     //check if sms writing is ongoing or not
       
  2314     if ( 0 != iSmsSlotLocation )
       
  2315         {
       
  2316         ret = KErrNotReady;
       
  2317         }
       
  2318     else if ( KErrNone == iSmsCache.Status() )
       
  2319         {
       
  2320 
       
  2321         //iWriteSmsEntryPtr = aEntry;
       
  2322 
       
  2323         //find a free slot to write the Sms
       
  2324         // -1 means "find the frst free slot"
       
  2325         if ( -1 != aIndex )
       
  2326             {
       
  2327             iSmsSlotLocation = TUint8( aIndex );
       
  2328             }
       
  2329         else
       
  2330             {
       
  2331             iSmsSlotLocation = TUint8( iSmsCache.FirstFreeLocation() );
       
  2332             aIndex = iSmsSlotLocation;
       
  2333             }
       
  2334 
       
  2335         if ( 0 == iSmsSlotLocation )
       
  2336             {
       
  2337             // asked to write to a free slot, but no free slots found
       
  2338             ret = CMmStaticUtility::EpocErrorCode(
       
  2339                 KErrOverflow,
       
  2340                 KErrMMEtelMaxReached );
       
  2341             }
       
  2342         else
       
  2343             {
       
  2344             ret = UiccWriteSMSReq( aEntry, iSmsSlotLocation );
       
  2345             }
       
  2346         }
       
  2347     else
       
  2348         {
       
  2349         ret = iSmsCache.Status();
       
  2350         }
       
  2351     return ret;
       
  2352     }
       
  2353 
       
  2354 // -----------------------------------------------------------------------------
       
  2355 // CMmSmsMessHandler::InitializeSmsCache
       
  2356 // Start reading cache
       
  2357 // -----------------------------------------------------------------------------
       
  2358 //
       
  2359 void CMmSmsMessHandler::InitializeSmsCache()
       
  2360     {
       
  2361     // SIM SMS cache: initialize cache
       
  2362 TFLOGSTRING("TSY: CMmSmsMessHandler::InitializeSmsCache -- SMS CACHEING START ---");
       
  2363 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_INITIALIZESMSCACHE, "CMmSmsMessHandler::InitializeSmsCache" );
       
  2364     iSmsCache.Reset();
       
  2365     GetNumOfEFSMSRecords (); // Read EF SMS count.
       
  2366     }
       
  2367 
       
  2368 // -----------------------------------------------------------------------------
       
  2369 // CMmSmsMessHandler::HandleError
       
  2370 // Handles CMmSmsMessHandler's errors comes via PhoNetReceiver RunError method.
       
  2371 // -----------------------------------------------------------------------------
       
  2372 //
       
  2373 void CMmSmsMessHandler::HandleError(
       
  2374         const TIsiReceiveC& aIsiMsg, // Isi message
       
  2375         TInt aError )                // Error code
       
  2376 
       
  2377     {
       
  2378 TFLOGSTRING2( "TSY: CMmSmsMessHandler::HandleError - Error: %d", aError );
       
  2379 OstTrace1( TRACE_NORMAL, CMMSMSMESSHANDLER_HANDLEERROR, "CMmSmsMessHandler::HandleError;aError=%d", aError );
       
  2380 
       
  2381     TUint8 resource( aIsiMsg.Get8bit( ISI_HEADER_OFFSET_RESOURCEID ) );
       
  2382     TUint8 messageId( aIsiMsg.Get8bit( ISI_HEADER_OFFSET_MESSAGEID ) );
       
  2383     TUint8 transId( aIsiMsg.Get8bit( ISI_HEADER_OFFSET_TRANSID ) );
       
  2384 
       
  2385 TFLOGSTRING4( "TSY: CMmSmsMessHandler::HandleError - resource: %d, msgId: %d, traId: %d", resource, messageId, transId );
       
  2386 OstTraceExt3(TRACE_NORMAL,DUP1_CMMSMSMESSHANDLER_HANDLEERROR,"CMmSmsMessHandler::HandleError;resource=%hhu;messageId=%hhu;transId=%hhu", resource, messageId, transId );
       
  2387 
       
  2388     switch ( resource )
       
  2389         {
       
  2390         default:
       
  2391             {
       
  2392 TFLOGSTRING2( "TSY: CMmSmsMessHandler::HandleError - PN_SMS, unknown resource: %d", resource );
       
  2393 OstTraceExt1( TRACE_NORMAL, DUP4_CMMSMSMESSHANDLER_HANDLEERROR, "CMmSmsMessHandler::HandleError;resource=%hhu", resource );
       
  2394             // Nothing to do here.
       
  2395             break;
       
  2396             }
       
  2397         }
       
  2398     }
       
  2399 
       
  2400 // -----------------------------------------------------------------------------
       
  2401 // CMmSmsMessHandler::SmsSettingsUpdateReq
       
  2402 // Sets SMS bearer.
       
  2403 // -----------------------------------------------------------------------------
       
  2404 //
       
  2405 TInt CMmSmsMessHandler::SmsSettingsUpdateReq(
       
  2406     RMobileSmsMessaging::TMobileSmsBearer& aBearer )
       
  2407     {
       
  2408 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsSettingsUpdateReq. aBearer: %d", aBearer);
       
  2409 OstTrace1( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSSETTINGSUPDATEREQ, "CMmSmsMessHandler::SmsSettingsUpdateReq;aBearer=%d", aBearer );
       
  2410 
       
  2411     TUint8 csRoutePriority( SMS_ROUTE_NOT_AVAILABLE );
       
  2412     TUint8 psRoutePriority( SMS_ROUTE_NOT_AVAILABLE );
       
  2413 
       
  2414     // The bearer information must be used in two ways:
       
  2415     // 1. It must be saved here, and is used later for SMS sending.
       
  2416     iMobileSmsBearer = aBearer;
       
  2417 
       
  2418     // 2. It must be immediadely set to ISI SMS Server (affects
       
  2419     // RP-SHORT-MESSAGE-MEMORY-AVAILABLE).
       
  2420     switch ( iMobileSmsBearer )
       
  2421         {
       
  2422         case RMobileSmsMessaging::ESmsBearerPacketOnly:
       
  2423             { // PS with highest priority, CS not available
       
  2424             psRoutePriority = SMS_ROUTE_PRIORITY_1;
       
  2425             break;
       
  2426             }
       
  2427         case RMobileSmsMessaging::ESmsBearerPacketPreferred:
       
  2428             { // PS with highest priority, CS with second highest priority
       
  2429             psRoutePriority = SMS_ROUTE_PRIORITY_1;
       
  2430             csRoutePriority = SMS_ROUTE_PRIORITY_2;
       
  2431             break;
       
  2432             }
       
  2433         case RMobileSmsMessaging::ESmsBearerCircuitOnly:
       
  2434             { // CS with highest priority, PS not available
       
  2435             csRoutePriority = SMS_ROUTE_PRIORITY_1;
       
  2436             break;
       
  2437             }
       
  2438         case RMobileSmsMessaging::ESmsBearerCircuitPreferred:
       
  2439             { // CS with highest priority, PS with second highest priority
       
  2440             csRoutePriority = SMS_ROUTE_PRIORITY_1;
       
  2441             psRoutePriority = SMS_ROUTE_PRIORITY_2;
       
  2442             break;
       
  2443             }
       
  2444         default:
       
  2445             {
       
  2446 TFLOGSTRING2("TSY:CMmSmsMessHandler::SmsSettingsUpdateReq:Invalid bearer = %d",iMobileSmsBearer);
       
  2447 OstTrace1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_SMSSETTINGSUPDATEREQ, "CMmSmsMessHandler::SmsSettingsUpdateReq;iMobileSmsBearer=%d", iMobileSmsBearer );
       
  2448             break;
       
  2449             }
       
  2450         }
       
  2451 
       
  2452 TFLOGSTRING3("TSY:CMmSmsMessHandler::SmsSettingsUpdateReq:CS priority = %d, PS priority = %d",csRoutePriority,psRoutePriority);
       
  2453 OstTraceExt2( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_SMSSETTINGSUPDATEREQ, "CMmSmsMessHandler::SmsSettingsUpdateReq;csRoutePriority=%hhd;psRoutePriority=%hhd", csRoutePriority, psRoutePriority );
       
  2454 
       
  2455     // SMS_SB_ROUTE_INFO sub block (8 bytes)
       
  2456     TBuf8<SIZE_SMS_SB_ROUTE_INFO> smsRouteInfoBuf( 0 );
       
  2457     TIsiSubBlock smsRouteInfoSb(
       
  2458         smsRouteInfoBuf,
       
  2459         SMS_SB_ROUTE_INFO,
       
  2460         EIsiSubBlockTypeId16Len16 );
       
  2461     smsRouteInfoBuf.Append( csRoutePriority );
       
  2462     smsRouteInfoBuf.Append( psRoutePriority );
       
  2463 
       
  2464     // Create SMS_SETTINGS_UPDATE_REQ message
       
  2465     TIsiSend isiMsg( iPhoNetSender->SendBufferDes() );
       
  2466     isiMsg.Set8bit( ISI_HEADER_OFFSET_RESOURCEID, PN_SMS );
       
  2467     isiMsg.Set8bit(
       
  2468         ISI_HEADER_SIZE + SMS_SETTINGS_UPDATE_REQ_OFFSET_TRANSID,
       
  2469         0 );
       
  2470     isiMsg.Set8bit(
       
  2471         ISI_HEADER_SIZE + SMS_SETTINGS_UPDATE_REQ_OFFSET_MESSAGEID,
       
  2472         SMS_SETTINGS_UPDATE_REQ  );
       
  2473     isiMsg.Set8bit(
       
  2474         ISI_HEADER_SIZE + SMS_SETTINGS_UPDATE_REQ_OFFSET_SETTINGTYPE,
       
  2475         SMS_SETTING_TYPE_ROUTE );
       
  2476     isiMsg.Set8bit(
       
  2477         ISI_HEADER_SIZE + SMS_SETTINGS_UPDATE_REQ_OFFSET_SUBBLOCKCOUNT,
       
  2478         1 );
       
  2479 
       
  2480     isiMsg.CopyData(
       
  2481         ISI_HEADER_SIZE + SIZE_SMS_SETTINGS_UPDATE_RESP,
       
  2482         smsRouteInfoSb.CompleteSubBlock() );
       
  2483 
       
  2484     return ( iPhoNetSender->Send( isiMsg.Complete() ) );
       
  2485     }
       
  2486 
       
  2487 // -----------------------------------------------------------------------------
       
  2488 // CMmSmsMessHandler::SmsSettingsUpdateResp
       
  2489 // Completes SMS bearer setting.
       
  2490 // -----------------------------------------------------------------------------
       
  2491 //
       
  2492 void CMmSmsMessHandler::SmsSettingsUpdateResp( const TIsiReceiveC& aIsiMsg )
       
  2493     {
       
  2494     TUint8 cause( aIsiMsg.Get8bit(
       
  2495         ISI_HEADER_SIZE + SMS_SETTINGS_UPDATE_RESP_OFFSET_SMSCAUSE ) );
       
  2496 
       
  2497 TFLOGSTRING2("TSY:CMmSmsMessHandler::SmsSettingsUpdateResp: response status=%d.",cause);
       
  2498 OstTraceExt1( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSGSMSETTINGSUPDATERESP, "CMmSmsMessHandler::SmsSettingsUpdateResp;cause=%hhu", cause );
       
  2499 
       
  2500     TInt err( CMmStaticUtility::CSCauseToEpocError(
       
  2501         PN_SMS,
       
  2502         SMS_CAUSE_TYPE_COMMON,
       
  2503         cause ) );
       
  2504 
       
  2505     iMessageRouter->Complete( EMobileSmsMessagingSetMoSmsBearer, err );
       
  2506     }
       
  2507 
       
  2508 // -----------------------------------------------------------------------------
       
  2509 // CMmSmsMessHandler::SmsClass2ReceivedMsgInd
       
  2510 // Processes class2 SMS. Called by CMmSmsMessHandler::SmsReceivedMsgInd.
       
  2511 // -----------------------------------------------------------------------------
       
  2512 //
       
  2513 TInt CMmSmsMessHandler::SmsClass2ReceivedMsgInd(
       
  2514     const TIsiReceiveC& aIsiMsg,
       
  2515     TUint8 aIsReplace )
       
  2516     {
       
  2517 TFLOGSTRING("TSY: CMmSmsMessHandler::SmsClass2ReceivedMsgInd");
       
  2518 OstTrace0( TRACE_NORMAL, DUP4_CMMSMSMESSHANDLER_SMSCLASS2PPROUTINGNTF, "CMmSmsMessHandler::SmsClass2ReceivedMsgInd" );
       
  2519     TInt ret( KErrNone );
       
  2520 
       
  2521     TUint smsTpduOffset( 0 );
       
  2522     if ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
       
  2523         ISI_HEADER_SIZE + SIZE_SMS_RECEIVED_MSG_IND,
       
  2524         SMS_SB_TPDU,
       
  2525         EIsiSubBlockTypeId16Len16,
       
  2526         smsTpduOffset ) )
       
  2527         {
       
  2528         // SMS_SB_TPDU sub block found
       
  2529         // Checked if sms writing is ongoing or not and cache is ok
       
  2530         if ( 0 == iSmsSlotLocation && KErrNone == iSmsCache.Status() )
       
  2531             {
       
  2532             TUint location( 0 );
       
  2533 
       
  2534             // If this is a replace message, try find a SMS to replace
       
  2535             if ( aIsReplace )
       
  2536                 {
       
  2537 TFLOGSTRING("TSY: CMmSmsMessHandler::SmsClass2ReceivedMsgInd --- replace");
       
  2538 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSCLASS2PPROUTINGNTF, "CMmSmsMessHandler::SmsClass2ReceivedMsgInd, replace" );
       
  2539                 for ( TInt i( 0 ); i <= iSmsCache.TotalEntries(); i++ )
       
  2540                     {
       
  2541                     RMobileSmsStore::TMobileGsmSmsEntryV1* simIsiMsg =
       
  2542                         iSmsCache.GetEntry( i );
       
  2543                     if ( simIsiMsg )
       
  2544                         {
       
  2545                         if ( CheckTpPidAndSenderAndServiceCenter(
       
  2546                             aIsReplace,
       
  2547                             aIsiMsg,
       
  2548                             simIsiMsg ) )
       
  2549                             {
       
  2550                             location = i;
       
  2551                             break;
       
  2552                             }
       
  2553                         }
       
  2554                     }
       
  2555                 }
       
  2556 
       
  2557             // Not a replace message, or no message to replace found.
       
  2558             // Try to find a free slot
       
  2559             if ( 0 == location )
       
  2560                 {
       
  2561                 location = iSmsCache.FirstFreeLocation();
       
  2562                 }
       
  2563 
       
  2564             // Location found, start SMS writing
       
  2565             if ( 0 != location )
       
  2566                 {
       
  2567 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsClass2ReceivedMsgInd -- incoming SMS2, writing to location %d", location);
       
  2568 OstTrace1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_SMSCLASS2PPROUTINGNTF, "CMmSmsMessHandler::SmsClass2ReceivedMsgInd;incoming SMS2, writing to location=%d", location );
       
  2569                 // iSmsSlotLocation = TUint8(location);
       
  2570                 // Write received class2 SMS to SIM Card
       
  2571                 // Get data from incoming message.
       
  2572                 RMobileSmsStore::TMobileGsmSmsEntryV1 incomingSMS;
       
  2573 
       
  2574                 // 1. Get service center address from received message
       
  2575                 TUint smsAddressOffset( 0 );
       
  2576                 if ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
       
  2577                     ISI_HEADER_SIZE + SIZE_SMS_RECEIVED_MSG_IND,
       
  2578                     SMS_SB_ADDRESS,
       
  2579                     EIsiSubBlockTypeId16Len16,
       
  2580                     smsAddressOffset ) )
       
  2581                     {
       
  2582                     if ( SMS_SMSC_ADDRESS == aIsiMsg.Get8bit(
       
  2583                         smsAddressOffset + SMS_SB_ADDRESS_OFFSET_ADDRESSTYPE ) )
       
  2584                         {
       
  2585                         // Convert service centre address (SC Address 04.11)
       
  2586                         TUint8 addressDataLength( aIsiMsg.Get8bit(
       
  2587                             smsAddressOffset +
       
  2588                             SMS_SB_ADDRESS_OFFSET_ADDRESSDATALENGTH ) );
       
  2589                         TPtrC8 scA( aIsiMsg.GetData(
       
  2590                             smsAddressOffset + SMS_SB_ADDRESS_OFFSET_ADDRESSDATA,
       
  2591                             addressDataLength ) );
       
  2592                         CMmSmsGsmAddress::GsmConv0411AddrToUnicode(
       
  2593                             incomingSMS.iServiceCentre.iTelNumber,
       
  2594                             scA,
       
  2595                             incomingSMS.iServiceCentre.iTypeOfNumber,
       
  2596                             incomingSMS.iServiceCentre.iNumberPlan );
       
  2597                         }
       
  2598                     }
       
  2599 
       
  2600                 // 2. Get sender address from received message
       
  2601                 TUint smsUserDataOffset( 0 );
       
  2602                 if ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
       
  2603                     ISI_HEADER_SIZE + SIZE_SMS_RECEIVED_MSG_IND,
       
  2604                     SMS_SB_TPDU,
       
  2605                     EIsiSubBlockTypeId16Len16,
       
  2606                     smsUserDataOffset ) )
       
  2607                     {
       
  2608                     TUint8 userDataLength( aIsiMsg.Get8bit(
       
  2609                         smsUserDataOffset + SMS_SB_TPDU_OFFSET_DATALENGTH ) );
       
  2610                     TPtrC8 sms( aIsiMsg.GetData(
       
  2611                         smsUserDataOffset + SMS_SB_TPDU_OFFSET_DATABYTES,
       
  2612                         userDataLength ) );
       
  2613 
       
  2614                     if ( 0 < sms.Length() )
       
  2615                         {
       
  2616                         // Check type of received SMS message
       
  2617                         TUint8 position( 0 );
       
  2618                         incomingSMS.iMsgStatus =
       
  2619                             static_cast <RMobileSmsStore::TMobileSmsStoreStatus>( sms[position] );
       
  2620 
       
  2621                         // Start of the user data
       
  2622                         incomingSMS.iMsgData =  sms.Mid( position );
       
  2623                         }
       
  2624                     }
       
  2625                     iSMSClass2Write = ETrue;
       
  2626                     ret = WriteSms( incomingSMS, location );
       
  2627                }
       
  2628 
       
  2629             // No free slots! SIM full
       
  2630             else
       
  2631                 {
       
  2632                 ret = KErrGsmSMSUnspecifiedProtocolError;
       
  2633                 }
       
  2634             }
       
  2635 
       
  2636         // Cache not ready
       
  2637         else
       
  2638             {
       
  2639 TFLOGSTRING("TSY: CMmSmsMessHandler::SmsClass2ReceivedMsgInd -- incoming SMS2, cache not ready/failed");
       
  2640 OstTrace0( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_SMSCLASS2PPROUTINGNTF, "CMmSmsMessHandler::SmsClass2ReceivedMsgInd, incoming SMS2, cache not ready/failed" );
       
  2641             ret = KErrGsmSMSMemoryCapacityExceeded;
       
  2642             // Setting this true will cause it to be resent?
       
  2643             iReceivedClass2ToBeReSent = ETrue;
       
  2644 
       
  2645             // If this is out of memory error, try to refill cache..
       
  2646             if ( KErrNoMemory == iSmsCache.Status() )
       
  2647                 {
       
  2648                 InitializeSmsCache();
       
  2649                 }
       
  2650             }
       
  2651         }
       
  2652 
       
  2653 TFLOGSTRING2("TSY: CMmSmsMessHandler::SmsClass2ReceivedMsgInd ret=%d", ret);
       
  2654 OstTrace1( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_SMSCLASS2PPROUTINGNTF, "CMmSmsMessHandler::SmsClass2ReceivedMsgInd;ret=%d", ret );
       
  2655     return ret;
       
  2656     }
       
  2657 
       
  2658 // -----------------------------------------------------------------------------
       
  2659 // CMmSmsMessHandler::SmsClass1ReceivedMsgInd
       
  2660 // Processes class1 SMS. Called by CMmSmsMessHandler::SmsReceivedMsgInd.
       
  2661 // -----------------------------------------------------------------------------
       
  2662 //
       
  2663 TInt CMmSmsMessHandler::SmsClass1ReceivedMsgInd(
       
  2664         const TIsiReceiveC& aIsiMsg)
       
  2665     {
       
  2666 TFLOGSTRING("TSY: CMmSmsMessHandler::SmsClass1ReceivedMsgInd");
       
  2667 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_SMSCLASS1PPROUTINGNTF, "CMmSmsMessHandler::SmsClass1ReceivedMsgInd" );
       
  2668     TInt ret( KErrNone );
       
  2669     TBool validPduFormat( EFalse );
       
  2670     TSmsMsg  smsMsgValue;
       
  2671     TSmsMsg* smsMsg = &smsMsgValue;
       
  2672 
       
  2673     // Handle SMS_SB_ADDRESS subblock (service center address)
       
  2674     TUint smsAddressOffset( 0 );
       
  2675     if ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
       
  2676         ISI_HEADER_SIZE + SIZE_SMS_RECEIVED_MSG_IND,
       
  2677         SMS_SB_ADDRESS,
       
  2678         EIsiSubBlockTypeId16Len16,
       
  2679         smsAddressOffset ) )
       
  2680         {
       
  2681          TUint8 addressDataLength( aIsiMsg.Get8bit(
       
  2682              smsAddressOffset + SMS_SB_ADDRESS_OFFSET_ADDRESSDATALENGTH ) );
       
  2683 
       
  2684          TPtrC8 serviceCenterAddress( aIsiMsg.GetData(
       
  2685              smsAddressOffset + SMS_SB_ADDRESS_OFFSET_ADDRESSDATA,
       
  2686              addressDataLength ) );
       
  2687 
       
  2688          CMmSmsGsmAddress::GsmConv0411AddrToUnicode(
       
  2689              smsMsg->iServiceCentre,
       
  2690              serviceCenterAddress,
       
  2691              smsMsg->iMobileScTON,
       
  2692              smsMsg->iMobileScNPI );
       
  2693          }
       
  2694      else
       
  2695          {
       
  2696 TFLOGSTRING("TSY:CMmSmsMessHandler::SmsClass1ReceivedMsgInd,SMS_SB_ADDRESS expected");
       
  2697 OstTrace0( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_SMSCLASS1PPROUTINGNTF, "CMmSmsMessHandler::SmsClass1ReceivedMsgInd,SMS_SB_ADDRESS expected" );
       
  2698          TF_ASSERT_NOT_REACHED();
       
  2699          }
       
  2700 
       
  2701     // Handle SMS_SB_TPDU subblock
       
  2702     TUint smsTpduOffset( 0 );
       
  2703     if ( KErrNone == aIsiMsg.FindSubBlockOffsetById(
       
  2704         ISI_HEADER_SIZE + SIZE_SMS_RECEIVED_MSG_IND,
       
  2705         SMS_SB_TPDU,
       
  2706         EIsiSubBlockTypeId16Len16,
       
  2707         smsTpduOffset ) )
       
  2708         {
       
  2709         TUint8 userDataLength( aIsiMsg.Get8bit(
       
  2710             smsTpduOffset + SMS_SB_TPDU_OFFSET_DATALENGTH ) );
       
  2711 
       
  2712         TPtrC8 smsUserData( aIsiMsg.GetData(
       
  2713             smsTpduOffset + SMS_SB_TPDU_OFFSET_DATABYTES,
       
  2714             userDataLength ) );
       
  2715 
       
  2716         if ( 0 < smsUserData.Length() )
       
  2717             {
       
  2718             // Check type of received SMS message
       
  2719             TUint8 messageParams( smsUserData[0] );
       
  2720             messageParams &= 0x03;
       
  2721 
       
  2722             // Copy SMS to iSmsMsg if message type was SMS-DELIVER or
       
  2723             // SMS-STATUS-REPORT. Set also KSimSmsNotPresent in iMessageStatus
       
  2724             // because message is routed directly to the SMS stack (not
       
  2725             // stored in SIM).
       
  2726             if ( KSmsMTIDeliverOrDeliverReport == messageParams ||
       
  2727                 KSmsMTIStatusReportOrCommand == messageParams )
       
  2728                 {
       
  2729                 validPduFormat = ETrue;
       
  2730                 smsMsg->iMessageStatus = KSimSmsNotPresent;
       
  2731                 smsMsg->iSmsMsg.Copy( smsUserData );
       
  2732                 }
       
  2733             }
       
  2734         else
       
  2735             {
       
  2736 TFLOGSTRING("TSY:CMmSmsMessHandler::SmsClass1ReceivedMsgInd, SMS_SB_USER_DATA expected");
       
  2737 OstTrace0( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_SMSCLASS1PPROUTINGNTF, "CMmSmsMessHandler::SmsClass1ReceivedMsgInd, SMS_SB_USER_DATA expected" );
       
  2738             TF_ASSERT_NOT_REACHED();
       
  2739             }
       
  2740 
       
  2741         if ( validPduFormat )
       
  2742             {
       
  2743             TBool smsInd( ETrue );
       
  2744             smsMsg->iSmsClass2 = EFalse;
       
  2745 
       
  2746             // Pack data
       
  2747             CMmDataPackage package;
       
  2748             package.PackData( &smsInd, &smsMsg );
       
  2749 
       
  2750             // Complete request to client
       
  2751             iMessageRouter->Complete(
       
  2752                 EMobileSmsMessagingReceiveMessage,
       
  2753                 &package,
       
  2754                 KErrNone );
       
  2755 
       
  2756             ret = KErrNone; // avoid doubled completion
       
  2757             }
       
  2758         else
       
  2759             {
       
  2760             // Message type is undefined. Send NACK to the SMS Server.
       
  2761             SmsReceivedMsgReportReq(
       
  2762                 EInternalNack,
       
  2763                 NULL,
       
  2764                 KErrGsmSMSUnspecifiedInvalidMessage );
       
  2765             // Caller is forced to complete
       
  2766             ret = KErrGeneral;
       
  2767             }
       
  2768         }
       
  2769 TFLOGSTRING2("TSY:CMmSmsMessHandler::SmsClass1ReceivedMsgInd;ret=%d", ret);
       
  2770 OstTrace1( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_SMSCLASS1PPROUTINGNTF, "CMmSmsMessHandler::SmsClass1ReceivedMsgInd;ret=%d", ret );
       
  2771     return ret;
       
  2772     }
       
  2773 
       
  2774 
       
  2775 // -----------------------------------------------------------------------------
       
  2776 // CMmSmsMessHandler::GetDestAddressLength
       
  2777 // Extracts the length of destination address from TPDU in octets
       
  2778 // -----------------------------------------------------------------------------
       
  2779 //
       
  2780 TInt CMmSmsMessHandler::GetDestAddressLength(
       
  2781     const TDesC8& aMsgData,
       
  2782     TUint8 subBlockId,
       
  2783     TUint8& aDestAddressLength ) const
       
  2784     {
       
  2785 TFLOGSTRING("TSY:CMmSmsMessHandler::GetDestAddressLength");
       
  2786 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_GETDESTADDRESSLENGTH, "CMmSmsMessHandler::GetDestAddressLength" );
       
  2787 
       
  2788     TInt ret( KErrNone );
       
  2789 
       
  2790     if ( SMS_SB_SUBMIT == subBlockId )
       
  2791         {
       
  2792         aDestAddressLength =
       
  2793             aMsgData[ KTpduSubmitIndexDestinationAddressLength ] ;
       
  2794         }
       
  2795     else
       
  2796         {
       
  2797         aDestAddressLength =
       
  2798             aMsgData[ KTpduCommandIndexDestinationAddressLength ] ;
       
  2799         }
       
  2800 
       
  2801     // According 3GPP 23.040 max length of destination address is 20
       
  2802     if ( KMaxAmountOfDigits >= aDestAddressLength )
       
  2803         {
       
  2804         // Destination address length is integer representation
       
  2805         // of the number of useful semi-octets of address field
       
  2806         aDestAddressLength =  ( aDestAddressLength + 1 ) / 2 ;
       
  2807         }
       
  2808     else
       
  2809         {
       
  2810         ret = KErrArgument;
       
  2811 TFLOGSTRING2("TSY:CMmSmsMessHandler::GetDestinationAddressLength: Error! Destination address too long: %d.",aDestAddressLength);
       
  2812 OstTraceExt1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_GETDESTADDRESSLENGTH, "CMmSmsMessHandler::GetDestAddressLength;aDestAddressLength=%hhu", aDestAddressLength );
       
  2813         }
       
  2814 TFLOGSTRING2("TSY:CMmSmsMessHandler::GetDestinationAddressLength:Destination address length %d.",aDestAddressLength);
       
  2815 OstTraceExt1( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_GETDESTADDRESSLENGTH, "CMmSmsMessHandler::GetDestAddressLength;aDestAddressLength=%hhu", aDestAddressLength );
       
  2816     return ret;
       
  2817     }
       
  2818 
       
  2819 
       
  2820 // -----------------------------------------------------------------------------
       
  2821 // Creates SMS_SB_SUBMIT subblock and appends it to ISI message
       
  2822 // -----------------------------------------------------------------------------
       
  2823 //
       
  2824 void CMmSmsMessHandler::BuildSmsSbSubmit(
       
  2825     const TDesC8& aMsgData,
       
  2826     TIsiSend& aIsiMsg,
       
  2827     TUint8 aMsgOffset,
       
  2828     TUint8 aDestAddressLength ) const
       
  2829     {
       
  2830 TFLOGSTRING("TSY:CMmSmsMessHandler::BuildSmsSbSubmit");
       
  2831 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_BUILDSMSSBSUBMIT, "CMmSmsMessHandler::BuildSmsSbSubmit" );
       
  2832 
       
  2833     // Extract needed parameters from TPDU for for SMS_SB_SUBMIT
       
  2834     TUint8 messageParameters( aMsgData[ KTpduIndexMessageParameters ] );
       
  2835     TUint8 messageReference( aMsgData[ KTpduIndexMessageReference ] );
       
  2836     TUint8 protocolId( aMsgData[ KTpduSubmitIndexProtocolIdentifier +
       
  2837         aDestAddressLength ] );
       
  2838     TUint8 dataCodingScheme( aMsgData[ KTpduSubmitIndexDataCodingScheme +
       
  2839         aDestAddressLength ] );
       
  2840 
       
  2841     // Create and fill SMS_SB_SUBMIT subblock
       
  2842     TBuf8<SIZE_SMS_SB_SUBMIT> submitBuf;
       
  2843     TIsiSubBlock submit( submitBuf, SMS_SB_SUBMIT, EIsiSubBlockTypeId16Len16 );
       
  2844     submitBuf.Append( messageParameters );
       
  2845     submitBuf.Append( messageReference );
       
  2846     submitBuf.Append( protocolId );
       
  2847     submitBuf.Append( dataCodingScheme );
       
  2848 
       
  2849     aIsiMsg.CopyData( aMsgOffset, submit.CompleteSubBlock() );
       
  2850 
       
  2851 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbSubmit. Message parameters: %d", messageParameters );
       
  2852 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbSubmit. Message reference: %d", messageReference );
       
  2853 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbSubmit. Protocol ID: %d", protocolId );
       
  2854 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbSubmit. Data coding scheme: %d", dataCodingScheme );
       
  2855 OstTraceExt4( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_BUILDSMSSBSUBMIT, "CMmSmsMessHandler::BuildSmsSbSubmit;messageParameters=%hhu;messageReference=%hhu;protocolId=%hhu;dataCodingScheme=%hhu", messageParameters, messageReference, protocolId, dataCodingScheme );
       
  2856     }
       
  2857 
       
  2858 
       
  2859 // -----------------------------------------------------------------------------
       
  2860 // Creates SMS_SB_COMMAND subblock and appends it to ISI message
       
  2861 // -----------------------------------------------------------------------------
       
  2862 void CMmSmsMessHandler::BuildSmsSbCommand(
       
  2863     const TDesC8& aMsgData,
       
  2864     TIsiSend& aIsiMsg,
       
  2865     TUint8 aMsgOffset ) const
       
  2866     {
       
  2867 TFLOGSTRING("TSY:CMmSmsMessHandler::BuildSmsSbCommand");
       
  2868 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_BUILDSMSSBCOMMAND, "CMmSmsMessHandler::BuildSmsSbCommand" );
       
  2869 
       
  2870     // Extract needed parameters from TPDU for SMS_SB_COMMAND
       
  2871     TUint8 messageParameters( aMsgData[ KTpduIndexMessageParameters ] );
       
  2872     TUint8 messageReference( aMsgData[ KTpduIndexMessageReference ] );
       
  2873     TUint8 protocolId( aMsgData[ KTpduCommandIndexProtocolIdentifier ] );
       
  2874     TUint8 commandType( aMsgData[ KTpduCommandIndexType ] );
       
  2875     TUint8 messageNumber( aMsgData[ KTpduCommandIndexMessageNumber ] );
       
  2876 
       
  2877     // Create and fill SMS_SB_COMMAND subblock
       
  2878     TBuf8<SIZE_SMS_SB_COMMAND> commandBuf;
       
  2879     TIsiSubBlock command(
       
  2880         commandBuf,
       
  2881         SMS_SB_COMMAND,
       
  2882         EIsiSubBlockTypeId16Len16 );
       
  2883 
       
  2884     commandBuf.Append( messageParameters );
       
  2885     commandBuf.Append( messageReference );
       
  2886     commandBuf.Append( protocolId );
       
  2887     commandBuf.Append( commandType );
       
  2888     commandBuf.Append( messageNumber );
       
  2889 
       
  2890     aIsiMsg.CopyData( aMsgOffset, command.CompleteSubBlock() );
       
  2891 
       
  2892 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbCommand. Message parameters: %d", messageParameters );
       
  2893 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbCommand. Message reference: %d", messageReference );
       
  2894 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbCommand. Protocol ID: %d", protocolId );
       
  2895 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbCommand. Command type: %d", commandType );
       
  2896 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbCommand. Message Number: %d", messageNumber );
       
  2897 OstTraceExt5( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_BUILDSMSSBCOMMAND, "CMmSmsMessHandler::BuildSmsSbCommand;messageParameters=%hhu;messageReference=%hhu;protocolId=%hhu;commandType=%hhu;messageNumber=%hhu", messageParameters, messageReference, protocolId, commandType, messageNumber );
       
  2898     }
       
  2899 
       
  2900 
       
  2901 // -----------------------------------------------------------------------------
       
  2902 // Creates SMS_SB_ADDRESS subblock and appends it to ISI message
       
  2903 // -----------------------------------------------------------------------------
       
  2904 TUint8 CMmSmsMessHandler::BuildSmsSbAddress(
       
  2905     const TDesC8& aAddress,
       
  2906     TIsiSend& aIsiMsg,
       
  2907     TUint8 aAddressType,
       
  2908     TUint8 aMsgOffset ) const
       
  2909     {
       
  2910 TFLOGSTRING("TSY:CMmSmsMessHandler::BuildSmsSbAddress");
       
  2911 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_BUILDSMSSBADDRESS, "CMmSmsMessHandler::BuildSmsSbAddress" );
       
  2912 
       
  2913     TUint8 addressLength( aAddress.Length() );
       
  2914     TUint8 subblockLength( 0 );
       
  2915     // Create and fill SMS_SB_ADDRESS subblock
       
  2916     TBuf8<SIZE_SMS_SB_ADDRESS + SMS_ADDRESS_MAX_LEN> addressBuf( 0 );
       
  2917     TIsiSubBlock address(
       
  2918         addressBuf,
       
  2919         SMS_SB_ADDRESS,
       
  2920         EIsiSubBlockTypeId16Len16 );
       
  2921     addressBuf.Append( aAddressType  );
       
  2922     addressBuf.Append( addressLength );
       
  2923     addressBuf.Append( aAddress );
       
  2924 
       
  2925     aIsiMsg.CopyData( aMsgOffset, address.CompleteSubBlock() );
       
  2926 
       
  2927     // Subblock length is needed for return value
       
  2928     subblockLength = addressBuf.Length();
       
  2929 
       
  2930 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbAddress. Address type: %d", aAddressType );
       
  2931 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbAddress. Address length: %d", addressLength );
       
  2932 OstTraceExt2( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_BUILDSMSSBADDRESS, "CMmSmsMessHandler::BuildSmsSbAddress;aAddressType=%hhu;addressLength=%hhu", aAddressType, addressLength );
       
  2933 #ifdef _DEBUG
       
  2934 for ( TInt i( 0 ); i < aAddress.Length(); i++ )
       
  2935     {
       
  2936 TFLOGSTRING3( "TSY:CMmSmsMessHandler::BuildSmsSbAddress. Address data[%d]: 0x%x", i, aAddress[i] );
       
  2937 OstTraceExt2( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_BUILDSMSSBADDRESS, "CMmSmsMessHandler::BuildSmsSbAddress;i=%hhu;aAddress[i]=%hhu", i, aAddress[i] );
       
  2938     }
       
  2939 #endif // _DEBUG
       
  2940 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbAddress. Length of subblock: %d", subblockLength );
       
  2941 OstTraceExt1( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_BUILDSMSSBADDRESS, "CMmSmsMessHandler::BuildSmsSbAddress;subblockLength=%hhu", subblockLength );
       
  2942 
       
  2943     return subblockLength;
       
  2944     }
       
  2945 
       
  2946 
       
  2947 // -----------------------------------------------------------------------------
       
  2948 // Creates SMS_SB_USER_DATA subblock and appends it to ISI message
       
  2949 // -----------------------------------------------------------------------------
       
  2950 TUint8 CMmSmsMessHandler::BuildSmsSbUserData(
       
  2951     const TDesC8& aMsgData,
       
  2952     TIsiSend& aIsiMsg,
       
  2953     TUint8 aTpUdl,
       
  2954     TUint8 aTpUserDataIndex,
       
  2955     TBool aDefaultAlphabet,
       
  2956     TUint8 aMsgOffset ) const
       
  2957     {
       
  2958 TFLOGSTRING("TSY:CMmSmsMessHandler::BuildSmsSbUserData");
       
  2959 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_BUILDSMSSBUSERDATA, "CMmSmsMessHandler::BuildSmsSbUserData" );
       
  2960 
       
  2961     TUint8 dataLengthInOctets( 0 );
       
  2962 
       
  2963     // If data is 7-bit, then TP-UDL is integer representation of
       
  2964     // the number of septets within the TP-UD field
       
  2965     if ( aDefaultAlphabet )
       
  2966         {
       
  2967         dataLengthInOctets = ( ( aTpUdl + 1 ) * 7 ) / 8;
       
  2968         }
       
  2969     else
       
  2970         {
       
  2971         dataLengthInOctets = aTpUdl;
       
  2972         }
       
  2973 
       
  2974     // Extract actual data bytes from TPDU
       
  2975     TPtrC8 dataBytes( aMsgData.Mid( aTpUserDataIndex, dataLengthInOctets ) );
       
  2976 
       
  2977     // Create and fill SMS_SB_USER_DATA subblock
       
  2978     TBuf8<SIZE_SMS_SB_USER_DATA + SMS_COMMAND_DATA_MAX_LEN> userDataBuf;
       
  2979     TIsiSubBlock userData(
       
  2980         userDataBuf,
       
  2981         SMS_SB_USER_DATA,
       
  2982         EIsiSubBlockTypeId16Len16 );
       
  2983     userDataBuf.Append( KSmsPadding  );
       
  2984     userDataBuf.Append( dataLengthInOctets );
       
  2985     userDataBuf.Append( KSmsPadding  );
       
  2986     userDataBuf.Append( aTpUdl  );
       
  2987     userDataBuf.Append( dataBytes );
       
  2988 
       
  2989     aIsiMsg.CopyData( aMsgOffset, userData.CompleteSubBlock() );
       
  2990 
       
  2991 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbUserData. User data length in octets: %d", dataLengthInOctets );
       
  2992 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbUserData. User data character count: %d", aTpUdl );
       
  2993 OstTraceExt2( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_BUILDSMSSBUSERDATA, "CMmSmsMessHandler::BuildSmsSbUserData;dataLengthInOctets=%hhu;aTpUdl=%hhu", dataLengthInOctets, aTpUdl );
       
  2994 
       
  2995     return dataLengthInOctets + 8; // 8 bytes sub block header data before data bytes
       
  2996     }
       
  2997 
       
  2998 
       
  2999 // -----------------------------------------------------------------------------
       
  3000 // Creates SMS_SB_VALIDITY_PERIOD subblock and appends it to ISI message
       
  3001 // -----------------------------------------------------------------------------
       
  3002 void CMmSmsMessHandler::BuildSmsSbValidityPeriod(
       
  3003     const TDesC8& aMsgData,
       
  3004     TIsiSend& aIsiMsg,
       
  3005     TUint8 aTpVpIndex,
       
  3006     TUint8 aTpVpLength,
       
  3007     TUint8 aMsgOffset ) const
       
  3008     {
       
  3009 TFLOGSTRING("TSY:CMmSmsMessHandler::BuildSmsSbValidityPeriod");
       
  3010 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_BUILDSMSSBVALIDITYPERIOD, "CMmSmsMessHandler::BuildSmsSbValidityPeriod" );
       
  3011 
       
  3012     // Extract validity period data bytes
       
  3013     TPtrC8 tpVpData( aMsgData.Mid( aTpVpIndex, aTpVpLength ) );
       
  3014 
       
  3015     // Create and fill SMS_SB_VALIDITY_PERIOD subblock, max length is 12
       
  3016     TBuf8<12> validityPeriodBuf;
       
  3017     TIsiSubBlock validityPeriod(
       
  3018         validityPeriodBuf,
       
  3019         SMS_SB_VALIDITY_PERIOD,
       
  3020         EIsiSubBlockTypeId16Len16 );
       
  3021     validityPeriodBuf.Append( aTpVpLength );
       
  3022     validityPeriodBuf.Append( tpVpData );
       
  3023 
       
  3024     aIsiMsg.CopyData( aMsgOffset, validityPeriod.CompleteSubBlock() );
       
  3025 
       
  3026 TFLOGSTRING2( "TSY:CMmSmsMessHandler::BuildSmsSbValidityPeriod. Validity period length: %d", aTpVpLength );
       
  3027 OstTraceExt1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_BUILDSMSSBVALIDITYPERIOD, "CMmSmsMessHandler::BuildSmsSbValidityPeriod;aTpVpLength=%hhu", aTpVpLength );
       
  3028 
       
  3029 #ifdef _DEBUG
       
  3030 for ( TInt i( 0 ); i < aTpVpLength; i++ )
       
  3031     {
       
  3032 TFLOGSTRING3( "Validity period, byte[%d], 0x%x", i, tpVpData[i] );
       
  3033 OstTraceExt2( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_BUILDSMSSBVALIDITYPERIOD, "CMmSmsMessHandler::BuildSmsSbValidityPeriod;i=%hhu;tpVpData[i]=%hhu", i, tpVpData[i] );
       
  3034     }
       
  3035 #endif // _DEBUG
       
  3036     }
       
  3037 
       
  3038 // -----------------------------------------------------------------------------
       
  3039 // Creates SMS_SB_CHECK_INFO sub block with SMS_CHECK_DISABLE_FDN and appends it
       
  3040 // to ISI message.
       
  3041 // -----------------------------------------------------------------------------
       
  3042 void CMmSmsMessHandler::BuildSmsCheckInfo(
       
  3043     TIsiSend& aIsiMsg,
       
  3044     TUint8 aMsgOffset ) const
       
  3045     {
       
  3046 TFLOGSTRING("TSY:CMmSmsMessHandler::BuildSmsCheckInfo");
       
  3047 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_BUILDSMSCHECKINFO, "CMmSmsMessHandler::BuildSmsCheckInfo" );
       
  3048 
       
  3049     // Create and fill SMS_SB_CHECK_INFO subblock.
       
  3050     TBuf8<SIZE_SMS_SB_CHECK_INFO> checkInfoBuf;
       
  3051     TIsiSubBlock checkInfo(
       
  3052         checkInfoBuf,
       
  3053         SMS_SB_CHECK_INFO,
       
  3054         EIsiSubBlockTypeId16Len16 );
       
  3055     checkInfoBuf.Append( SMS_CHECK_DISABLE_FDN );
       
  3056     checkInfoBuf.Append( KSmsPadding );
       
  3057     checkInfoBuf.Append( KSmsPadding );
       
  3058     checkInfoBuf.Append( KSmsPadding );
       
  3059 
       
  3060     aIsiMsg.CopyData( aMsgOffset, checkInfo.CompleteSubBlock() );
       
  3061 
       
  3062     }
       
  3063 
       
  3064 // -----------------------------------------------------------------------------
       
  3065 // CMmSmsMessHandler::ProcessUiccMsg
       
  3066 // Handles data received from UICC server
       
  3067 // -----------------------------------------------------------------------------
       
  3068 //
       
  3069 TInt CMmSmsMessHandler::ProcessUiccMsg(
       
  3070     TInt aTraId,
       
  3071     TInt aStatus,
       
  3072     const TDesC8& aFileData )
       
  3073     {
       
  3074 TFLOGSTRING3("TSY:CMmSmsMessHandler::ProcessUiccMsg, aTraId: %d, status: %d", aTraId, aStatus );
       
  3075 OstTrace1( TRACE_NORMAL, CMMSMSMESSHANDLER_PROCESSUICCMSG, "CMmSmsMessHandler::ProcessUiccMsg;aTraId=%d", aTraId );
       
  3076 OstTrace1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_PROCESSUICCMSG, "CMmSmsMessHandler::ProcessUiccMsg;aStatus=%d", aStatus );
       
  3077 
       
  3078     TInt ret( KErrNone );
       
  3079 
       
  3080     switch( aTraId )
       
  3081         {
       
  3082         case ETrIdReadSMS:
       
  3083             {
       
  3084             UiccReadSMSResp( aStatus, aFileData );
       
  3085             break;
       
  3086             }
       
  3087         case ETrIdReadSMSForComplete:
       
  3088             {
       
  3089             UiccReadSMSRespForComplete( aStatus, aFileData );
       
  3090             break;
       
  3091             }
       
  3092         case ETrIdWriteSMS:
       
  3093             {
       
  3094             UiccWriteSMSResp( aStatus );
       
  3095             break;
       
  3096             }
       
  3097         case ETrIdReadSMSRecordCount:
       
  3098             {
       
  3099             GetNumOfEFSMSRecordsResp( aStatus, aFileData );
       
  3100             break;
       
  3101             }
       
  3102         default:
       
  3103             {
       
  3104 TFLOGSTRING("TSY:CMmSmsMessHandler::ProcessUiccMsg - unknown transaction ID" );
       
  3105 OstTrace0( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_PROCESSUICCMSG, "CMmSmsMessHandler::ProcessUiccMsg - unknown transaction ID" );
       
  3106 
       
  3107             break;
       
  3108             }
       
  3109         }
       
  3110     return ret;
       
  3111     }
       
  3112 
       
  3113 // -----------------------------------------------------------------------------
       
  3114 // CMmSmsMessHandler::UiccReadSMSOrSMSRecordCountReq
       
  3115 // Read SMS or SMS EF record count from SIM/USIM
       
  3116 // -----------------------------------------------------------------------------
       
  3117 //
       
  3118 TInt CMmSmsMessHandler::UiccReadSMSOrSMSRecordCountReq(
       
  3119     const TUint8 aRecordId,
       
  3120     const TUiccTrId aTrId )
       
  3121     {
       
  3122 TFLOGSTRING3("TSY: CMmSmsMessHandler::UiccReadSMSReq, aTraId: %d, aRecordId: %d", aTrId, aRecordId );
       
  3123 OstTraceExt2( TRACE_NORMAL, CMMSMSMESSHANDLER_UICCREADSMSORSMSRECORDCOUNTREQ, "CMmSmsMessHandler::UiccReadSMSOrSMSRecordCountReq;aTrId=%hhu;aRecordId=%hhu", aTrId, aRecordId );
       
  3124 
       
  3125     TUint8 serviceType( 0 );
       
  3126     TInt ret( KErrNone );
       
  3127 
       
  3128     switch( aTrId )
       
  3129         {
       
  3130         case ETrIdReadSMS:
       
  3131         case ETrIdReadSMSForComplete:
       
  3132             {
       
  3133             // Save record id for next request
       
  3134             iRecordId = aRecordId;
       
  3135             serviceType = UICC_APPL_READ_LINEAR_FIXED;
       
  3136             break;
       
  3137             }
       
  3138         case ETrIdReadSMSRecordCount:
       
  3139             {
       
  3140             serviceType = UICC_APPL_FILE_INFO;
       
  3141             break;
       
  3142             }
       
  3143         default:
       
  3144             {
       
  3145 TFLOGSTRING("TSY: CMmSmsMessHandler::UiccReadSMSReq - unknown transaction ID" );
       
  3146 OstTrace0( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_UICCREADSMSORSMSRECORDCOUNTREQ, "CMmSmsMessHandler::UiccReadSMSOrSMSRecordCountReq - unknown transaction ID" );
       
  3147             ret = KErrUnknown;
       
  3148             break;
       
  3149             }
       
  3150         }
       
  3151 
       
  3152     // Set parameters for UICC_APPL_CMD_REQ message
       
  3153     TUiccReadLinearFixed params;
       
  3154     params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
       
  3155     params.trId = aTrId;
       
  3156     params.dataOffset = 0;
       
  3157     params.dataAmount = 0;
       
  3158     params.record = aRecordId;
       
  3159 
       
  3160     params.fileId = KElemFileShortMessages;
       
  3161     params.fileIdSfi = UICC_SFI_NOT_PRESENT;
       
  3162     params.serviceType = serviceType;
       
  3163 
       
  3164     // File id path
       
  3165     params.filePath.Append( KMasterFileId >> 8 );
       
  3166     params.filePath.Append( KMasterFileId );
       
  3167     params.filePath.Append( iMmUiccMessHandler->GetApplicationFileId() );
       
  3168 
       
  3169     if ( KErrNone == ret )
       
  3170         {
       
  3171         ret = iMmUiccMessHandler->CreateUiccApplCmdReq( params );
       
  3172         }
       
  3173 
       
  3174     return ret;
       
  3175     }
       
  3176 
       
  3177 // -----------------------------------------------------------------------------
       
  3178 // CMmSmsMessHandler::UiccReadSMSResp
       
  3179 //
       
  3180 // -----------------------------------------------------------------------------
       
  3181 //
       
  3182 void CMmSmsMessHandler::UiccReadSMSResp(
       
  3183     TInt aStatus,
       
  3184     const TDesC8& aFileData )
       
  3185     {
       
  3186 TFLOGSTRING("TSY: CMmSmsMessHandler::UiccReadSMSResp" );
       
  3187 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_UICCREADSMSRESP, "CMmSmsMessHandler::UiccReadSMSResp" );
       
  3188 
       
  3189     if ( KErrNone == aStatus )
       
  3190         {
       
  3191 TFLOGSTRING2("TSY: CMmSmsMessHandler::SimStSmsHandleReadCacheEntriesL -- cacheing iRecordId=%d", iRecordId );
       
  3192 OstTraceExt1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_UICCREADSMSRESP, "CMmSmsMessHandler::UiccReadSMSResp;iRecordId=%hhu", iRecordId );
       
  3193 
       
  3194         if ( 0 != aFileData.Length() )
       
  3195             {
       
  3196             // add to cache
       
  3197             RMobileSmsStore::TMobileGsmSmsEntryV1 smsData;
       
  3198 
       
  3199             TUint8 position( 0 );
       
  3200             smsData.iMsgStatus =
       
  3201                 static_cast <RMobileSmsStore::TMobileSmsStoreStatus>(
       
  3202                     aFileData[position] );
       
  3203 
       
  3204             TBuf<KMaxAddressBufferSize> receivedMsgServiceCentre;
       
  3205             RMobilePhone::TMobileTON receivedMsgMobileScTON(
       
  3206                 RMobilePhone::EUnknownNumber );
       
  3207             RMobilePhone::TMobileNPI receivedMsgMobileScNPI(
       
  3208                 RMobilePhone::EUnknownNumberingPlan );
       
  3209 
       
  3210             position++;
       
  3211             TUint8 addressDataLength( aFileData[position] );
       
  3212             position++;
       
  3213             TPtrC8 scA( aFileData.Mid( position, addressDataLength ) );
       
  3214             CMmSmsGsmAddress::GsmConv0411AddrToUnicode(
       
  3215                 receivedMsgServiceCentre,
       
  3216                 scA,
       
  3217                 receivedMsgMobileScTON,
       
  3218                 receivedMsgMobileScNPI );
       
  3219 
       
  3220             smsData.iServiceCentre.iTypeOfNumber = receivedMsgMobileScTON;
       
  3221             smsData.iServiceCentre.iNumberPlan = receivedMsgMobileScNPI;
       
  3222             smsData.iServiceCentre.iTelNumber = receivedMsgServiceCentre;
       
  3223 
       
  3224             position += addressDataLength; // Start of the TPDU
       
  3225             TUint8 totalLength( aFileData.Length() ); // Total aFileData length
       
  3226             TUint8 tpduLength( totalLength - position );
       
  3227             smsData.iMsgData = aFileData.Mid( position, tpduLength  );
       
  3228 
       
  3229             iSmsCache.AddEntryL( &smsData, iRecordId );
       
  3230             }
       
  3231 
       
  3232         // if the cache is not ready, try reading the next entry
       
  3233         if ( iRecordId < iSmsCache.TotalEntries() )
       
  3234             {
       
  3235             iRecordId++; // Next record
       
  3236             UiccReadSMSOrSMSRecordCountReq( iRecordId, ETrIdReadSMS );
       
  3237             }
       
  3238         // or else this is the last entry, mark cache as ready
       
  3239         else
       
  3240             {
       
  3241             iSmsCache.SetStatus( KErrNone );
       
  3242             }
       
  3243         }
       
  3244     else
       
  3245         {
       
  3246 TFLOGSTRING("TSY: CMmSmsMessHandler::UiccReadSMSResp - abort caching");
       
  3247 OstTrace0( TRACE_NORMAL, DUP2_CMMSMSMESSHANDLER_UICCREADSMSRESP, "CMmSmsMessHandler::UiccReadSMSResp - abort caching" );
       
  3248         // else SIM suddenly removed ==> abort caching
       
  3249         // or example SIM rejected (EFSA-6ZQ9K3).
       
  3250 
       
  3251         // SMS is on SIM, but we couldn't read it. Cache must be
       
  3252         // invalidated
       
  3253         iSmsCache.Reset();
       
  3254         // use KErrNoMemory as error condition, so that getinfo will try
       
  3255         // to fill cache again
       
  3256         iSmsCache.SetStatus( KErrNoMemory );
       
  3257         }
       
  3258 
       
  3259     // either done or failed
       
  3260     if ( KErrNotReady != iSmsCache.Status() )
       
  3261         {
       
  3262 TFLOGSTRING2("TSY: CMmSmsMessHandler::UiccReadSMSResp - Success or Error value of SMS cache read = %d",iSmsCache.Status() );
       
  3263 OstTrace1( TRACE_NORMAL, DUP3_CMMSMSMESSHANDLER_UICCREADSMSRESP, "CMmSmsMessHandler::UiccReadSMSResp;iSmsCache.Status()=%d", iSmsCache.Status() );
       
  3264 
       
  3265 TFLOGSTRING3("TSY: CMmSmsMessHandler::UiccReadSMSResp --- SMS CACHE READ DONE --- total=%d used=%d",iSmsCache.TotalEntries(), iSmsCache.UsedEntries() );
       
  3266 OstTrace1( TRACE_NORMAL, DUP4_CMMSMSMESSHANDLER_UICCREADSMSRESP, "CMmSmsMessHandler::UiccReadSMSResp;iSmsCache.TotalEntries()=%d", iSmsCache.TotalEntries() );
       
  3267 
       
  3268         // there is a chance that EMobileSmsMessagingGetMessageStoreInfo
       
  3269         // request is already on if so, then complete it here... if there is
       
  3270         // no request on, then this is harmless..
       
  3271         TUint8 numOfLoc( TUint8( iSmsCache.TotalEntries() ) );
       
  3272         TInt usedEntries( iSmsCache.UsedEntries() );
       
  3273 
       
  3274         //create package
       
  3275         CMmDataPackage data;
       
  3276         data.PackData( &numOfLoc, &usedEntries );
       
  3277         iSmsSlotLocation = 0;
       
  3278 
       
  3279         iMessageRouter->Complete(
       
  3280             EMobileSmsMessagingGetMessageStoreInfo,
       
  3281             &data,
       
  3282             iSmsCache.Status() );
       
  3283 
       
  3284         iMessageRouter->Complete(
       
  3285             EMobilePhoneStoreGetInfo,
       
  3286             &data,
       
  3287             iSmsCache.Status() );
       
  3288 
       
  3289         // it is possible that re-caching was done due to sim refresh.
       
  3290 //        iMessageRouter->GetPhoneMessHandler()->
       
  3291 //            SmsCachingCompleted( iSmsCache.Status() );
       
  3292 
       
  3293         // if cache is up and a message was received while cacheing then resume
       
  3294         if ( KErrNone == iSmsCache.Status() && iReceivedClass2ToBeReSent )
       
  3295             {
       
  3296 TFLOGSTRING("TSY: CMmSmsMessHandler::UiccReadSMSResp -- resume SMS reception");
       
  3297 OstTrace0( TRACE_NORMAL, DUP5_CMMSMSMESSHANDLER_UICCREADSMSRESP, "CMmSmsMessHandler::UiccReadSMSResp -- resume SMS reception" );
       
  3298             SmsReceiveMessageReq( SMS_RECEPTION_STORAGE_STATUS_UPDATE );
       
  3299             iReceivedClass2ToBeReSent = EFalse;
       
  3300             }
       
  3301         }
       
  3302     }
       
  3303 
       
  3304 // -----------------------------------------------------------------------------
       
  3305 // CMmSmsMessHandler::UiccReadSMSRespForComplete
       
  3306 //
       
  3307 // -----------------------------------------------------------------------------
       
  3308 //
       
  3309 void CMmSmsMessHandler::UiccReadSMSRespForComplete(
       
  3310     TInt aStatus,
       
  3311     const TDesC8& aFileData )
       
  3312     {
       
  3313 TFLOGSTRING("TSY: CMmSmsMessHandler::UiccReadSMSRespForComplete" );
       
  3314 //OstTraceExt2( TRACE_NORMAL, CMMSMSMESSHANDLER_UICCREADSMSRESP, "CMmSmsMessHandler::UiccReadSMSResp;aStatus=%d;aFileData=%s", aStatus,aFileData );
       
  3315 
       
  3316 
       
  3317     if ( KErrNone == aStatus )
       
  3318         {
       
  3319 TFLOGSTRING2("TSY: CMmSmsMessHandler::UiccReadSMSRespForComplete -- cacheing iRecordId=%d", iRecordId );
       
  3320 OstTraceExt1( TRACE_NORMAL, CMMSMSMESSHANDLER_UICCREADSMSRESPFORCOMPLETE, "CMmSmsMessHandler::UiccReadSMSRespForComplete;iRecordId=%hhu", iRecordId );
       
  3321 
       
  3322         if ( 0 != aFileData.Length() )
       
  3323             {
       
  3324             // add to cache
       
  3325             RMobileSmsStore::TMobileGsmSmsEntryV1 smsData;
       
  3326 
       
  3327             TUint8 position( 0 );
       
  3328             // Force status as message to be read
       
  3329             smsData.iMsgStatus =
       
  3330                 static_cast <RMobileSmsStore::TMobileSmsStoreStatus>(
       
  3331                     aFileData[position] );
       
  3332 
       
  3333             TBuf<KMaxAddressBufferSize> receivedMsgServiceCentre;
       
  3334             RMobilePhone::TMobileTON receivedMsgMobileScTON(
       
  3335                 RMobilePhone::EUnknownNumber );
       
  3336             RMobilePhone::TMobileNPI receivedMsgMobileScNPI(
       
  3337                 RMobilePhone::EUnknownNumberingPlan );
       
  3338 
       
  3339             position++;
       
  3340             TUint8 addressDataLength( aFileData[position] );
       
  3341             position++;
       
  3342             TPtrC8 scA( aFileData.Mid( position, addressDataLength ) );
       
  3343             CMmSmsGsmAddress::GsmConv0411AddrToUnicode(
       
  3344                 receivedMsgServiceCentre,
       
  3345                 scA,
       
  3346                 receivedMsgMobileScTON,
       
  3347                 receivedMsgMobileScNPI );
       
  3348 
       
  3349             smsData.iServiceCentre.iTypeOfNumber = receivedMsgMobileScTON;
       
  3350             smsData.iServiceCentre.iNumberPlan = receivedMsgMobileScNPI;
       
  3351             smsData.iServiceCentre.iTelNumber = receivedMsgServiceCentre;
       
  3352 
       
  3353             position += addressDataLength; // Start of the TPDU
       
  3354             TUint8 totalLength( aFileData.Length() ); // Total aFileData length
       
  3355             TUint8 tpduLength( totalLength - position );
       
  3356             smsData.iMsgData = aFileData.Mid( position, tpduLength  );
       
  3357 
       
  3358             // This is done only when SMS written through ETel.
       
  3359             if ( !iSMSClass2Write )
       
  3360                 {
       
  3361                 //create package
       
  3362                 CMmDataPackage data;
       
  3363                 data.PackData( &iSmsSlotLocation, &iReceivedClass2ToBeReSent );
       
  3364                 iSmsSlotLocation = 0;
       
  3365                 iMessageRouter->Complete(
       
  3366                     EMobilePhoneStoreWrite,
       
  3367                     &data,
       
  3368                     KErrNone );
       
  3369 
       
  3370                 iReceivedClass2ToBeReSent = EFalse;
       
  3371                 }
       
  3372             else
       
  3373                 {
       
  3374                 // This is done only when received class 2 message has been handled.
       
  3375                 TSmsMsg smsMsg;
       
  3376                 smsMsg.iLocation = iSmsSlotLocation;
       
  3377                 smsMsg.iMessageStatus = smsData.iMsgStatus;
       
  3378                 smsMsg.iMobileScNPI = smsData.iServiceCentre.iNumberPlan;
       
  3379                 smsMsg.iMobileScTON = smsData.iServiceCentre.iTypeOfNumber;
       
  3380                 smsMsg.iServiceCentre = smsData.iServiceCentre.iTelNumber;
       
  3381                 smsMsg.iSmsClass2 = ETrue;
       
  3382                 smsMsg.iSmsMsg = smsData.iMsgData;
       
  3383 
       
  3384                 iSmsSlotLocation = 0;
       
  3385 
       
  3386                 //Complete request to client
       
  3387                 TBool smsInd( ETrue );
       
  3388                 TSmsMsg* smsMsgPtr = &smsMsg;
       
  3389 
       
  3390                 //create package
       
  3391                 CMmDataPackage data;
       
  3392                 data.PackData( &smsInd, &smsMsgPtr );
       
  3393                 iMessageRouter->Complete(
       
  3394                     EMobileSmsMessagingReceiveMessage,
       
  3395                     &data,
       
  3396                     KErrNone );
       
  3397                 }
       
  3398             // At this point sms is safely in SIM and request is completed
       
  3399             // Add to cache may fail, in which case we just invalidate
       
  3400             // cache in out of memory handler
       
  3401 
       
  3402             iSmsCache.AddEntryL( &smsData, iRecordId );
       
  3403             }
       
  3404 
       
  3405         }
       
  3406     else
       
  3407         {
       
  3408         // This is done only when received class 2 message has been handled.
       
  3409         if ( iSMSClass2Write )
       
  3410             {
       
  3411             TInt ret ( SmsReceivedMsgReportReq(
       
  3412                 ESmsMessagingAckSmsStored,
       
  3413                 NULL,
       
  3414                 KErrNone ) );
       
  3415 
       
  3416             if ( KErrNone != ret )
       
  3417                 {
       
  3418                 TBool smsInd( EFalse );
       
  3419                 TSmsMsg* nullSms = NULL;
       
  3420 
       
  3421                 //create package
       
  3422                 CMmDataPackage data;
       
  3423                 //Complete request to client
       
  3424                 data.PackData( &smsInd, &nullSms );
       
  3425                 iSmsSlotLocation = 0;
       
  3426 
       
  3427                 // ISI message construction failed or phonet sender
       
  3428                 // returned error
       
  3429                 iMessageRouter->Complete(
       
  3430                     EMobileSmsMessagingReceiveMessage,
       
  3431                     &data,
       
  3432                     KErrGeneral );
       
  3433                 }
       
  3434             }
       
  3435         else
       
  3436             {
       
  3437             //create package
       
  3438             CMmDataPackage data;
       
  3439             data.PackData( &iSmsSlotLocation, &iReceivedClass2ToBeReSent );
       
  3440             iSmsSlotLocation = 0;
       
  3441             iMessageRouter->Complete(
       
  3442                 EMobilePhoneStoreWrite,
       
  3443                 &data,
       
  3444                 CMmStaticUtility::UICCCSCauseToEpocError( aStatus ) );
       
  3445             }
       
  3446         // SMS is on SIM, but we couldn't read it. Cache must be
       
  3447         // invalidated
       
  3448         iSmsCache.Reset();
       
  3449         // use KErrNoMemory as error condition, so that getinfo will try
       
  3450         // to fill cache again
       
  3451         iSmsCache.SetStatus( KErrNoMemory );
       
  3452         }
       
  3453 
       
  3454     iSMSClass2Write = EFalse;
       
  3455     }
       
  3456 
       
  3457 // -----------------------------------------------------------------------------
       
  3458 // CMmSmsMessHandler::UiccWriteSMSReq
       
  3459 // Write SMS to SIM
       
  3460 // -----------------------------------------------------------------------------
       
  3461 //
       
  3462 TInt CMmSmsMessHandler::UiccWriteSMSReq(
       
  3463     const RMobileSmsStore::TMobileGsmSmsEntryV1& aEntry,
       
  3464     const TUint8 aRecordId
       
  3465     )
       
  3466     {
       
  3467 TFLOGSTRING2("TSY: CMmSmsMessHandler::UiccWriteSMSReq aRecordId: %d", aRecordId );
       
  3468 OstTraceExt1( TRACE_NORMAL, CMMSMSMESSHANDLER_UICCWRITESMSREQ, "CMmSmsMessHandler::UiccWriteSMSReq;aRecordId=%hhu", aRecordId );
       
  3469 
       
  3470     // Set parameters for UICC_APPL_CMD_REQ message
       
  3471     TUiccWriteLinearFixed params;
       
  3472     params.messHandlerPtr = static_cast<MUiccOperationBase*>( this );
       
  3473     params.trId = ETrIdWriteSMS;
       
  3474     params.dataOffset = 0;
       
  3475     params.dataAmount = 0;
       
  3476     params.record = aRecordId;
       
  3477 
       
  3478     params.fileId = KElemFileShortMessages;
       
  3479     params.fileIdSfi = UICC_SFI_NOT_PRESENT;
       
  3480     params.serviceType = UICC_APPL_UPDATE_LINEAR_FIXED;
       
  3481 
       
  3482     // File id path
       
  3483     params.filePath.Append( KMasterFileId >> 8 );
       
  3484     params.filePath.Append( KMasterFileId );
       
  3485     params.filePath.Append( iMmUiccMessHandler->GetApplicationFileId() );
       
  3486 
       
  3487     // File data to be updated.
       
  3488     TBuf8<KSmsElemetaryFileRecordLength> fileDataBuf;
       
  3489 
       
  3490     // Fill record. See ETSI TS 31 102 "4.2.25   EFSMS (Short messages)"
       
  3491 
       
  3492     TUint8 totalDataLength( 0 );
       
  3493     fileDataBuf.Append( KSimSmsMtNotRead );
       
  3494     totalDataLength++;
       
  3495 
       
  3496     //build Gsm 04.11 type of address structure
       
  3497     TBuf8<KMaxAddressBufferSize>  scAddress;
       
  3498     TPtrC16 telNumber( aEntry.iServiceCentre.iTelNumber );
       
  3499     CMmSmsGsmAddress::GsmConvUnicodeTo0411Addr(
       
  3500         aEntry.iServiceCentre.iTypeOfNumber,
       
  3501         aEntry.iServiceCentre.iNumberPlan,
       
  3502         scAddress,
       
  3503         telNumber );
       
  3504 
       
  3505     // addressDataLength
       
  3506     fileDataBuf.Append( scAddress.Length() );
       
  3507     totalDataLength++;
       
  3508 
       
  3509     fileDataBuf.Append( scAddress );
       
  3510 
       
  3511     // It is possible for a TS Service Centre Address of maximum permitted
       
  3512     // length, e.g. containing more than 18 address digits, to be associated
       
  3513     // with a maximum length TPDU such that their combined length is 176 bytes.
       
  3514     // In this case the ME shall store in the USIM the TS Service Centre
       
  3515     // Address and the TPDU in bytes 2 176 without modification, except for the
       
  3516     // last byte of the TPDU, which shall not be stored.
       
  3517 
       
  3518     RMobileSmsMessaging::TMobileSmsGsmTpdu msgData( aEntry.iMsgData );
       
  3519 
       
  3520     totalDataLength += ( msgData.Length() + scAddress.Length() );
       
  3521 
       
  3522     TUint msgDataLen( msgData.Length() );
       
  3523     TInt unfilledLength( fileDataBuf.MaxLength() - totalDataLength );
       
  3524 
       
  3525     if ( 0 >  unfilledLength )
       
  3526         {
       
  3527         msgDataLen--;
       
  3528         }
       
  3529     fileDataBuf.Append( msgData.Left( msgDataLen ) );
       
  3530 
       
  3531     // Fill unused fields with FF
       
  3532     if ( 0 <  unfilledLength )
       
  3533         {
       
  3534         fileDataBuf.AppendFill( 0xFF, unfilledLength );
       
  3535         }
       
  3536 
       
  3537     params.fileData.Append( fileDataBuf );
       
  3538 
       
  3539     return iMmUiccMessHandler->CreateUiccApplCmdReq( params );
       
  3540     }
       
  3541 
       
  3542 
       
  3543 // -----------------------------------------------------------------------------
       
  3544 // CMmSmsMessHandler::UiccWriteSMSResp
       
  3545 //
       
  3546 // -----------------------------------------------------------------------------
       
  3547 //
       
  3548 void CMmSmsMessHandler::UiccWriteSMSResp( TInt aStatus )
       
  3549     {
       
  3550 TFLOGSTRING2("TSY: CMmSmsMessHandler::UiccWriteSMSResp aStatus: %d", aStatus );
       
  3551 OstTrace1( TRACE_NORMAL, CMMSMSMESSHANDLER_UICCWRITESMSRESP, "CMmSmsMessHandler::UiccWriteSMSResp;aStatus=%d", aStatus );
       
  3552 
       
  3553     // Create Package
       
  3554     CMmDataPackage package;
       
  3555 
       
  3556     if ( iSMSClass2Write )
       
  3557         {
       
  3558         if ( KErrNone == aStatus )
       
  3559             {
       
  3560             // After writing class2 SMS to SIM card, it has
       
  3561             // to be read in case SIM SW has changed the contents
       
  3562             TInt ret( UiccReadSMSOrSMSRecordCountReq( iSmsSlotLocation, ETrIdReadSMSForComplete ) );
       
  3563             if ( KErrNone != ret )
       
  3564                 {
       
  3565                 ret = SmsReceivedMsgReportReq( EInternalNack, NULL, KErrGsmSMSUnspecifiedProtocolError );
       
  3566                 if ( KErrNone != ret )
       
  3567                     {
       
  3568                     TBool smsInd( EFalse );
       
  3569                     TSmsMsg* nullSms = NULL;
       
  3570                     //Complete request to client
       
  3571                     package.PackData( &smsInd, &nullSms );
       
  3572                     iSmsSlotLocation = 0;
       
  3573 
       
  3574                     // ISI message construction failed or phonet sender
       
  3575                     // returned error
       
  3576                     iMessageRouter->Complete(
       
  3577                         EMobileSmsMessagingReceiveMessage,
       
  3578                         &package,
       
  3579                         KErrGeneral );
       
  3580                     }
       
  3581                 }
       
  3582             }
       
  3583         else
       
  3584             {
       
  3585             TInt ret( SmsReceivedMsgReportReq( EInternalNack, NULL, KErrGsmSMSUnspecifiedProtocolError ) );
       
  3586             if ( KErrNone != ret )
       
  3587                 {
       
  3588                 // ISI message construction failed or phonet sender
       
  3589                 // returned error
       
  3590                 TBool smsInd( EFalse );
       
  3591                 TSmsMsg* nullSms = NULL;
       
  3592 
       
  3593                 //Pack data
       
  3594                 package.PackData( &smsInd, &nullSms );
       
  3595                 iSmsSlotLocation = 0;
       
  3596 
       
  3597                 // ISI message construction failed or phonet sender
       
  3598                 // returned error
       
  3599                 iMessageRouter->Complete(
       
  3600                     EMobileSmsMessagingReceiveMessage,
       
  3601                     &package,
       
  3602                     KErrGeneral );
       
  3603                 }
       
  3604             }
       
  3605         }
       
  3606     else
       
  3607         {
       
  3608         if ( KErrNone == aStatus )
       
  3609             {
       
  3610             // After writing class2 SMS to SIM card, it has
       
  3611             // to be read in case SIM SW has changed the contents
       
  3612             TInt ret( UiccReadSMSOrSMSRecordCountReq( iSmsSlotLocation, ETrIdReadSMSForComplete ) );
       
  3613             if ( KErrNone != ret )
       
  3614                 {
       
  3615                 package.PackData(
       
  3616                     &iSmsSlotLocation,
       
  3617                     &iReceivedClass2ToBeReSent );
       
  3618                 iSmsSlotLocation = 0;
       
  3619                 iMessageRouter->Complete(
       
  3620                     EMobilePhoneStoreWrite,
       
  3621                     &package,
       
  3622                     ret );
       
  3623                 iReceivedClass2ToBeReSent = EFalse;
       
  3624                 }
       
  3625             }
       
  3626         else
       
  3627             {
       
  3628             package.PackData( &iSmsSlotLocation, &iReceivedClass2ToBeReSent );
       
  3629             iSmsSlotLocation = 0;
       
  3630             iMessageRouter->Complete(
       
  3631                 EMobilePhoneStoreWrite,
       
  3632                 &package,
       
  3633             KErrGeneral );
       
  3634             iReceivedClass2ToBeReSent = EFalse;
       
  3635             }
       
  3636         }
       
  3637     }
       
  3638 
       
  3639 // -----------------------------------------------------------------------------
       
  3640 // CMmSmsMessHandler::SimStSmsGetNumOfLocReq
       
  3641 // Construct a SIM_ST_SMS_GET_NUM_OF_LOC_REQ ISI message
       
  3642 // to the SIM Server
       
  3643 // -----------------------------------------------------------------------------
       
  3644 //
       
  3645 void CMmSmsMessHandler::GetNumOfEFSMSRecords( void )
       
  3646     {
       
  3647 TFLOGSTRING("TSY: CMmSmsMessHandler::GetNumOfEFSMSRecords" );
       
  3648 OstTrace0( TRACE_NORMAL, CMMSMSMESSHANDLER_GETNUMOFEFSMSRECORDS, "CMmSmsMessHandler::GetNumOfEFSMSRecords" );
       
  3649 
       
  3650     TUint8 recordID( 0 );
       
  3651     TUiccTrId trId( ETrIdReadSMSRecordCount );
       
  3652 
       
  3653     CMmSmsMessHandler::UiccReadSMSOrSMSRecordCountReq ( recordID,
       
  3654                                                         trId  );
       
  3655     }
       
  3656 
       
  3657 // -----------------------------------------------------------------------------
       
  3658 // CMmSmsMessHandler::GetNumOfEFSMSRecordsResp
       
  3659 //
       
  3660 // -----------------------------------------------------------------------------
       
  3661 //
       
  3662 void CMmSmsMessHandler::GetNumOfEFSMSRecordsResp(
       
  3663     TInt aStatus,
       
  3664     const TDesC8& aFileData )
       
  3665     {
       
  3666 TFLOGSTRING("TSY: CMmSmsMessHandler::GetNumOfEFSMSRecordsResp" );
       
  3667 OstTraceExt2( TRACE_NORMAL, CMMSMSMESSHANDLER_GETNUMOFEFSMSRECORDSRESP, "CMmSmsMessHandler::GetNumOfEFSMSRecordsResp;aStatus=%d;aFileData=%s", aStatus, aFileData );
       
  3668 
       
  3669     TInt offSet( 0 );
       
  3670 
       
  3671     //Save number of SMS locations on SIM card
       
  3672     TInt smsNumOfLoc( 0 );
       
  3673 
       
  3674     if ( KErrNone == aStatus )
       
  3675         {
       
  3676         offSet = aFileData.Find( &KTagFCIFileDescriptor, 1 );
       
  3677         if( offSet != KErrNotFound )
       
  3678             {
       
  3679             smsNumOfLoc =
       
  3680                 aFileData[offSet + UICC_FCI_EF_FDESC_OFFSET_NUM_ENTR];
       
  3681             }
       
  3682         }
       
  3683 
       
  3684     // Continue with reading all sms entries from sim
       
  3685     if ( smsNumOfLoc > 0 )
       
  3686         {
       
  3687         // got the total number or SIM SMS entries
       
  3688         iSmsCache.SetTotalEntriesL( smsNumOfLoc );
       
  3689 TFLOGSTRING2("TSY: CMmSmsMessHandler::SimStSmsGetNumOfLocRespL -- total number of locations on sim %d", iSmsCache.TotalEntries() );
       
  3690 OstTrace1( TRACE_NORMAL, DUP1_CMMSMSMESSHANDLER_GETNUMOFEFSMSRECORDSRESP, "CMmSmsMessHandler::GetNumOfEFSMSRecordsResp;iSmsCache.TotalEntries()=%d", iSmsCache.TotalEntries() );
       
  3691 
       
  3692         // now start reading entries one by one starting from record 1
       
  3693         UiccReadSMSOrSMSRecordCountReq( 1, ETrIdReadSMS );
       
  3694         }
       
  3695     else
       
  3696         {
       
  3697         // There is a chance that getinfo requests are already ongoing
       
  3698         // if so, then complete them here.
       
  3699         TUint8 numOfLoc( 0 );
       
  3700         TInt usedEntries( -1 ); // unable to determine.
       
  3701         CMmDataPackage data;
       
  3702         data.PackData( &numOfLoc, &usedEntries );
       
  3703         iMessageRouter->Complete(
       
  3704             EMobileSmsMessagingGetMessageStoreInfo,
       
  3705             &data,
       
  3706             CMmStaticUtility::UICCCSCauseToEpocError( aStatus )  );
       
  3707 
       
  3708         iMessageRouter->Complete(
       
  3709             EMobilePhoneStoreGetInfo,
       
  3710             &data,
       
  3711             KErrNoMemory );
       
  3712         }
       
  3713     }
       
  3714 
       
  3715 //  End of File