adaptationlayer/tsy/nokiatsy_dll/src/cmmussdmesshandler.cpp
changeset 0 63b37f68c1ce
child 5 8ccc39f9d787
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/adaptationlayer/tsy/nokiatsy_dll/src/cmmussdmesshandler.cpp	Fri Nov 06 17:28:23 2009 +0000
@@ -0,0 +1,862 @@
+/*
+* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+
+//  Include Files
+
+#include <ctsy/pluginapi/cmmdatapackage.h>
+#include <e32std.h>        // error values
+#include <etelmm.h>
+#include <ctsy/serviceapi/mmtsy_defaults.h>
+#include <ss_wmisi.h>
+#include <tisi.h>
+
+#include "cmmmessagerouter.h"
+#include "cmmphonetsender.h"
+#include "cmmstaticutility.h"
+#include "cmmussdmesshandler.h"
+#include "tsylogger.h"
+#include "osttracedefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "cmmussdmesshandlertraces.h"
+#endif
+
+//  External Data Structures
+    //  none
+
+// External Function Prototypes
+    //  none
+
+// LOCAL CONSTANTS AND MACROS
+
+// hard-coded transaction id for ISA messages.
+const TUint8 KUssdTransId = 5;
+const TUint8 KFiller = 0x00;
+
+// MODULE DATA STRUCTURES
+    //  none
+
+// Local Data Structures
+    //  none
+
+// Local Function Prototypes
+    //  none
+
+//  LOCAL FUNCTIONS
+    //  none
+
+// MEMBER FUNCTIONS
+
+//=============================================================================
+
+// -----------------------------------------------------------------------------
+// CMmUssdMessHandler::ConstructL
+// Symbian 2nd phase constructor. Initialises internal attributes.
+// -----------------------------------------------------------------------------
+//
+CMmUssdMessHandler::CMmUssdMessHandler
+    (
+    // None
+    )
+    {
+TFLOGSTRING("TSY: CMmUssdMessHandler::CMmUssdMessHandler");
+OstTrace0( TRACE_NORMAL, CMMUSSDMESSHANDLER_CMMUSSDMESSHANDLER, "CMmUssdMessHandler::CMmUssdMessHandler" );
+    //None
+    }
+
+// -----------------------------------------------------------------------------
+// CMmUssdMessHandler::~CMmUssdMessHandler
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CMmUssdMessHandler::~CMmUssdMessHandler
+    (
+    // None
+    )
+    {
+TFLOGSTRING("TSY: CMmUssdMessHandler::~CMmUssdMessHandler");
+OstTrace0( TRACE_NORMAL, DUP1_CMMUSSDMESSHANDLER_CMMUSSDMESSHANDLER, "CMmUssdMessHandler::~CMmUssdMessHandler" );
+    }
+// -----------------------------------------------------------------------------
+// CMmUssdMessHandler::ConstructL
+// Symbian 2nd phase constructor. Initialises internal attributes.
+// -----------------------------------------------------------------------------
+//
+void CMmUssdMessHandler::ConstructL
+    (
+    // None
+    )
+    {
+TFLOGSTRING("TSY: CMmUssdMessHandler::ConstructL");
+OstTrace0( TRACE_NORMAL, CMMUSSDMESSHANDLER_CONSTRUCTL, "CMmUssdMessHandler::ConstructL" );
+    // The flag indicates the correct complete method in failed case for
+    // SS_SERVICE_FAILED_RESP
+    iIsSendReleaseCalled = EFalse;
+    //No ongoing request
+    iIsUssdSendReqOnGoing = EFalse;
+    //No pending request
+    iIsSendReleaseReqPending = EFalse;
+
+    iNoFdnUSSDReq = EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CMmUssdMessHandler::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMmUssdMessHandler* CMmUssdMessHandler::NewL
+    (
+    CMmPhoNetSender* aPhoNetSender, //pointer to phonet sender
+    CMmPhoNetReceiver* aPhoNetReceiver, // pointer to phonet receiver
+    CMmMessageRouter* aMessageRouter    //pointer to message router
+    )
+    {
+TFLOGSTRING("TSY: CMmUssdMessHandler::NewL.\n");
+OstTrace0( TRACE_NORMAL, CMMUSSDMESSHANDLER_NEWL, "CMmUssdMessHandler::NewL" );
+
+    CMmUssdMessHandler* ussdMessHandler =
+        new( ELeave ) CMmUssdMessHandler();
+
+    CleanupStack::PushL( ussdMessHandler );
+
+    ussdMessHandler->ConstructL();
+    ussdMessHandler->iPhoNetSender = aPhoNetSender;
+    ussdMessHandler->iMessageRouter = aMessageRouter;
+    aPhoNetReceiver->RegisterL(ussdMessHandler, PN_SS, SS_GSM_USSD_SEND_RESP);
+    aPhoNetReceiver->RegisterL(ussdMessHandler, PN_SS, SS_SERVICE_FAILED_RESP);
+    aPhoNetReceiver->RegisterL(ussdMessHandler, PN_SS, SS_GSM_USSD_RECEIVE_IND);
+
+    CleanupStack::Pop( ussdMessHandler );
+
+    return ussdMessHandler;
+    }
+
+// -----------------------------------------------------------------------------
+// CMmUssdMessHandler::ReceiveMessageL
+// Called when an ISI message has been received.
+// -----------------------------------------------------------------------------
+//
+void CMmUssdMessHandler::ReceiveMessageL
+    (
+    const TIsiReceiveC& aIsiMessage    // ISI-message received
+    )
+    {
+    TInt resource (aIsiMessage.Get8bit(ISI_HEADER_OFFSET_RESOURCEID) );
+    TInt messageId (aIsiMessage.Get8bit(ISI_HEADER_OFFSET_MESSAGEID) );
+
+TFLOGSTRING3("TSY: CMmUssdMessHandler::ReceiveMessageL - resouce: %d, msgId: %d", resource, messageId);
+OstTraceExt2( TRACE_NORMAL, CMMUSSDMESSHANDLER_RECEIVEMESSAGEL, "CMmUssdMessHandler::ReceiveMessageL;resource=%d;messageId=%d", resource, messageId );
+
+    switch( resource )
+        {
+        case PN_SS:
+            {
+            switch( messageId )
+                {
+                case SS_GSM_USSD_SEND_RESP:
+                    {
+                    SsGsmUssdSendResp( aIsiMessage );
+                    break;
+                    }
+                case SS_SERVICE_FAILED_RESP:
+                    {
+                    SsServiceFailedResp( aIsiMessage );
+                    // SS_SERVICE_FAILED_RESP message is needed by Custom
+                    // message handler
+                    break;
+                    }
+                case SS_GSM_USSD_RECEIVE_IND:
+                    {
+                    SsGsmUssdReceiveInd( aIsiMessage );
+                    break;
+                    }
+                default:
+                    {
+TFLOGSTRING2("TSY: CMmUssdMessHandler::ReceiveMessageL - PN_SS - unknown msgId: %d", messageId);
+OstTrace1( TRACE_NORMAL, DUP1_CMMUSSDMESSHANDLER_RECEIVEMESSAGEL, "CMmUssdMessHandler::ReceiveMessageL;unknown messageId=%d", messageId );
+                    // No propiert handler methods for ISI-message found
+                    break;
+                    }
+                }
+            break;
+            }
+        default:
+            {
+TFLOGSTRING2("TSY: CMmUssdMessHandler::ReceiveMessageL - unknown resource: %d", resource);
+OstTrace1( TRACE_NORMAL, DUP2_CMMUSSDMESSHANDLER_RECEIVEMESSAGEL, "CMmUssdMessHandler::ReceiveMessageL;resource=%d", resource );
+            break;
+            }
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMmUssdMessHandler::SsGsmUssdSendReq
+// Construct a SS_GSM_USSD_SEND_REQ ISI message
+// -----------------------------------------------------------------------------
+//
+TInt CMmUssdMessHandler::SsGsmUssdSendReq
+    (
+    const CMmDataPackage* aDataPackage
+    )
+    {
+TFLOGSTRING("TSY: CMmUssdMessHandler::SsGsmUssdSendReq");
+OstTrace0( TRACE_NORMAL, CMMUSSDMESSHANDLER_SSGSMUSSDSENDREQ, "CMmUssdMessHandler::SsGsmUssdSendReq" );
+    TInt ret ( KErrNone );
+    TBuf8<RMobileUssdMessaging::KGsmUssdDataSize> data( 0 );
+    TDes8* attributes( 0 );
+    TUint8 numOfSubblocks( 2 );
+
+    aDataPackage->UnPackData( data, attributes );
+
+    RMobileUssdMessaging::TMobileUssdAttributesV1Pckg* msgAttrPck (
+        (RMobileUssdMessaging::TMobileUssdAttributesV1Pckg*) ( attributes ) );
+
+    RMobileUssdMessaging::TMobileUssdAttributesV1 msgAttr ( ( *msgAttrPck )() );
+
+TFLOGSTRING2("TSY: CMmUssdMessHandler::SsGsmUssdSendReq. AttributeType: %d", msgAttr.iType );
+OstTrace1( TRACE_NORMAL, DUP1_CMMUSSDMESSHANDLER_SSGSMUSSDSENDREQ, "CMmUssdMessHandler::SsGsmUssdSendReq;msgAttr.iType=%d", msgAttr.iType );
+
+    TUint8 ussdType( KFiller ); //initialize ussdtype to 0
+
+    if ( RMobileUssdMessaging::KUssdMessageType & msgAttr.iFlags )
+        {
+        switch ( msgAttr.iType )
+            {
+            // User has requested to send MO USSD
+            case RMobileUssdMessaging::EUssdMORequest:
+                ussdType = SS_GSM_USSD_COMMAND;
+                break;
+            // User is replying to MT USSD.
+            case RMobileUssdMessaging::EUssdMOReply:
+                ussdType = SS_GSM_USSD_MT_REPLY;
+                break;
+            // User is signing for the MT request
+            case RMobileUssdMessaging::EUssdMOAcknowledgement:
+                ussdType = SS_GSM_USSD_NOTIFY;
+                break;
+            // Unknown or illegal cases return error to client
+            default:
+                // ussd type is unknown, report error
+                ret = KErrArgument;
+                break;
+            }
+        }
+    else
+        {
+TFLOGSTRING("TSY: CMmUssdMessHandler::SsGsmUssdSendReq. Type flag missing" );
+OstTrace0( TRACE_NORMAL, DUP2_CMMUSSDMESSHANDLER_SSGSMUSSDSENDREQ, "CMmUssdMessHandler::SsGsmUssdSendReq, Type flag missing" );
+        // ussd type is unknown, report error
+        ret = KErrArgument;
+        }
+
+    TUint8 codingInfo( KFiller );  //initialize codinginfo to 0
+    // If messagetype was valid, check data coding scheme.
+    if ( KErrNone == ret )
+        {
+        if ( RMobileUssdMessaging::KUssdMessageDcs & msgAttr.iFlags )
+            {
+            //get data coding scheme
+            codingInfo = msgAttr.iDcs;
+            }
+         else
+            {
+TFLOGSTRING("TSY: CMmUssdMessHandler::SsGsmUssdSendReq. DCS flag missing" );
+OstTrace0( TRACE_NORMAL, DUP3_CMMUSSDMESSHANDLER_SSGSMUSSDSENDREQ, "CMmUssdMessHandler::SsGsmUssdSendReq, DCS flag missing" );
+            // data coding scheme is unknown, report error.
+            ret = KErrArgument;
+            }
+        }
+
+    // If messagetype and data coding scheme were valid, send message.
+    if ( KErrNone == ret )
+        {
+        if ( RMobileUssdMessaging::KUssdDataFormat & msgAttr.iFlags )
+            {
+            // Create UssdSendReq ISI-message
+            TIsiSend ssGsmUssdSendReq( iPhoNetSender->SendBufferDes() );
+            ssGsmUssdSendReq.Set8bit( ISI_HEADER_OFFSET_RESOURCEID, PN_SS );
+            ssGsmUssdSendReq.Set8bit( ISI_HEADER_OFFSET_TRANSID, KUssdTransId );
+            ssGsmUssdSendReq.Set8bit(
+                ISI_HEADER_OFFSET_MESSAGEID,
+                SS_GSM_USSD_SEND_REQ );
+
+            ssGsmUssdSendReq.Set8bit( ISI_HEADER_SIZE +
+                SS_GSM_USSD_SEND_REQ_OFFSET_USSDTYPE, ussdType );
+
+            // Create SsGsmUssdString subblock.
+            // subblock header + ussd string length subblock max length = 164
+
+            TBuf8<KMaxLengthOfUssdMessage + 3> ssGsmUssdStringSb( 0 );
+
+            TIsiSubBlock subblockSSGsmUssdString(
+                ssGsmUssdStringSb, SS_GSM_USSD_STRING, EIsiSubBlockTypeId8Len8 );
+
+            ssGsmUssdStringSb.Append( codingInfo );
+            ssGsmUssdStringSb.Append( data.Length() );
+            ssGsmUssdStringSb.Append( data );
+
+            ssGsmUssdSendReq.CopyData( ISI_HEADER_SIZE +
+                SIZE_SS_GSM_USSD_SEND_REQ,
+                subblockSSGsmUssdString.CompleteSubBlock() );
+
+            // create subblock SS_SB_CHECK_INFO
+            TBuf8<SIZE_SS_SB_CHECK_INFO>sbData( 0 );
+            TIsiSubBlock ssCheckInfoSb(
+                sbData,
+                SS_SB_CHECK_INFO,
+                EIsiSubBlockTypeId8Len8 );
+
+            if( iNoFdnUSSDReq )
+                {
+                sbData.Append( SS_FDN_CHECK_SUPPRESS );
+                }
+            else
+                {
+                sbData.Append( SS_NO_FDN_CHECK_SUPPRESS );
+                }
+
+            sbData.Append( SS_NO_RESOURCE_CONTROL_SUPPRESS );
+
+            // add the SIZE_SS_SB_CHECK_INFO subblock to service req
+            ssGsmUssdSendReq.CopyData(
+                ISI_HEADER_SIZE + SIZE_SS_GSM_USSD_SEND_REQ +
+                ssGsmUssdStringSb.Length(),
+                ssCheckInfoSb.CompleteSubBlock( ) );
+
+            ssGsmUssdSendReq.Set8bit( ISI_HEADER_SIZE +
+                SS_GSM_USSD_SEND_REQ_OFFSET_SUBBLOCKCOUNT, numOfSubblocks );
+
+
+            //send message via phonet
+            ret = iPhoNetSender->Send( ssGsmUssdSendReq.Complete() );
+            }
+        else
+            {
+            // dataformat is unspecified, report error.
+            ret = KErrArgument;
+            }
+        }
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CMmUssdMessHandler::SsGsmUssdSendReq
+// Construct a SS_GSM_USSD_SEND_REQ ISI message that ends ussd session
+// -----------------------------------------------------------------------------
+//
+TInt CMmUssdMessHandler::SsGsmUssdSendReq
+    (
+    void
+    )
+    {
+TFLOGSTRING("LTSY: CMmUssdMessHandler::SsGsmUssdSendReq. End USSD session" );
+OstTrace0( TRACE_NORMAL, DUP4_CMMUSSDMESSHANDLER_SSGSMUSSDSENDREQ, "CMmUssdMessHandler::SsGsmUssdSendReq" );
+
+    // Change the flag to indicate the correct complete method for failed resp
+    iIsSendReleaseCalled = ETrue;
+    // No pending request anymore
+    iIsSendReleaseReqPending = EFalse;
+
+    // create buffer for isi msg data
+    TBuf8<2> messageData( 0 );
+
+    messageData.Append( SS_GSM_USSD_END );
+    // number of sub blocks
+    messageData.Append( 0 );
+
+    return iPhoNetSender->Send(
+        PN_SS,
+        KUssdTransId,
+        SS_GSM_USSD_SEND_REQ,
+        messageData );
+    }
+
+// -----------------------------------------------------------------------------
+// CMmUssdMessHandler::SsGsmUssdSendResp
+// Completes successful Ss Gsm Ussd Send Request.
+// -----------------------------------------------------------------------------
+//
+void CMmUssdMessHandler::SsGsmUssdSendResp
+    (
+    const TIsiReceiveC &aIsiMessage //received isi message
+    )
+    {
+TFLOGSTRING("TSY: CMmUssdMessHandler::SsGsmUssdSendResp" );
+OstTrace0( TRACE_NORMAL, CMMUSSDMESSHANDLER_SSGSMUSSDSENDRESP, "CMmUssdMessHandler::SsGsmUssdSendResp" );
+
+    TUint8 length ( aIsiMessage.Get8bit(
+        ISI_HEADER_SIZE + SS_GSM_USSD_SEND_RESP_OFFSET_LENGTHOFUSSDSTRING ) );
+
+    TBuf8<KMaxLengthOfUssdMessage> ussdString ( aIsiMessage.GetData(
+        ISI_HEADER_SIZE + SS_GSM_USSD_SEND_RESP_OFFSET_USSDSTRING, length ) );
+
+    TUint8 ussdType ( aIsiMessage.Get8bit(
+        ISI_HEADER_SIZE + SS_GSM_USSD_SEND_RESP_OFFSET_USSDTYPE ) );
+
+    //create package.
+    CMmDataPackage package;
+
+    // If the message sent was of type SS_GSM_USSD_END, and the request
+    // was a SendRelease request, then a different request must be completed
+    if ( SS_GSM_USSD_END == ussdType && iIsSendReleaseCalled )
+        {
+TFLOGSTRING("TSY: CMmUssdMessHandler::SsGsmUssdSendResp. Response to SendRelease." );
+OstTrace0( TRACE_NORMAL, DUP1_CMMUSSDMESSHANDLER_SSGSMUSSDSENDRESP, "CMmUssdMessHandler::SsGsmUssdSendResp, Response to SendRelease" );
+
+        // Reset the flag
+        iIsSendReleaseCalled = EFalse;
+
+        RMobilePhone::TMobilePhoneSendSSRequestV3 returnResult;
+
+        returnResult.iOpCode = KErrNone;
+        returnResult.iAdditionalInfo.Append( KErrNone );
+
+        //pack the data
+        package.PackData( &returnResult );
+
+        //complete the request
+        iMessageRouter->Complete(
+            EMobileUssdMessagingSendRelease,
+            &package,
+            KErrNone);
+        }
+    // otherwise complete the send message request
+    else
+        {
+        if ( iNoFdnUSSDReq )
+            {
+            // Call CompleteSendMessageNoFdnCheck request.
+            iMessageRouter->Complete(
+                EMobileUssdMessagingSendMessageNoFdnCheck,
+                KErrNone );
+            }
+        else
+            {
+            // Call CompleteSendMessage request.
+            iMessageRouter->Complete(
+                EMobileUssdMessagingSendMessage,
+                KErrNone );
+            }
+
+        //Req is not ongoing anymore
+        iIsUssdSendReqOnGoing = EFalse;
+
+        //if a cancel request has been made
+        if ( iIsSendReleaseReqPending )
+            {
+TFLOGSTRING("TSY: CMmUssdMessHandler::SsGsmUssdSendResp. SendRelease pending." );
+OstTrace0( TRACE_NORMAL, DUP2_CMMUSSDMESSHANDLER_SSGSMUSSDSENDRESP, "CMmUssdMessHandler::SsGsmUssdSendResp, SendRelease pending" );
+
+            TInt ret ( KErrNone );
+            ret = SsGsmUssdSendReq();
+
+            if ( KErrNone != ret )
+                {
+                RMobilePhone::TMobilePhoneSendSSRequestV3 returnResult;
+
+                returnResult.iOpCode = static_cast <TUint8 > ( KErrGeneral );
+                returnResult.iAdditionalInfo.Append(
+                    static_cast < TUint8 > ( KErrGeneral ) );
+
+                //complete the request
+                iMessageRouter->Complete(
+                    EMobileUssdMessagingSendRelease,
+                    &package,
+                    KErrGeneral );
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMmUssdMessHandler::SsServiceFailedResp
+// Completes unsuccessful Ss Gsm Ussd Send Request ( MO USSD ).
+// -----------------------------------------------------------------------------
+//
+void CMmUssdMessHandler::SsServiceFailedResp
+    (
+    const TIsiReceiveC &aIsiMessage //received isi message
+    )
+    {
+
+TFLOGSTRING("TSY: CMmUssdMessHandler::SsServiceFailedResp" );
+OstTrace0( TRACE_NORMAL, CMMUSSDMESSHANDLER_SSSERVICEFAILEDRESP, "CMmUssdMessHandler::SsServiceFailedResp" );
+
+    // Initialize cause type and value, if no specified.
+    // subblock found, use SS_UNSPECIFIED_REASON.
+    TUint8 causeType( KErrNone );
+    TUint8 causeValue( SS_UNSPECIFIED_REASON );
+    // If no sub block, set epocerror to KErrGeneral.
+    TInt epocError( KErrGeneral );
+
+    // offset where the subblock starts
+    TUint sbStartOffset( KErrNone );
+
+    //create package.
+    CMmDataPackage package;
+
+    if( KErrNone == aIsiMessage.FindSubBlockOffsetById(
+        ISI_HEADER_SIZE + SIZE_SS_SERVICE_FAILED_RESP,
+        SS_GSM_INDICATE_MSG_ERROR,
+        EIsiSubBlockTypeId8Len8,
+        sbStartOffset ) )
+        {
+        causeType = SS_GSM_INDICATE_MSG_ERROR;
+        causeValue = aIsiMessage.Get8bit(
+            sbStartOffset + SS_GSM_INDICATE_MSG_ERROR_OFFSET_MESSAGEERRORCODE );
+        }
+    else if( KErrNone == aIsiMessage.FindSubBlockOffsetById(
+        ISI_HEADER_SIZE + SIZE_SS_SERVICE_FAILED_RESP,
+        SS_GSM_INDICATE_ERROR,
+        EIsiSubBlockTypeId8Len8,
+        sbStartOffset ) )
+        {
+        causeType = SS_GSM_INDICATE_ERROR;
+        causeValue = aIsiMessage.Get8bit(
+            sbStartOffset + SS_GSM_INDICATE_ERROR_OFFSET_ERRORCODE );
+        }
+    else if( KErrNone == aIsiMessage.FindSubBlockOffsetById(
+        ISI_HEADER_SIZE + SIZE_SS_SERVICE_FAILED_RESP,
+        SS_GSM_INDICATE_PROBLEM,
+        EIsiSubBlockTypeId8Len8,
+        sbStartOffset ) )
+        {
+        causeType = aIsiMessage.Get8bit(
+            sbStartOffset + SS_GSM_INDICATE_PROBLEM_OFFSET_PROBLEMTYPE );
+        causeValue = aIsiMessage.Get8bit(
+            sbStartOffset + SS_GSM_INDICATE_PROBLEM_OFFSET_PROBLEMCODE );
+        }
+    else if( KErrNone == aIsiMessage.FindSubBlockOffsetById(
+        ISI_HEADER_SIZE + SIZE_SS_SERVICE_FAILED_RESP,
+        SS_OTHER_ERROR,
+        EIsiSubBlockTypeId8Len8,
+        sbStartOffset ) )
+        {
+        causeType = SS_OTHER_ERROR;
+        causeValue = aIsiMessage.Get8bit(
+            sbStartOffset + SS_OTHER_ERROR_OFFSET_ERRORCODE );
+        }
+    else if( KErrNone == aIsiMessage.FindSubBlockOffsetById(
+        ISI_HEADER_SIZE + SIZE_SS_SERVICE_FAILED_RESP,
+        SS_GSM_MM_RELEASED,
+        EIsiSubBlockTypeId8Len8,
+        sbStartOffset ) )
+        {
+        causeType= SS_GSM_MM_RELEASED;
+        causeValue = aIsiMessage.Get8bit(
+            sbStartOffset + SS_GSM_MM_RELEASED_OFFSET_CAUSE );
+        }
+    else
+        {
+        causeType = KNoCsCauseType; // causetype not defined
+        }
+
+    //If cause value is SS_GSM_SS_NOT_AVAILABLE (comes in SS_OTHER_ERROR sub block)
+    //this indicates that there is not network coverage.
+    if( SS_GSM_SS_NOT_AVAILABLE == causeValue )
+        {
+        epocError = CMmStaticUtility::EpocErrorCode(
+            KErrCouldNotConnect,
+            KErrGsmSMSNoNetworkService );
+TFLOGSTRING("TSY: CMmUssdMessHandler::SsServiceFailedResp. Cause: SS_GSM_SS_NOT_AVAILABLE => No network coverage." );
+OstTrace0( TRACE_NORMAL, DUP1_CMMUSSDMESSHANDLER_SSSERVICEFAILEDRESP, "CMmUssdMessHandler::SsServiceFailedResp, Cause: SS_GSM_SS_NOT_AVAILABLE => No network coverage" );
+        }
+    else
+        {
+        // Translate error to epoc world, Fix RFState problem
+        epocError = CMmStaticUtility::CSCauseToEpocError(
+            PN_SS,
+            causeType,
+            causeValue );
+        }
+
+    if ( iIsSendReleaseCalled )
+        {
+TFLOGSTRING("TSY: CMmUssdMessHandler::SsServiceFailedResp. SendRelease failed." );
+OstTrace0( TRACE_NORMAL, DUP2_CMMUSSDMESSHANDLER_SSSERVICEFAILEDRESP, "CMmUssdMessHandler::SsServiceFailedResp, SendRelease failed" );
+
+        // Reset the flag
+        iIsSendReleaseCalled = EFalse;
+
+        RMobilePhone::TMobilePhoneSendSSRequestV3 returnResult;
+
+        returnResult.iOpCode = static_cast < TUint8 > ( KErrGeneral );
+        returnResult.iAdditionalInfo.Append( epocError );
+
+        //pack the data
+        package.PackData( &returnResult );
+
+        // Call CompleteSendRelease request with epocError from TSY.
+        iMessageRouter->Complete(
+            EMobileUssdMessagingSendRelease,
+            &package,
+            epocError );
+        }
+    else
+        {
+        if ( iNoFdnUSSDReq )
+            {
+            // Call CompleteSendMessageNoFdnCheck request with epocError from TSY.
+            iMessageRouter->Complete(
+                EMobileUssdMessagingSendMessageNoFdnCheck,
+                epocError );
+            }
+        else
+            {
+            // Call CompleteSendMessage request with epocError from TSY.
+            iMessageRouter->Complete(
+                EMobileUssdMessagingSendMessage,
+                epocError );
+            }
+
+        //Request is not ongoing anymore
+        iIsUssdSendReqOnGoing = EFalse;
+
+        //if a Cancel request has been made
+        if ( iIsSendReleaseReqPending )
+            {
+            iIsSendReleaseReqPending = EFalse;
+
+            RMobilePhone::TMobilePhoneSendSSRequestV3 returnResult;
+
+            returnResult.iOpCode = static_cast < TUint8 > ( KErrNone );
+            returnResult.iAdditionalInfo.Append( KErrNone );
+
+            //pack the data
+            package.PackData( &returnResult );
+
+            //complete the request immediately without having sent anything
+            //to SS server because the 1rst request has failed so there is no
+            //need to cancel it.
+            iMessageRouter->Complete(
+                EMobileUssdMessagingSendRelease,
+                &package,
+                KErrNone );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMmUssdMessHandler::SsGsmUssdReceiveInd
+// Breaks a SS_GSM_USSD_RECEIVE_IND ISI message
+// -----------------------------------------------------------------------------
+//
+void CMmUssdMessHandler::SsGsmUssdReceiveInd
+    (
+    const TIsiReceiveC &aIsiMessage //received isi message
+    )
+    {
+    //create package.
+    CMmDataPackage notifyPackage;
+
+    TUint8 length ( aIsiMessage.Get8bit(
+        ISI_HEADER_SIZE + SS_GSM_USSD_SEND_RESP_OFFSET_LENGTHOFUSSDSTRING ) );
+
+    TBuf8<KMaxLengthOfUssdMessage> ussdString ( aIsiMessage.GetData(
+        ISI_HEADER_SIZE + SS_GSM_USSD_SEND_RESP_OFFSET_USSDSTRING, length ) );
+
+    TUint8 codingInfo ( aIsiMessage.Get8bit(
+        ISI_HEADER_SIZE + SS_GSM_USSD_RECEIVE_IND_OFFSET_CODINGINFO ) );
+
+    TUint8 ussdType ( aIsiMessage.Get8bit(
+        ISI_HEADER_SIZE + SS_GSM_USSD_RECEIVE_IND_OFFSET_USSDTYPE ) );
+
+    RMobileUssdMessaging::TMobileUssdAttributesV1 receiveUssdMessageAttributes;
+    TBuf8<RMobileUssdMessaging::KGsmUssdDataSize> receiveUssdMessage( 0 );
+
+    receiveUssdMessage.Copy( ussdString );
+
+    receiveUssdMessageAttributes.iDcs = codingInfo;
+
+    receiveUssdMessageAttributes.iFlags =
+        ( RMobileUssdMessaging::KUssdDataFormat+
+        RMobileUssdMessaging::KUssdMessageType+
+        RMobileUssdMessaging::KUssdMessageDcs );
+
+    receiveUssdMessageAttributes.iFormat =
+        ( RMobileUssdMessaging::EFormatPackedString );
+
+TFLOGSTRING2("TSY: CMmUssdMessHandler::SsGsmUssdReceiveInd: UssdType %d", ussdType);
+OstTraceExt1( TRACE_NORMAL, CMMUSSDMESSHANDLER_SSGSMUSSDRECEIVEIND, "CMmUssdMessHandler::SsGsmUssdReceiveInd;ussdType=%hhu", ussdType );
+
+    switch ( ussdType )
+        {
+        case SS_GSM_USSD_REQUEST:
+        case SS_GSM_USSD_COMMAND:
+            {
+            receiveUssdMessageAttributes.iType =
+                RMobileUssdMessaging::EUssdMTRequest;
+            break;
+            }
+        // Set USSD message type to EUssdMTReply if ussdType is .
+        // SS_GSM_USSD_MT_REPLY or SS_GSM_USSD_END.
+        case SS_GSM_USSD_MT_REPLY:
+            {
+            receiveUssdMessageAttributes.iType =
+                RMobileUssdMessaging::EUssdMTReply;
+            break;
+            }
+        case SS_GSM_USSD_END:
+            {
+            receiveUssdMessageAttributes.iType =
+                RMobileUssdMessaging::EUssdMTReply;
+            RMobilePhone::TMobilePhoneSendSSRequestV3 returnResult;
+            returnResult.iOpCode = KErrNone;
+            returnResult.iAdditionalInfo.Append( KErrNone );
+
+            //pack the data
+            notifyPackage.PackData( &returnResult );
+            break;
+            }
+        case SS_GSM_USSD_NOTIFY:
+            {
+            receiveUssdMessageAttributes.iType =
+                RMobileUssdMessaging::EUssdMTNotify;
+            break;
+            }
+        // Can't map SS_GSM_USSD_COMMAND to MM ETel values.
+        default:
+            {
+            receiveUssdMessageAttributes.iType =
+                RMobileUssdMessaging::EUssdUnknown;
+            break;
+            }
+        }   // end switch
+
+    //create package.
+    CMmDataPackage package;
+
+    //pack the data
+    package.PackData( &receiveUssdMessage, &receiveUssdMessageAttributes );
+
+    if ( SS_GSM_USSD_END != ussdType || ussdString.Length() )
+        {
+        iMessageRouter->Complete(
+            EMobileUssdMessagingReceiveMessage,
+            &package,
+            KErrNone );
+
+TFLOGSTRING("TSY: CMmUssdMessHandler::SsGsmUssdReceiveInd: Complete : EMobileUssdMessagingReceiveMessage" );
+OstTrace0( TRACE_NORMAL, DUP1_CMMUSSDMESSHANDLER_SSGSMUSSDRECEIVEIND, "CMmUssdMessHandler::SsGsmUssdReceiveInd, EMobileUssdMessagingReceiveMessage" );
+        }
+
+    if ( SS_GSM_USSD_END == ussdType )
+        {
+        // Complete the request
+        // This notifies a client of a MT USSD release message to the mobile device.
+        iMessageRouter->Complete(
+            EMobileUssdMessagingNotifyNetworkRelease,
+            &notifyPackage,
+            KErrNone );
+
+TFLOGSTRING("TSY: CMmUssdMessHandler::SsGsmUssdReceiveInd: Complete : EMobileUssdMessagingNotifyNetworkRelease" );
+OstTrace0( TRACE_NORMAL, DUP2_CMMUSSDMESSHANDLER_SSGSMUSSDRECEIVEIND, "CMmUssdMessHandler::SsGsmUssdReceiveInd, EMobileUssdMessagingNotifyNetworkRelease" );
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMmUssdMessHandler::ExtFuncL
+// Dispatches Etel requests to DOS level handlers
+// -----------------------------------------------------------------------------
+//
+TInt CMmUssdMessHandler::ExtFuncL
+    (
+    TInt aIpc,
+    const CMmDataPackage* aDataPackage
+    )
+    {
+
+    //*************************************************************//.
+    // NOTE.
+    //.
+    // LICENSEE SPECIFIC MESSAGE HANDLER IMPLEMENTATION STARTS HERE.
+    //.
+    //*************************************************************//.
+
+TFLOGSTRING("TSY: CMmUssdMessHandler::ExtFuncL");
+OstTrace0( TRACE_NORMAL, DUP1_CMMUSSDMESSHANDLER_EXTFUNCL, "CMmUssdMessHandler::ExtFuncL" );
+
+    TInt ret( KErrNone );
+
+         if( EMobileUssdMessagingSendMessageNoFdnCheck == aIpc )
+            {
+            TFLOGSTRING("TSY: CMmUssdMessHandler::ExtFuncL - iNoFdnUSSDReq --> TRUE");
+            // set flag
+            iNoFdnUSSDReq = ETrue;
+            }
+        else
+            {
+            TFLOGSTRING("TSY: CMmUssdMessHandler::ExtFuncL - iNoFdnUSSDReq --> FALSE");
+            iNoFdnUSSDReq = EFalse;
+            }
+
+    switch ( aIpc )
+        {
+        case EMobileUssdMessagingSendMessage:
+        case EMobileUssdMessagingSendMessageNoFdnCheck:
+            {
+            ret = SsGsmUssdSendReq( aDataPackage );
+            iIsUssdSendReqOnGoing = ETrue;
+            break;
+            }
+        case EMobileUssdMessagingSendRelease:
+            {
+            if ( iIsUssdSendReqOnGoing )
+                {
+                iIsSendReleaseReqPending = ETrue;
+                }
+            else
+                {
+                ret = SsGsmUssdSendReq();
+                }
+            break;
+            }
+        default:
+            {
+TFLOGSTRING2("TSY: CMmUssdMessHandler::ExtFuncL - Unknown IPC: %d", aIpc);
+OstTrace1( TRACE_NORMAL, DUP2_CMMUSSDMESSHANDLER_EXTFUNCL, "CMmUssdMessHandler::ExtFuncL;aIpc=%d", aIpc );
+            ret = KErrNotSupported;
+            break;
+            }
+        }
+    return ret;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMmUssdMessHandler::HandlerError
+// Handles CMmUssdMessHandler's errors that comes via PhoNetReceiver RunError
+// method.
+// -----------------------------------------------------------------------------
+//
+void CMmUssdMessHandler::HandleError
+    (
+    const TIsiReceiveC& /*aIsiMessage*/,// Isi message
+    TInt /*aError*/                     // Error code
+    )
+    {
+TFLOGSTRING("TSY: CMmUssdMessHandler::HandleError");
+OstTrace0( TRACE_NORMAL, CMMUSSDMESSHANDLER_HANDLEERROR, "CMmUssdMessHandler::HandleError" );
+    }
+
+
+//end of file
+