adaptationlayer/tsy/simatktsy_dll/src/satcc.cpp
changeset 0 63b37f68c1ce
child 5 8ccc39f9d787
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/adaptationlayer/tsy/simatktsy_dll/src/satcc.cpp	Fri Nov 06 17:28:23 2009 +0000
@@ -0,0 +1,1819 @@
+/*
+* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+
+
+//  INCLUDE FILES
+#include "satcc.h"              // sat call control class
+#include "satmessaging.h"       // sat messaging class
+#include "satmesshandler.h"     // sat message handler class
+#include "ber_tlv.h"            // sat ber-tlv classes
+#include "satutil.h"            // sat utility class
+
+#include <pn_const.h>           // server id constants
+#include <tisi.h>               // isi message
+#include <ss_wmisi.h>           // Modem SS server
+#include <call_modemisi.h>      // Modem Call server
+#include <gpdsisi.h>            // GPDS server
+#include <uiccisi.h>            // UICC server
+#include "osttracedefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "satcctraces.h"
+#endif
+
+
+
+// CONSTANTS
+// Zero character code
+const TUint8 KZeroCharacterCode                 = 0x30;
+// Maximum length for PDP Context Activation Parameters, see 3GPP TS 31.111
+const TUint8 KPdpContextActivationParamsMaxSize = 124;
+// From 3GPP TS 31.111, 7.3.1.6 Structure of ENVELOPE (CALL CONTROL)
+const TUint8 KCcResultAllowedNoModification     = 0x00;
+const TUint8 KCcResultNotAllowed                = 0x01;
+const TUint8 KCcResultAllowedWithModifications  = 0x02;
+
+// Maximum data length without additional TLVs in envelope response
+const TUint8 KCcEmptyResponseLenght     = 0x02;
+// Buffer seze used for all CC responses
+const TInt KMaximumCcBufferSize =
+    4 +     //CALL_MODEM_SB_RESOURCE
+    4 +     //CALL_MODEM_SB_RESOURCE_SEQ_ID
+    4 +     //CALL_MODEM_SB_RESOURCE_STATUS
+    4 +     //CALL_MODEM_SB_MODE
+    252 +   //CALL_MODEM_SB_BC
+    252 +   //CALL_MODEM_SB_DESTINATION_ADDRESS
+    252 +   //CALL_MODEM_SB_DESTINATION_SUBADDRESS
+    252 +   //CALL_MODEM_SB_BC
+    4;      //CALL_MODEM_SB_CAUSE
+
+const TUint8 KMSBMask = 0x80;
+
+
+// ==================== MEMBER FUNCTIONS ====================================
+
+// -----------------------------------------------------------------------------
+// CSatCC::CSatCC
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CSatCC::CSatCC
+        (
+        CSatMessHandler*    aSatMessHandler, //Pointer to the message handler
+        CTsySatMessaging*   aSatMessaging    //Pointer to satmessaging class
+        )
+        :
+        iSatMessHandler( aSatMessHandler ),
+        iSatMessaging( aSatMessaging ),
+        iTonNpiPresent( EFalse ),
+        iEnvelopeResponseData( NULL )
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_CSATCC, "CSatCC::CSatCC" );
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CSatCC::ConstructL()
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_CONSTRUCTL, "CSatCC::ConstructL" );
+    TFLOGSTRING("TSY: CSatCC::ConstructL");
+
+    // Create array for CC request information storing
+    iCallControlArray = new( ELeave ) RArray<TCallControl>( 1 );
+
+    iUssdTlvSupported = EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CSatCC* CSatCC::NewL
+        (
+        CSatMessHandler*    aSatMessHandler, //Pointer to the message handler
+        CTsySatMessaging*   aSatMessaging    //Pointer to satmessaging class
+        )
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_NEWL, "CSatCC::NewL" );
+    TFLOGSTRING("TSY: CSatCC::NewL");
+
+    CSatCC* self = new( ELeave ) CSatCC( aSatMessHandler, aSatMessaging );
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CSatCC::~CSatCC
+// C++ destructor
+// -----------------------------------------------------------------------------
+//
+CSatCC::~CSatCC()
+    {
+    OstTrace0( TRACE_NORMAL, DUP1_CSATCC_CSATCC, "CSatCC::~CSatCC" );
+    TFLOGSTRING("TSY: CSatCC::~CSatCC");
+    
+    if( iCallControlArray )
+        {
+        iCallControlArray->Close();
+        delete iCallControlArray;
+        }
+
+    if ( iEnvelopeResponseData )
+        {
+        delete iEnvelopeResponseData;
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CSatCC::GetArrayIndexById
+// Helper method for searching desired information from array
+// used for locating stored call control event information
+// -----------------------------------------------------------------------------
+//
+TInt CSatCC::GetArrayIndexById
+        (
+        const TInt &aTid
+        )
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_GETARRAYINDEXBYID, "CSatCC::GetArrayIndexById" );
+    TFLOGSTRING("TSY: CSatCC::GetArrayIndexById");
+
+    TInt ret ( KErrNotFound );
+    TInt arraySize ( iCallControlArray->Count() );
+
+    // Only there's Cc transaction ongoing
+    if ( arraySize )
+        {
+        for ( TInt i = 0 ; ret == KErrNotFound && i < arraySize ; i++ )
+            {
+            if ( ( *iCallControlArray )[i].iTransId == aTid )
+                {
+                ret = i;
+                }
+            }
+        if ( KErrNotFound == ret)
+            {
+            TFLOGSTRING3("TSY: CSatCC::GetArrayIndexById, Error:ID 0x%x not found. Array size: %d", aTid, arraySize );
+            OstTraceExt2( TRACE_NORMAL, DUP1_CSATCC_GETARRAYINDEXBYID, "CSatCC::GetArrayIndexById, Error: ID 0x%x not found. Array size: %d", aTid, arraySize );
+            }
+        }
+    else
+        {
+        //None. This is not our message.
+        }
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::AddLocationInformationToTlv
+// Adds location informating to given TTlv.
+// -----------------------------------------------------------------------------
+//
+void CSatCC::AddLocationInformationToTlv
+        (
+        TTlv& aTlv //Tlv to be sent
+        )
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_ADDLOCATIONINFORMATIONTOTLV, "CSatCC::AddLocationInformationToTlv" );
+    TFLOGSTRING("TSY: CSatCC::AddLocationInformationToTlv");
+
+    const CSatMessHandler::TLocationInfo& locInfo
+        = iSatMessHandler->LocationInfo();
+
+    aTlv.AddTag( KTlvLocationInformationTag );
+    // append Mobile Country  & Network Codes, 3 bytes
+    aTlv.AddData( locInfo.iOperatorCode );
+    // append LAC code
+    aTlv.AddData( locInfo.iLac );
+    // append CellId
+    aTlv.AddData( locInfo.iCellId );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CSatCC::SendSSEnvelope
+// Sends call control SS envelope
+// -----------------------------------------------------------------------------
+//
+TInt CSatCC::SendSSEnvelope
+        (
+        const TCallControl& aCcstruct //Structure containing call event info
+        )
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_SENDSSENVELOPE, "CSatCC::SendSSEnvelope" );
+    TFLOGSTRING("TSY: CSatCC::SendSSEnvelope");
+
+    // create envelope
+    TTlv envelope;
+    envelope.Begin  ( KBerTlvCallControlTag );
+    // device identities
+    envelope.AddTag ( KTlvDeviceIdentityTag );
+    envelope.AddByte( KMe );
+    envelope.AddByte( KSim );
+    // SS string
+    envelope.AddTag( KTlvSsStringTag );
+
+    //There is no TON and NPI in SS cc request. Information is part of the
+    //number string: Spec ETSI TS 122 030 v5.0.0 says that if number starts
+    //with +, TON is international and if it starts without it, it's unknown.
+    //Default NPI is used if all digits are in the range 0-9.
+    //NPI shall be unknown if other number information is included.
+    //In any case if the user has selected some particular
+    //NPI, that will be used.
+    TInt i( 0 );
+    TUint8 tonNpi( KTonNpiUnknown );
+
+    // If SS is entered by user, there's no SEND SS from where to resolve TonNpi
+    // Then TonNpi is resolved from SS string
+    // TonNpi   = Unknown if '+'-sign is not present
+    //          = International if '+'-sign is found
+    //          = No TonNpi if phone number is not present or SS-string contains
+    //            only SS code
+    if ( !iTonNpiPresent )
+        {
+        // 3GPP TS 22 030 V7.0.0 (2004-03) says:
+        // "The procedure always starts with *, #, **, ## or *#
+        // and is finished by #. Each part within the procedure
+        // is separated by *."
+
+        // skip start characters
+        while ( ( i < aCcstruct.iString.Length() ) &&
+                 ( ( '*' == aCcstruct.iString[i] ) ||
+                   ( '#' == aCcstruct.iString[i] ) ) )
+            {
+            i++;
+            }
+        TInt ssCode( 0 );
+        // seek for separation character and store service code
+        while ( ( i < aCcstruct.iString.Length() )
+                && ( '*' != aCcstruct.iString[i] )
+                && ( '#' != aCcstruct.iString[i] ) )
+            {
+            ssCode *= 10;
+            ssCode += ( aCcstruct.iString[i] - KZeroCharacterCode );
+            i++;
+            }
+        // With these SS codes dialling number may be included. It's located
+        // after first separation mark '*', but it can be empty.
+        // See 3GPP TS 22.030 7.0.0, 6.5.2 and Annex B.
+        // With checking the service code ton/npi resolving is made
+        // unambiguous.
+        // Structure of SS string: *service code*SIA*SIB*SIC#
+        // Content of SIB and SIC have no impact to ton/npi
+        if( SS_GSM_ALL_FORWARDINGS == ssCode
+            || SS_GSM_ALL_COND_FORWARDINGS == ssCode
+            || SS_GSM_FORW_UNCONDITIONAL == ssCode
+            || SS_GSM_FORW_BUSY == ssCode
+            || SS_GSM_FORW_NO_REPLY == ssCode
+            || SS_GSM_FORW_NO_REACH == ssCode)
+            {
+            // Set tonNpi international, if separation character (*) and (+)
+            // sign is found
+            if ( ( ( i + 1 ) < aCcstruct.iString.Length() )
+                && ( ( '*' == aCcstruct.iString[i] )
+                && ( '+' == aCcstruct.iString[i + 1] ) ) )
+                {
+                tonNpi = KTonNpiInternational;
+                }
+            // Procedure is finished by #
+            // If * is not found -> no number found
+            else if ( ( i < aCcstruct.iString.Length() )
+                    && ('#' == aCcstruct.iString[i] ) )
+                {
+                tonNpi = KNoTonNpi;
+                }
+            // Additional check for (**) "double star" case
+            else if ( ( ( i + 1 )  < aCcstruct.iString.Length() )
+                    && ( '*' == aCcstruct.iString[i] )
+                    && ( '*' == aCcstruct.iString[i + 1] ) )
+                {
+                // ** means there is an additional SIB field included,
+                // but SIA (number) is empty
+                // PhoneNumber is not present
+                tonNpi = KNoTonNpi;
+                }
+            // All other compinations shall result the "unknown" ton/npi
+            else
+                {
+                // Number is found but its tonnpi is unknown
+                tonNpi = KTonNpiUnknown;
+                }
+            }
+        else
+            {
+            //With all other SS codes TON/NPI is set to 0xff
+            tonNpi = KNoTonNpi;
+            }
+        }
+    else
+        {
+        // TonNpi is resolved from SEND SS proactive command
+        tonNpi = iTonNpiForSS;
+        }
+    iTonNpiPresent = EFalse;
+
+    envelope.AddByte( tonNpi );
+
+    TBuf8<255> ss;
+    TSatUtility::AsciiToBCD( aCcstruct.iString, ss );
+    envelope.AddData( ss );
+    // location information
+    AddLocationInformationToTlv( envelope );
+    // send it away...
+    return iSatMessHandler->UiccCatReqEnvelope(
+        aCcstruct.iTransId,
+        envelope.End());
+    }
+
+
+// -----------------------------------------------------------------------------
+// CSatCC::SendUSSDEnvelope
+// Sends call control USSD envelope
+// -----------------------------------------------------------------------------
+//
+TInt CSatCC::SendUSSDEnvelope
+        (
+        const TCallControl& aCcstruct //Structure containing call event info
+        )
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_SENDUSSDENVELOPE, "CSatCC::SendUSSDEnvelope" );
+
+    TInt ret( KErrNone );
+    // create envelope
+    TTlv envelope;
+    envelope.Begin( KBerTlvCallControlTag );
+
+    // device identities
+    envelope.AddTag( KTlvDeviceIdentityTag );
+    envelope.AddByte( KMe );
+    envelope.AddByte( KSim );
+
+    // USSD string tlv supported
+    if ( iUssdTlvSupported )
+        {
+        envelope.AddTag( KTlvUssdStringTag );
+        envelope.AddByte( aCcstruct.iUssdCodingInfo );
+        envelope.AddData( aCcstruct.iUssdString );
+        AddLocationInformationToTlv( envelope );
+
+        ret = iSatMessHandler->UiccCatReqEnvelope(
+            aCcstruct.iTransId,
+            envelope.End() );
+        }
+    else
+        {
+        // UssdTlv is not supported by the SIM, with Call control
+        // Checks whether the USSD string can be coded in the SS obj. SS obj.
+        // can only contain "*", "#", and the numbers 0-9.
+        if ( IsOnlyDigitsInUssd( aCcstruct.iUssdString ) )
+            {
+            envelope.AddTag( KTlvSsStringTag );
+            // If the Dialling Number/SSC String does not contain a dialling
+            // number e.g. a control string deactivating a service, the
+            // TON/NPI byte shall be set to 'FF' by the ME (see note
+            // 3GPP TS 11.11). in this case TON & NPI must be set to 0xFF
+            envelope.AddByte( 0xFF );
+            TBuf8<255> ss;
+            TSatUtility::AsciiToBCD( aCcstruct.iUssdString, ss );
+            envelope.AddData( ss );
+            AddLocationInformationToTlv( envelope );
+
+            ret = iSatMessHandler->UiccCatReqEnvelope(
+                aCcstruct.iTransId,
+                envelope.End());
+            }
+        else
+            {
+            // SIM does not support USSD and converting it to SS was
+            // impossible. Remove the created CcStruct from the CC array and
+            // send CC event response.
+            TPtrC8 atkData;
+            SendSsResourceControlReq( aCcstruct, KError, atkData );
+            
+            TInt index( GetArrayIndexById( aCcstruct.iTransId ) );
+            if ( index != KErrNotFound )
+                {
+                iCallControlArray->Remove( index );
+                iCallControlArray->Compress();
+                }
+            }
+        }
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::SendCallEnvelope
+// Sends call control call envelope
+// -----------------------------------------------------------------------------
+//
+TInt CSatCC::SendCallEnvelope
+        (
+        const TIsiReceiveC& aIsiMessage,
+        const TCallControl& aCallControl //Structure containing call event info
+        )
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_SENDCALLENVELOPE, "CSatCC::SendCallEnvelope" );
+
+    // create envelope
+    TTlv envelope;
+    envelope.Begin( KBerTlvCallControlTag );
+    // device identities
+    envelope.AddTag( KTlvDeviceIdentityTag );
+    envelope.AddByte( KMe );
+    envelope.AddByte( KSim );
+    // address is mandatory
+    TInt addressLength( 0 );
+    TUint sbStartOffset( 0 );
+
+    TInt retValue( aIsiMessage.FindSubBlockOffsetById(
+       ISI_HEADER_SIZE + SIZE_CALL_MODEM_RESOURCE_IND ,
+       CALL_MODEM_SB_DESTINATION_ADDRESS,
+       EIsiSubBlockTypeId8Len8,
+       sbStartOffset ) );
+    
+    if ( KErrNone == retValue )
+        {
+        envelope.AddTag( KTlvAddressTag );
+        envelope.AddByte( KMSBMask | aCallControl.iAddressType );
+        // Unicode address must be converted to BCD number
+        TBuf8<123> address;
+        TSatUtility::AsciiToBCD( aCallControl.iString, address );
+        envelope.AddData( address );
+        }
+    // In Nokia context BC is mandatory
+    envelope.AddTag( KTlvCapabilityConfigurationParametersTag );
+    // Length of actual BC information element
+    envelope.AddByte( aCallControl.iBearerCapabilities.Length() );
+    envelope.AddData( aCallControl.iBearerCapabilities );
+    // If subaddress present
+    retValue = aIsiMessage.FindSubBlockOffsetById(
+          ISI_HEADER_SIZE + SIZE_CALL_MODEM_RESOURCE_IND ,
+          CALL_MODEM_SB_DESTINATION_SUBADDRESS,
+          EIsiSubBlockTypeId8Len8,
+          sbStartOffset );
+    if ( KErrNone == retValue )
+        {
+        envelope.AddTag( KTlvSubaddressTag );
+        // Subaddress is given in same form as expected in envelope
+        addressLength = aIsiMessage.Get8bit( sbStartOffset + 
+            CALL_MODEM_SB_DESTINATION_SUBADDRESS_OFFSET_ADDRLEN );
+        envelope.AddData( aIsiMessage.GetData( sbStartOffset + 
+            CALL_MODEM_SB_DESTINATION_SUBADDRESS_OFFSET_ADDR, 
+            addressLength ) );
+        }
+    // Add mandatory location information
+    AddLocationInformationToTlv( envelope );
+    // send it away..
+    return iSatMessHandler->UiccCatReqEnvelope(
+        aCallControl.iTransId,
+        envelope.End() );
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::SendPdpContextActivationEnvelope
+// Sends Call Control PDP context activation envelope
+// -----------------------------------------------------------------------------
+//
+TInt CSatCC::SendPdpContextActivationEnvelope
+        (
+        const TUint8 aPdpCcEnvelopeTid,
+        const TDesC8& aPdpContextActivationParams
+        )
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_SENDPDPCONTEXTACTIVATIONENVELOPE, "CSatCC::SendPdpContextActivationEnvelope" );
+    TFLOGSTRING( "TSY: CSatCC::SendPdpContextActivationEnvelope" );
+    // Create envelope
+    TTlv envelope;
+    envelope.Begin( KBerTlvCallControlTag );
+    // Add Device identities
+    envelope.AddTag( KTlvDeviceIdentityTag );
+    envelope.AddByte( KMe);
+    envelope.AddByte( KSim);
+    // Add PDP context activation parameters
+    envelope.AddTag ( KTlvPdpContextActivationParametersTag );
+    envelope.AddData( aPdpContextActivationParams );
+    // Add location information
+    AddLocationInformationToTlv( envelope );
+    // send it away..
+    return iSatMessHandler->UiccCatReqEnvelope( aPdpCcEnvelopeTid,
+        envelope.End() );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CSatCC::UiccCatRespEnvelopeReceived
+// Handler function of incoming call control related data notification messages
+// -----------------------------------------------------------------------------
+//
+void CSatCC::UiccCatRespEnvelopeReceived( const TIsiReceiveC& aIsiMessage )
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_UICCCATRESPENVELOPERECEIVED, "CSatCC::UiccCatRespEnvelopeReceived" );
+    TFLOGSTRING( "TSY:CSatCC::UiccCatRespEnvelopeReceived" );
+
+    TUint8 status( aIsiMessage.Get8bit(
+        ISI_HEADER_SIZE + UICC_CAT_RESP_OFFSET_STATUS ) );
+    TUint8 transId( aIsiMessage.Get8bit( ISI_HEADER_OFFSET_TRANSID ) );
+
+    if ( UICC_STATUS_OK  == status )
+        {
+        TUint uiccSbApduOffset( 0 );
+        if ( KErrNone == aIsiMessage.FindSubBlockOffsetById(
+            ISI_HEADER_SIZE + SIZE_UICC_CAT_RESP,
+            UICC_SB_APDU,
+            EIsiSubBlockTypeId16Len16,
+            uiccSbApduOffset ) )
+            {
+            TPtrC8 apduData;
+            TUint16 apduLength( aIsiMessage.Get16bit(
+                uiccSbApduOffset + UICC_SB_APDU_OFFSET_APDULENGTH ) );
+            apduData.Set( aIsiMessage.GetData(
+                uiccSbApduOffset + UICC_SB_APDU_OFFSET_APDU,
+                apduLength ) );
+            // Status bytes are two last bytes in APDU
+            TUint8 sw1( apduData[apduLength - 2] );
+            TUint8 sw2( apduData[apduLength - 1] );
+
+            // Get Call Control General Result
+            TInt result( TSatUtility::Sw1Sw2Check( sw1, sw2 ) );
+
+            // This msg comes for envelope, terminal response and
+            // terminal profile. So let's check first if this response is for
+            // CC event by comparing transaction id with the one used when
+            // sending the CC event envelope.
+            TInt ccIndex( GetArrayIndexById( transId ) );
+
+            // This is a response to either Voice Call, SS or USSD CC envelope
+            if ( ccIndex != KErrNotFound )
+                {
+                switch( ( *iCallControlArray )[ccIndex].iRecourceId )
+                    {
+                    case PN_MODEM_CALL:
+                        {
+                        SendCallModemResourceReq(
+                            ( *iCallControlArray )[ccIndex],
+                            result,
+                            apduData );
+                        break;
+                        }
+                    case PN_SS:
+                        {
+                        SendSsResourceControlReq(
+                            ( *iCallControlArray )[ccIndex],
+                            result,
+                            apduData );
+                        break;
+                        }
+                    case PN_GPDS:
+                        {
+                        SendGpdsResourceControlReq(
+                            ( *iCallControlArray )[ccIndex],
+                            result,
+                            apduData );
+                        break;
+                        }
+                    default:
+                        {
+                        break;
+                        }
+                    } // End of switch
+                iCallControlArray->Remove( ccIndex );
+                iCallControlArray->Compress();
+                } // End of if ( ccIndex != KErrNotFound )
+            }
+        else // Subblock is mandatory
+            {
+            TFLOGSTRING("TSY: CSatMessHandler::UiccCatRespEnvelopeReceived - Mandatory subblock UICC_SB_APDU not found");
+            OstTrace0( TRACE_NORMAL, DUP1_CSATCC_UICCCATRESPENVELOPERECEIVED, "CSatCC::UiccCatRespEnvelopeReceived - Mandatory subblock UICC_SB_APDU not found" );
+            }
+        } // End of if ( UICC_STATUS_OK  == status )
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::ClearArraysForRefresh
+// Clears the array containing call control event data due refresh.
+// Empiric studies show that transaction id count starts from beginning
+// in SIMSON after refresh and therefore possible incoming responses
+// for call control are no longer recognizable.
+// -----------------------------------------------------------------------------
+//
+void CSatCC::ClearArraysForRefresh()
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_CLEARARRAYSFORREFRESH, "CSatCC::ClearArraysForRefresh" );
+    TFLOGSTRING("TSY: CSatCC::ClearArraysForRefresh");
+
+    iCallControlArray->Reset();
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::SetStatusOfUssdSupport
+// Set internal flag according to EF-SST
+// -----------------------------------------------------------------------------
+//
+void CSatCC::SetStatusOfUssdSupport
+        (
+        TBool aStatus
+        )
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_SETSTATUSOFUSSDSUPPORT, "CSatCC::SetStatusOfUssdSupport" );
+    TFLOGSTRING("TSY: CSatCC::SetStatusOfUssdSupport");
+    iUssdTlvSupported = aStatus;
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::IsOnlyDigitsInUssd
+// This methods returns ETrue when a Ussd string contains only "*", "#",
+// and the numbers 0-9.
+// Note: Ussd string is always received in packed format, when  it 7-bit GSM
+// default alphabet.
+// -----------------------------------------------------------------------------
+//
+TBool CSatCC::IsOnlyDigitsInUssd
+        (
+        TPtrC8 aUSSDString
+        )
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_ISONLYDIGITSINUSSD, "CSatCC::IsOnlyDigitsInUssd" );
+    TFLOGSTRING("TSY: CSatCC::IsOnlyDigitsInUssd");
+
+    // Unpack it
+    TBuf8<256> ussdString;
+    TSatUtility::Packed7to8Unpacked( aUSSDString, ussdString );
+
+    TBool ret( ETrue );
+    for( TInt k=0; k < ussdString.Length(); k++)
+        {
+        if ( ussdString[k]!='#' &&
+             ussdString[k]!='*' &&
+             ussdString[k]!='+' &&
+             ( ussdString[k]<'0'  ||
+             ussdString[k]>'9' ) )
+            {
+            ret = EFalse;
+            break;
+            }
+        }
+
+    return ret;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CSatCC::MessageReceivedL
+// Handle received messages related to event download
+// Called by CSatMessHandler::MessageReceivedL, when a new ISI message arrives.
+// -----------------------------------------------------------------------------
+//
+void CSatCC::MessageReceivedL
+        (
+        const TIsiReceiveC& aIsiMessage
+        )
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_MESSAGERECEIVEDL, "CSatCC::MessageReceivedL" );
+    TFLOGSTRING("TSY: CSatCC::MessageReceivedL");
+
+    TUint8 resource( aIsiMessage.Get8bit( ISI_HEADER_OFFSET_RESOURCEID ) );
+    TUint8 messageId( aIsiMessage.Get8bit( ISI_HEADER_OFFSET_MESSAGEID ) );
+
+
+    if ( PN_MODEM_CALL == resource )
+        {
+        switch( messageId )
+            {
+            case CALL_MODEM_RESOURCE_IND:
+                {
+                CallModemResourceInd( aIsiMessage );
+                break;
+                }
+            case CALL_MODEM_RESOURCE_CONF_IND:
+                {
+    TFLOGSTRING("TSY: CSatCC::MessageReceived, CALL_MODEM_RESOURCE_CONF_IND");
+    OstTrace0( TRACE_NORMAL, DUP1_CSATCC_MESSAGERECEIVED, "TSY: CSatCC::MessageReceived, CALL_MODEM_RESOURCE_CONF_IND" );
+                
+                if ( CALL_MODEM_RES_CONF_STARTUP == 
+                    aIsiMessage.Get8bit( ISI_HEADER_SIZE + 
+                        CALL_MODEM_RESOURCE_CONF_IND_OFFSET_CONFSTATUS ) )
+                    {
+                    // configure resource control if CC enabled in (U)SIM
+                    // MT call is always controlled by NTSY
+                    if ( iCallControlEnabled )
+                        {
+                        iSatMessHandler->CallModemResourceConfReq(
+                            CALL_MODEM_RES_ID_MO_INIT |
+                            CALL_MODEM_RES_ID_MT_INIT,
+                            CALL_MODEM_RES_ID_MASK_MO_INIT |
+                            CALL_MODEM_RES_ID_MASK_MT_INIT );
+                        }
+                    else
+                        {
+                        iSatMessHandler->CallModemResourceConfReq(
+                            CALL_MODEM_RES_ID_MT_INIT,
+                            CALL_MODEM_RES_ID_MASK_MT_INIT );
+                        }
+                    }
+                break;
+                }
+            case CALL_MODEM_RESOURCE_CONF_RESP:
+                {
+    TFLOGSTRING("TSY: CSatCC::MessageReceived, CALL_MODEM_RESOURCE_CONF_RESP");
+    OstTrace0( TRACE_NORMAL, DUP2_CSATCC_MESSAGERECEIVED, "TSY: CSatCC::MessageReceived, CALL_MODEM_RESOURCE_CONF_RESP" );
+    
+                if ( CALL_MODEM_RES_CONF_SET == 
+                    aIsiMessage.Get8bit( ISI_HEADER_SIZE + 
+                        CALL_MODEM_RESOURCE_CONF_RESP_OFFSET_CONFOPERATION ) )
+                    {
+    TFLOGSTRING("TSY: CSatCC::MessageReceived, CALL_MODEM_RESOURCE_CONF_RESP Resource configured");
+    OstTrace0( TRACE_NORMAL, DUP3_CSATCC_MESSAGERECEIVED, "TSY: CSatCC::MessageReceived, CALL_MODEM_RESOURCE_CONF_RESP Resource configured" );
+    
+                    }
+                break;
+                }
+            case CALL_MODEM_RESOURCE_RESP:
+                {
+    TFLOGSTRING("TSY: CSatCC::MessageReceived, CALL_MODEM_RESOURCE_RESP Resource control sequence done");
+    OstTrace0( TRACE_NORMAL, DUP4_CSATCC_MESSAGERECEIVED, "TSY: CSatCC::MessageReceived, CALL_MODEM_RESOURCE_RESP Resource control sequence done" );
+    
+                break;
+                }
+            default:
+                {
+                // none
+                break;
+                }
+
+            }
+        }
+    else if ( PN_SS == resource )
+        {
+        switch( messageId )
+            {
+            case SS_RESOURCE_CONTROL_IND:
+                {
+                SsResourceControlInd( aIsiMessage );
+                break;
+                }
+            case SS_RESOURCE_CONF_IND:
+                {
+    TFLOGSTRING("TSY: CSatCC::MessageReceived, SS_RESOURCE_CONF_IND");
+    OstTrace0( TRACE_NORMAL, DUP5_CSATCC_MESSAGERECEIVED, "TSY: CSatCC::MessageReceived, SS_RESOURCE_CONF_IND" );
+    
+                if ( SS_RESOURCE_CONF_READY  == 
+                    aIsiMessage.Get8bit( ISI_HEADER_SIZE + 
+                        SS_RESOURCE_CONF_IND_OFFSET_CONFSTATUS  ) )
+                    {
+                    // configure resource control if CC enabled in (U)SIM
+                    if ( iCallControlEnabled )
+                        {
+                        iSatMessHandler->SsResourceConfReq();
+                        }
+                    }
+                break;
+                }
+            case SS_RESOURCE_CONF_RESP:
+                {
+                if ( SS_RESOURCE_CONF_SET == 
+                        aIsiMessage.Get8bit( ISI_HEADER_SIZE + 
+                            SS_RESOURCE_CONF_RESP_OFFSET_CONFOPERATION  ) )
+                    {
+    TFLOGSTRING("TSY: CSatCC::MessageReceived, SS_RESOURCE_CONF_RESP Resource configured");
+    OstTrace0( TRACE_NORMAL, DUP6_CSATCC_MESSAGERECEIVED, "TSY: CSatCC::MessageReceived, SS_RESOURCE_CONF_RESP Resource configured" );
+    
+                    }
+                break;
+                }
+            case SS_STATUS_IND:
+                {
+                TUint8 status( aIsiMessage.Get8bit( ISI_HEADER_SIZE + 
+                    SS_STATUS_IND_OFFSET_SSSTATUSINDICATION  ) );
+
+                if ( SS_STATUS_REQUEST_SERVICE_FAILED == status
+                    || SS_GSM_STATUS_REQUEST_USSD_FAILED )
+                    {
+                    if( iEnvelopeResponseData )
+                        {
+                        iSatMessaging->NotifyClientAboutCallControlEventL(
+                            iCcResult,
+                            iEnvelopeResponseData->Des() );
+                        // Delete temporarily stored envelope response data
+                        delete iEnvelopeResponseData;
+                        // No matter what the response was, set related data to
+                        // init values
+                        iCcResult = KAllowed;
+                        }
+                    }
+                break;
+                }
+            default:
+                {
+                // none
+                break;
+                }
+            }
+        }
+    else if ( PN_GPDS == resource )
+        {
+        switch( messageId )
+            {
+            case GPDS_RESOURCE_CONTROL_IND:
+                {
+                GpdsResourceControlInd( aIsiMessage );
+                break;
+                }
+            case GPDS_RESOURCE_CONTROL_RESP:
+                {
+    TFLOGSTRING("TSY: CSatCC::MessageReceived, GPDS_RESOURCE_CONTROL_RESP Resource control sequence done");
+    OstTrace0( TRACE_NORMAL, DUP7_CSATCC_MESSAGERECEIVED, "TSY: CSatCC::MessageReceived, GPDS_RESOURCE_CONTROL_RESP Resource control sequence done" );
+
+                break;
+                }
+            case GPDS_RESOURCE_CONF_IND:
+                {
+    TFLOGSTRING("TSY: CSatCC::MessageReceived, GPDS_RESOURCE_CONF_IND");
+    OstTrace0( TRACE_NORMAL, DUP8_CSATCC_MESSAGERECEIVED, "TSY: CSatCC::MessageReceived, GPDS_RESOURCE_CONF_IND" );
+
+                if ( iCallControlOnGPRSEnabled )
+                    {
+                    iSatMessHandler->GpdsResourceConfReq();
+                    }
+                break;
+                }
+            case GPDS_RESOURCE_CONF_RESP:
+                {
+                if ( GPDS_RESOURCE_CONF_SET == 
+                        aIsiMessage.Get8bit( ISI_HEADER_SIZE + 
+                            GPDS_RESOURCE_CONF_RESP_OFFSET_CONFOPERATION  ) )
+                    {
+    TFLOGSTRING("TSY: CSatCC::MessageReceived, GPDS_RESOURCE_CONF_RESP Resource configured");
+    OstTrace0( TRACE_NORMAL, DUP9_CSATCC_MESSAGERECEIVED, "TSY: CSatCC::MessageReceived, GPDS_RESOURCE_CONF_RESP Resource configured" );
+
+                    }
+                break;
+                }
+            default:
+                {
+                // none
+                break;
+                }
+            }
+        }
+    else if ( PN_UICC == resource )
+        {
+        switch( messageId )
+            {
+            case UICC_APPL_CMD_RESP:
+                {
+                TUint8 trId( aIsiMessage.Get8bit(
+                    ISI_HEADER_SIZE + UICC_APPL_CMD_RESP_OFFSET_TRANSID ) );
+                TUint8 status( aIsiMessage.Get8bit( ISI_HEADER_SIZE +
+                    UICC_APPL_CMD_RESP_OFFSET_STATUS ) );
+                TUint8 serviceType( aIsiMessage.Get8bit( ISI_HEADER_SIZE +
+                    UICC_APPL_CMD_RESP_OFFSET_SERVICETYPE ) );
+                // Card type
+                TUint8 cardType( aIsiMessage.Get8bit(
+                    ISI_HEADER_SIZE + UICC_APPL_CMD_RESP_OFFSET_CARDTYPE ) );
+
+                if ( UICC_STATUS_OK == status &&
+                    UICC_APPL_READ_TRANSPARENT == serviceType )
+                    {
+                    // Read file data from UICC_SB_FILE_DATA
+                    TInt fileDataLength( 0 );
+                    TPtrC8 fileData;
+                    TUint uiccSbFileDataOffset( 0 );
+                    if ( KErrNone == aIsiMessage.FindSubBlockOffsetById(
+                        ISI_HEADER_SIZE + SIZE_UICC_APPL_CMD_RESP,
+                        UICC_SB_FILE_DATA,
+                        EIsiSubBlockTypeId16Len16,
+                        uiccSbFileDataOffset ) )
+                        {
+                        fileDataLength = aIsiMessage.Get32bit(
+                            uiccSbFileDataOffset + UICC_SB_FILE_DATA_OFFSET_DATALENGTH );
+                        fileData.Set( aIsiMessage.GetData(
+                            uiccSbFileDataOffset + UICC_SB_FILE_DATA_OFFSET_DATA,
+                            fileDataLength ) );
+                        // Check call control status
+                        if ( KUiccTrIdServiceTableByte4 == trId )
+                            {
+                            TUint8 usedBitMaskCallControl( KCallControlBitMaskUsim );
+                            if ( UICC_CARD_TYPE_ICC == cardType )
+                                {
+                                usedBitMaskCallControl = KCallControlBitMaskSim;
+                                }
+                            // Bit 6 is the status bit of call control
+                            if ( fileData[0] & usedBitMaskCallControl )
+                                {
+                                // Call control enabled in (U)SIM
+                                iCallControlEnabled = ETrue;
+                                iSatMessHandler->CallModemResourceConfReq(
+                                    CALL_MODEM_RES_ID_MO_INIT |
+                                    CALL_MODEM_RES_ID_MT_INIT,
+                                    CALL_MODEM_RES_ID_MASK_MO_INIT |
+                                    CALL_MODEM_RES_ID_MASK_MT_INIT );
+                                iSatMessHandler->SsResourceConfReq();
+                                }
+                             else
+                                {
+                                // Call control disabled in (U)SIM
+                                iCallControlEnabled = EFalse;
+                                iSatMessHandler->CallModemResourceConfReq(
+                                    CALL_MODEM_RES_ID_MT_INIT,
+                                    CALL_MODEM_RES_ID_MASK_MT_INIT );
+                                }
+                            }
+                        // Check call control GPRS status
+                        else if ( KUiccTrIdServiceTableByte7 == trId )
+                            {
+                            if ( fileData[0] & KCallControlBitMaskUsim )
+                                {
+                                // Call control on GPRS enabled in USIM
+                                iCallControlOnGPRSEnabled = ETrue;
+                                iSatMessHandler->GpdsResourceConfReq();
+                                }
+                            else
+                                {
+                                // Call control on GPRS disabled in USIM
+                                iCallControlOnGPRSEnabled = EFalse;
+                                }
+                            }
+                        }
+                    else // Subblock is mandatory
+                        {
+                        TFLOGSTRING("TSY: CSatCC::MessageReceivedL - Mandatory subblock UICC_SB_FILE_DATA not found");
+                        OstTrace0( TRACE_NORMAL, DUP1_CSATCC_MESSAGERECEIVEDL, "CSatCC::MessageReceivedL - - Mandatory subblock UICC_SB_FILE_DATA not found" );
+                        }
+                    } // End of if ( UICC_STATUS_OK == status
+                break;
+                } // End of case UICC_APPL_CMD_RESP
+            case UICC_CAT_RESP:
+                {
+                // In case of envelope response handle the data
+                TUint8 serviceType(
+                    aIsiMessage.Get8bit(
+                        ISI_HEADER_SIZE + UICC_CAT_RESP_OFFSET_SERVICETYPE ) );
+                if ( UICC_CAT_ENVELOPE == serviceType )
+                    {
+                    UiccCatRespEnvelopeReceived( aIsiMessage );
+                    }
+                break;
+                }
+            default:
+                {
+                break;
+                }
+            } // End of switch( messageId )
+        } // End of else if ( PN_UICC == resource )
+    // No else
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::SetTonNpi
+// Set CSatCC internal Ton and Npi
+// Called by CTsySatMessaging::SetTonNpi when SEND SS proactive command arrives
+// -----------------------------------------------------------------------------
+//
+void CSatCC::SetTonNpi
+        (
+        const TUint8 aTonNpi
+        )
+    {
+    OstTrace0( TRACE_NORMAL, CSATCC_SETTONNPI, "CSatCC::SetTonNpi" );
+    TFLOGSTRING("TSY: CSatCC::SetTonNpi");
+
+    iTonNpiForSS = aTonNpi;
+    iTonNpiPresent = ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::CallModemResourceInd
+// Handles resource control request from modem Call server
+// -----------------------------------------------------------------------------
+//
+void CSatCC::CallModemResourceInd( const TIsiReceiveC& aIsiMessage )
+    {
+    TFLOGSTRING("TSY: CSatCC::CallModemResourceInd");
+    OstTrace0( TRACE_NORMAL, CSATCC_CALLMODEMRESOURCEIND, "CSatCC::CallModemResourceInd" );
+
+    TUint sbStartOffset( 0 );
+    // Check if resource control is requested for MO call.
+
+    TInt retValue( aIsiMessage.FindSubBlockOffsetById(
+           ISI_HEADER_SIZE + SIZE_CALL_MODEM_RESOURCE_IND ,
+           CALL_MODEM_SB_RESOURCE,
+           EIsiSubBlockTypeId8Len8,
+           sbStartOffset ) );
+
+    if ( KErrNone == retValue 
+        && CALL_MODEM_RES_ID_MO_INIT & aIsiMessage.Get16bit( sbStartOffset +
+            CALL_MODEM_SB_RESOURCE_OFFSET_RES  ) )
+        {
+        TCallControl callcontrol;
+        // store traid's
+        callcontrol.iTransId = aIsiMessage.Get8bit( ISI_HEADER_SIZE + 
+            CALL_MODEM_RESOURCE_IND_OFFSET_TRID );
+        callcontrol.iRecourceId = aIsiMessage.Get8bit(
+            ISI_HEADER_OFFSET_RESOURCEID);
+        callcontrol.iCallId = aIsiMessage.Get8bit( ISI_HEADER_SIZE + 
+            CALL_MODEM_RESOURCE_IND_OFFSET_CALLID );
+
+        retValue = aIsiMessage.FindSubBlockOffsetById(
+           ISI_HEADER_SIZE + SIZE_CALL_MODEM_RESOURCE_IND ,
+           CALL_MODEM_SB_RESOURCE_SEQ_ID,
+           EIsiSubBlockTypeId8Len8,
+           sbStartOffset );
+        if( KErrNone == retValue )
+            {
+            callcontrol.iResourceSeqId = aIsiMessage.Get8bit( sbStartOffset + 
+                CALL_MODEM_SB_RESOURCE_SEQ_ID_OFFSET_SEQUENCEID );
+            }
+
+        retValue = aIsiMessage.FindSubBlockOffsetById(
+            ISI_HEADER_SIZE + SIZE_CALL_MODEM_RESOURCE_IND ,
+            CALL_MODEM_SB_MODE,
+            EIsiSubBlockTypeId8Len8,
+            sbStartOffset );
+        if( KErrNone == retValue )
+            {
+            callcontrol.iCallMode.Append( aIsiMessage.Get8bit( sbStartOffset + 
+                CALL_MODEM_SB_MODE_OFFSET_MODE ) );
+            callcontrol.iCallMode.Append( aIsiMessage.Get8bit( sbStartOffset + 
+                CALL_MODEM_SB_MODE_OFFSET_MODEINFO ) );
+            }
+
+        retValue = aIsiMessage.FindSubBlockOffsetById(
+            ISI_HEADER_SIZE + SIZE_CALL_MODEM_RESOURCE_IND ,
+            CALL_MODEM_SB_BC,
+            EIsiSubBlockTypeId8Len8,
+            sbStartOffset );
+        if( KErrNone == retValue )
+            {
+            TInt bearerLength( aIsiMessage.Get8bit( sbStartOffset +
+                CALL_MODEM_SB_BC_OFFSET_BCLENGTH ) );
+            
+            callcontrol.iBearerCapabilities.Copy( aIsiMessage.GetData( 
+                sbStartOffset + CALL_MODEM_SB_BC_OFFSET_BCDATA,
+                bearerLength ) );
+            }
+
+        retValue = aIsiMessage.FindSubBlockOffsetById(
+           ISI_HEADER_SIZE + SIZE_CALL_MODEM_RESOURCE_IND ,
+           CALL_MODEM_SB_DESTINATION_ADDRESS,
+           EIsiSubBlockTypeId8Len8,
+           sbStartOffset );
+
+        if( KErrNone == retValue )
+            {
+            callcontrol.iAddressType = aIsiMessage.Get8bit( sbStartOffset +
+                CALL_MODEM_SB_DESTINATION_ADDRESS_OFFSET_ADDRTYPE );
+            TUint8 addressLength( aIsiMessage.Get8bit( sbStartOffset +
+                CALL_MODEM_SB_DESTINATION_ADDRESS_OFFSET_ADDRLEN ) );
+            callcontrol.iString.Copy( aIsiMessage.GetData( sbStartOffset + 
+                CALL_MODEM_SB_DESTINATION_ADDRESS_OFFSET_ADDR,
+                addressLength * 2 ) );
+            }
+
+        if( CALL_MODEM_MODE_EMERGENCY == callcontrol.iCallMode[0] )
+            {
+            // Do not make SIM call control, allow emergency calls always
+            TPtrC8 atkData;
+            SendCallModemResourceReq(
+                callcontrol,
+                KAllowed,
+                atkData );
+            }
+        else
+            {
+            // store struct
+            iCallControlArray->Append( callcontrol );
+            // Send envelope
+            SendCallEnvelope( aIsiMessage, callcontrol );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::SendCallModemResourceReq
+// Creates resource control response for modem Call server
+// -----------------------------------------------------------------------------
+//
+void CSatCC::SendCallModemResourceReq(
+    const TCallControl& aTcc,
+    const TUint8 aResult,
+    TPtrC8 aApduData )
+    {
+    TFLOGSTRING("TSY: CSatCC::SendCallModemResourceReq");
+    OstTrace0( TRACE_NORMAL, CSATCC_SENDCALLMODEMRESOURCEREQ, "CSatCC::SendCallModemResourceReq" );
+
+    TBuf8<KMaximumCcBufferSize> isiMessage;
+    TInt ret( KErrNotFound );
+    CBerTlv response;
+    response.SetData( aApduData );
+    // Set initial cc result, e.g. the SIM has responded with sw1/sw2 90 00
+    // without any additional data. In error case reject the initiated action.
+    TUint8 ccresult( KAllowed == aResult ?
+        KCcResultAllowedNoModification : KCcResultNotAllowed );
+    // if result provided in SIM response
+    if ( KCcEmptyResponseLenght < aApduData.Length() )
+        {
+        ccresult = aApduData[ 0 ];
+        }
+    // Internal call control result
+    TUint8 internalCcResult( KAllowed );
+    // CALL_MODEM_RESOURCE_REQ has 5 mandatory sb's
+    TUint8 sbcount( 5 );
+
+    // Add mandatory data
+    // Modem Call ID [M]: the unique call ID or CALL_ID_NONE.
+    isiMessage.Append( aTcc.iCallId );
+    // CALL_MODEM_SB_RESOURCE [M]: resource. Shall be same as in the corresponding indication.
+    TIsiSubBlock resource( 
+        isiMessage,
+        CALL_MODEM_SB_RESOURCE,
+        EIsiSubBlockTypeId8Len8 );
+    TSatUtility::AppendWord( CALL_MODEM_RES_ID_MO_INIT, isiMessage );
+    resource.CompleteSubBlock();
+    
+    // CALL_MODEM_SB_RESOURCE_SEQ_ID [M]: Sequence ID. Shall be same as in the corresponding indication.
+    TIsiSubBlock resourceSeqId( 
+        isiMessage,
+        CALL_MODEM_SB_RESOURCE_SEQ_ID,
+        EIsiSubBlockTypeId8Len8 );
+    isiMessage.Append( aTcc.iResourceSeqId  );
+    isiMessage.Append( KPadding );
+    resourceSeqId.CompleteSubBlock();
+
+    // CALL_MODEM_SB_RESOURCE_STATUS [M]: resource status is allowed or denied.
+    TIsiSubBlock status(
+        isiMessage,
+        CALL_MODEM_SB_RESOURCE_STATUS,
+        EIsiSubBlockTypeId8Len8 );
+
+    switch( ccresult )
+        {
+        case KCcResultAllowedNoModification:
+            {
+            isiMessage.Append( CALL_MODEM_RESOURCE_ALLOWED );
+            isiMessage.Append( KPadding );
+            break;
+            }
+        case KCcResultNotAllowed:
+            {
+            isiMessage.Append( CALL_MODEM_RESOURCE_DENIED );
+            isiMessage.Append( KPadding );
+            internalCcResult = KRejected;
+            break;
+            }
+        case KCcResultAllowedWithModifications:
+            {
+            // First check if this has been modified to a new SS/USSD action
+            CTlv ssServerString;
+            
+            if ( KErrNone == response.TlvByTagValue( &ssServerString, 
+                KTlvSsStringTag ) ||
+                KErrNone == response.TlvByTagValue( &ssServerString,
+                KTlvUssdStringTag ) )
+                {
+                isiMessage.Append( CALL_MODEM_RESOURCE_DENIED );
+                isiMessage.Append( KPadding );
+                internalCcResult = KChanged;
+                }
+            else
+                {
+                // Other parameters have been changed
+                isiMessage.Append( CALL_MODEM_RESOURCE_ALLOWED );
+                isiMessage.Append( KPadding );
+                internalCcResult = KModified;
+                }
+            break;
+            }
+        default:
+            {
+            break;
+            }
+        }
+    status.CompleteSubBlock();
+
+    if ( KRejected == internalCcResult || KChanged == internalCcResult )
+        {
+        // CALL_MODEM_SB_CAUSE sb is needed in rejected cases
+        TIsiSubBlock cause( 
+            isiMessage,
+            CALL_MODEM_SB_CAUSE,
+            EIsiSubBlockTypeId8Len8 );
+        isiMessage.Append( CALL_MODEM_CAUSE_TYPE_CLIENT  );
+        isiMessage.Append( CALL_MODEM_CAUSE_NOT_ALLOWED );
+        cause.CompleteSubBlock();
+        sbcount++;
+        }
+    
+    // CALL_MODEM_SB_MODE [M]: call mode.
+    TIsiSubBlock mode( 
+        isiMessage,
+        CALL_MODEM_SB_MODE,
+        EIsiSubBlockTypeId8Len8 );
+    // 2 byte buffer
+    isiMessage.Append( aTcc.iCallMode );
+    mode.CompleteSubBlock();
+    
+    // CALL_MODEM_SB_BC [M]: Bearer Capabilities for the call.
+    TIsiSubBlock bearer( 
+        isiMessage,
+        CALL_MODEM_SB_BC,
+        EIsiSubBlockTypeId8Len8 );
+
+    // Check if (U)SIM has provided new bearer caps
+    CTlv bcTlv;
+    if ( KCcEmptyResponseLenght < aApduData.Length() &&
+        KErrNone == response.TlvByTagValue( &bcTlv,
+            KTlvCapabilityConfigurationParametersTag ) )
+        {
+        // BC length is the first byte in BC data
+        isiMessage.Append( bcTlv.GetData(
+            ETLV_CapabilityConfigurationParameters ) );
+        }
+    else
+        {
+        isiMessage.Append( aTcc.iBearerCapabilities.Length() );
+        isiMessage.Append( aTcc.iBearerCapabilities );
+        }
+    bearer.CompleteSubBlock();
+
+    TIsiSubBlock address( 
+        isiMessage,
+        CALL_MODEM_SB_DESTINATION_ADDRESS ,
+        EIsiSubBlockTypeId8Len8 );
+    // Check if request has been modified and therefore response includes
+    // additional data
+    if ( KModified == internalCcResult &&
+        ( KCcEmptyResponseLenght < aApduData.Length() ) )
+        {
+        CTlv addressTlv;
+        ret = response.TlvByTagValue( &addressTlv, KTlvAddressTag );
+        if ( KErrNone == ret  )
+            {
+            // CALL_MODEM_ADDRESS_TYPE, mask MSB off
+            isiMessage.Append( addressTlv.GetValue()[ 0 ] ^KMSBMask );
+            isiMessage.Append( KPadding );
+            isiMessage.Append( KPadding );
+            
+            // Temp storage for address
+            TBuf8<2 * KCallServerMaxAddressLenght> asciiAddress;
+            TSatUtility::BCDToAscii( addressTlv.GetValue().Mid( 1 ),
+                asciiAddress );
+
+            //add the number string as unicode.
+            TBuf16<KCallServerMaxAddressLenght> unicodeNumber;
+            TSatUtility::ConvertSms7ToUnicode16( unicodeNumber, asciiAddress );
+            TBuf8<2 * KCallServerMaxAddressLenght> temp;
+            TIsiUtility::CopyToBigEndian( unicodeNumber, temp );
+            
+            // Address length = Number of Unicode characters in address
+            isiMessage.Append( temp.Length()/2 );
+            isiMessage.Append( temp );
+            
+            address.CompleteSubBlock();
+            sbcount++;
+            }
+        
+        CTlv subAddressTlv;
+        ret = response.TlvByTagValue( &subAddressTlv, KTlvSubaddressTag );
+        if ( KErrNone == ret )
+            {
+            TIsiSubBlock subAddress( 
+                isiMessage,
+                CALL_MODEM_SB_DESTINATION_SUBADDRESS,
+                EIsiSubBlockTypeId8Len8 );
+            isiMessage.Append( subAddressTlv.GetLength() );
+            isiMessage.Append( subAddressTlv.GetData( ETLV_SubAddress ) );
+            subAddress.CompleteSubBlock();
+            sbcount++;
+            }
+        }
+    else
+        {
+        // use original destination address
+        isiMessage.Append( aTcc.iAddressType );
+        isiMessage.Append( KPadding );
+        isiMessage.Append( KPadding );
+        // Number of Unicode characters
+        isiMessage.Append( aTcc.iString.Length()/2 );
+        isiMessage.Append( aTcc.iString );
+        address.CompleteSubBlock();
+        sbcount++;
+        }
+
+    TBuf8<1> numOfSubblocks;
+    numOfSubblocks.Append( sbcount);
+    isiMessage.Insert( 1, numOfSubblocks );
+    // send request
+    iSatMessHandler->CallModemResourceReq( aTcc.iTransId, isiMessage );
+
+    if ( KCcEmptyResponseLenght < aApduData.Length() )
+        {
+        // Notify client about call control if alpha id present or original
+        // action has changed to new action
+        iSatMessaging->NotifyClientAboutCallControlEventL(
+            internalCcResult,
+            aApduData );
+        }
+   }
+
+// -----------------------------------------------------------------------------
+// CSatCC::SsResourceControlInd
+// Handles resource control request from modem SS server
+// -----------------------------------------------------------------------------
+//
+void CSatCC::SsResourceControlInd( const TIsiReceiveC& aIsiMessage )
+    {
+    TFLOGSTRING("TSY: CSatCC::SsResourceControlInd");
+    OstTrace0( TRACE_NORMAL, CSATCC_SSRESOURCECONTROLIND, "CSatCC::SsResourceControlInd" );
+
+    TCallControl callcontrol;
+    TInt stringLength;
+    // store traid's
+    callcontrol.iTransId = aIsiMessage.Get8bit( ISI_HEADER_SIZE + 
+        SS_RESOURCE_CONTROL_IND_OFFSET_TRANSID );    
+    callcontrol.iRecourceId = aIsiMessage.Get8bit(
+        ISI_HEADER_OFFSET_RESOURCEID);
+
+    TUint sbStartOffset( 0 );
+    TInt retValue( aIsiMessage.FindSubBlockOffsetById(
+       ISI_HEADER_SIZE + SIZE_SS_RESOURCE_CONTROL_IND,
+       SS_SB_RESOURCE_SEQ_ID,
+       EIsiSubBlockTypeId8Len8,
+       sbStartOffset ) );
+    
+    if( KErrNone == retValue )
+        {
+        callcontrol.iResourceSeqId = aIsiMessage.Get8bit( sbStartOffset + 
+            SS_SB_RESOURCE_SEQ_ID_OFFSET_SEQUENCEID );
+        }
+    
+    retValue = aIsiMessage.FindSubBlockOffsetById(
+        ISI_HEADER_SIZE + SIZE_SS_RESOURCE_CONTROL_IND,
+        SS_SB_SS_CONTROL,
+        EIsiSubBlockTypeId8Len8,
+        sbStartOffset );
+    
+    if( KErrNone == retValue )
+        {
+        stringLength = aIsiMessage.Get8bit( sbStartOffset +
+            SS_SB_SS_CONTROL_OFFSET_SSSTRINGLENGTH );
+        callcontrol.iString.Copy( aIsiMessage.GetData( 
+            sbStartOffset + SS_SB_SS_CONTROL_OFFSET_SSSTRING,
+            stringLength) );
+        }
+    
+    retValue = aIsiMessage.FindSubBlockOffsetById(
+        ISI_HEADER_SIZE + SIZE_SS_RESOURCE_CONTROL_IND,
+        SS_SB_USSD_CONTROL,
+        EIsiSubBlockTypeId8Len8,
+        sbStartOffset );
+    
+    if( KErrNone == retValue )
+        {
+        callcontrol.iUssdCodingInfo = aIsiMessage.Get8bit( sbStartOffset +
+            SS_SB_USSD_CONTROL_OFFSET_CODINGINFO );
+        stringLength = aIsiMessage.Get8bit( sbStartOffset +
+            SS_SB_USSD_CONTROL_OFFSET_USSDSTRINGLENGTH  );
+       
+        callcontrol.iUssdString.Copy( aIsiMessage.GetData( 
+            sbStartOffset + SS_SB_USSD_CONTROL_OFFSET_USSDSTRING,
+            stringLength ) );
+        }
+    // store struct
+    iCallControlArray->Append( callcontrol );
+    // Send envelope
+    if ( callcontrol.iString.Length() )
+        {
+        SendSSEnvelope( callcontrol );
+        }
+    else
+        {
+        SendUSSDEnvelope( callcontrol );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::SendSsResourceControlReq
+// Creates resource control response for modem SS server
+// -----------------------------------------------------------------------------
+//
+void CSatCC::SendSsResourceControlReq( 
+        const TCallControl& aTcc,
+        const TUint8 aResult,
+        TPtrC8 aApduData )
+    {
+    TFLOGSTRING("TSY: CSatCC::SendSsResourceControlReq");
+    OstTrace0( TRACE_NORMAL, CSATCC_SENDSSRESOURCECONTROLREQ, "CSatCC::SendSsResourceControlReq" );
+
+    TBuf8<KMaximumCcBufferSize> isiMessage;
+    CBerTlv response;
+    response.SetData( aApduData );
+    // Set initial cc result, e.g. the SIM has responded with sw1/sw2 90 00
+    // without any additional data. In error case reject the initiated action.
+    TUint8 ccresult( KAllowed == aResult ?
+        KCcResultAllowedNoModification : KCcResultNotAllowed );
+    // if provided in SIM response
+    if ( KCcEmptyResponseLenght < aApduData.Length() )
+        {
+        ccresult = aApduData[0];
+        }
+
+    // Internal call control result
+    TUint8 internalCcResult( KAllowed );
+    // if original request is changed to new action, the sequence differs
+    // when the original action is changed to other SS server action
+    TBool changedSsServerAction( EFalse );
+    // SS_RESOURCE_CONTROL_REQ has 3 mandatory sb's
+    TUint8 sbcount( 3 );
+    // Add mandatory data
+    isiMessage.Append( KPadding );
+    // SS_SB_RESOURCE [M]: resource. Shall be same as in the corresponding indication.
+    TIsiSubBlock resource( 
+        isiMessage,
+        SS_SB_RESOURCE ,
+        EIsiSubBlockTypeId8Len8 );
+    TSatUtility::AppendWord( SS_RES_ID_MO_SS_OPERATION, isiMessage );
+    resource.CompleteSubBlock();
+    
+    // SS_SB_RESOURCE_SEQ_ID [M]: [M]: Sequence ID. Shall be same as in the corresponding indication.
+    TIsiSubBlock resourceSeqId( 
+        isiMessage,
+        SS_SB_RESOURCE_SEQ_ID,
+        EIsiSubBlockTypeId8Len8 );
+    isiMessage.Append( aTcc.iResourceSeqId  );
+    isiMessage.Append( KPadding );
+    resourceSeqId.CompleteSubBlock();
+
+    // CALL_MODEM_SB_RESOURCE_STATUS [M]: resource status is allowed or denied.
+    TIsiSubBlock status(
+        isiMessage,
+        SS_SB_RESOURCE_STATUS,
+        EIsiSubBlockTypeId8Len8 );
+
+    switch( ccresult )
+        {
+        case KCcResultAllowedNoModification:
+            {
+            isiMessage.Append( SS_RESOURCE_ALLOWED );
+            isiMessage.Append( KPadding );
+            break;
+            }
+        case KCcResultNotAllowed:
+            {
+            isiMessage.Append( SS_RESOURCE_DENIED );
+            isiMessage.Append( KPadding );
+            internalCcResult = KRejected;
+            break;
+            }
+        case KCcResultAllowedWithModifications:
+            {
+            // First check if this has been modified to a new CALL
+            CTlv address;
+
+            if ( KErrNone == response.TlvByTagValue(
+                &address, KTlvAddressTag ) )
+                {
+                // Original action has been modified to call
+                isiMessage.Append( SS_RESOURCE_DENIED );
+                isiMessage.Append( KPadding );
+                internalCcResult = KChanged;
+                }
+            // Now check if original SS action has been changed to USSD action
+            CTlv ssServerString;
+            if ( aTcc.iString.Length() )
+                {
+                if ( KErrNone == response.TlvByTagValue( &ssServerString,
+                        KTlvUssdStringTag ) )
+                    {
+                    isiMessage.Append( SS_RESOURCE_DENIED );
+                    isiMessage.Append( KPadding );
+                    internalCcResult = KChanged;
+                    changedSsServerAction = ETrue;
+                    }
+                else
+                    {
+                    // original SS string has been modified to new SS string
+                    isiMessage.Append( SS_RESOURCE_ALLOWED );
+                    isiMessage.Append( KPadding );
+                    internalCcResult = KModified;
+                    }
+                }
+            else if ( aTcc.iUssdString.Length() )
+                {
+                // Or original USSD action has been modified to SS action
+                if ( KErrNone == response.TlvByTagValue( &ssServerString,
+                        KTlvSsStringTag ) )
+                    {
+                    isiMessage.Append( SS_RESOURCE_DENIED );
+                    isiMessage.Append( KPadding );
+                    internalCcResult = KChanged;
+                    changedSsServerAction = ETrue;
+                    }
+                else
+                    {
+                    // USSD string has been modified to new USSD string
+                    isiMessage.Append( SS_RESOURCE_ALLOWED );
+                    isiMessage.Append( KPadding );
+                    internalCcResult = KModified;
+                    }
+                }
+            break;
+            }
+        default:
+            {
+            break;
+            }
+        }
+    status.CompleteSubBlock();
+
+    // SS_SB_SS_CONTROL/SS_SB_USSD_CONTROL is added only if original action has
+    // been modified
+    if ( KModified == internalCcResult )
+        {
+        if ( aTcc.iString.Length() )
+            {
+            CTlv ssStringTlv;
+            if ( KErrNone == response.TlvByTagValue( &ssStringTlv,
+                KTlvSsStringTag ) )
+                {
+                TIsiSubBlock ssControl(
+                    isiMessage,
+                    SS_SB_SS_CONTROL,
+                    EIsiSubBlockTypeId8Len8 );
+                
+                TUint8 tonNpi( ssStringTlv.GetValue()[0] );
+                TPtrC8 ssString( ssStringTlv.GetValue().Mid(1) );
+
+                TBuf8<255> ss;
+                TSatUtility::BCDToAscii( ssString, ss );
+
+                if ( KTonNpiInternational == tonNpi )
+                    {
+                    // insert '+' to the number
+                    // ETSI TS 122 030 V5.0.0 (2002-06) says:
+                    // "The procedure always starts with *, #, **, ## or *#
+                    // and is finished by #. Each part within the procedure
+                    // is separated by *."
+                    TInt i( 0 );
+                    // skip start
+                    while ( (i < ss.Length()) && ('*' == ss[i]  || '#' == ss[i] ) )
+                        {
+                        i++;
+                        }
+                    // seek to separation
+                    while ( (i < ss.Length()) && (ss[i] != '*') )
+                        {
+                        i++;
+                        }
+                    // now insert '+' to start of SI
+                    if ( i < ss.Length() )
+                        {
+                        _LIT8(KPlus, "+");
+                        ss.Insert(i+1, KPlus);
+                        }
+                    }
+                isiMessage.Append( ss.Length() );
+                isiMessage.Append( ss );
+                ssControl.CompleteSubBlock();
+                sbcount++;
+                }
+            }
+        else
+            {
+            CTlv ussdStringTlv;
+            if ( KErrNone == response.TlvByTagValue( &ussdStringTlv,
+                KTlvUssdStringTag ) )
+                {
+                TIsiSubBlock ussdControl(
+                    isiMessage,
+                    SS_SB_USSD_CONTROL,
+                    EIsiSubBlockTypeId8Len8 );
+                // Coding of USSD string. 3GPP TS 23.038 CBS Data Coding Sceme
+                isiMessage.Append( ussdStringTlv.GetValue()[0] );
+                TPtrC8 ussdString( ussdStringTlv.GetValue().Mid(1) );
+                isiMessage.Append( ussdString.Length() );
+                isiMessage.Append( ussdString );
+                ussdControl.CompleteSubBlock();
+                sbcount++;
+                }
+            }
+        }
+    
+    TBuf8<1> numOfSubblocks;
+    numOfSubblocks.Append( sbcount);
+    isiMessage.Insert( 1, numOfSubblocks );
+    // send request
+    iSatMessHandler->SsResourceControlReq( aTcc.iTransId, isiMessage );
+
+    if ( KCcEmptyResponseLenght < aApduData.Length()
+        && !changedSsServerAction )
+        {
+        // Notify client about call control if alpha id present
+        iSatMessaging->NotifyClientAboutCallControlEventL(
+            internalCcResult,
+            aApduData );
+        }
+    else if ( changedSsServerAction )
+        {
+        // SIM ATK TSY has to wait SS_STATUS_IND before continuing with
+        // changed action. This because SS server is still busy with original
+        // action. Therefore save data for later usage.
+        iEnvelopeResponseData = aApduData.Alloc();
+        iCcResult = internalCcResult;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::GpdsResourceControlInd
+// Handles resource control request from modem GPDS server
+// -----------------------------------------------------------------------------
+//
+void CSatCC::GpdsResourceControlInd( const TIsiReceiveC& aIsiMessage )
+    {
+    TFLOGSTRING("TSY: CSatCC::GpdsResourceControlInd");
+    OstTrace0( TRACE_NORMAL, CSATCC_GPDSRESOURCECONTROLIND, "CSatCC::GpdsResourceControlInd" );
+
+    TCallControl callcontrol;
+    TInt paramsLength;
+    TBuf8<KPdpContextActivationParamsMaxSize> paramsBuffer;
+    // store traid's
+    callcontrol.iTransId = aIsiMessage.Get8bit( ISI_HEADER_SIZE + 
+        GPDS_RESOURCE_CONTROL_REQ_OFFSET_UTID );    
+    callcontrol.iRecourceId = aIsiMessage.Get8bit(
+        ISI_HEADER_OFFSET_RESOURCEID);
+    callcontrol.iResourceSeqId = aIsiMessage.Get8bit( ISI_HEADER_SIZE +
+        GPDS_RESOURCE_CONTROL_IND_OFFSET_SEQUENCEID );
+
+    TUint sbStartOffset( 0 );
+    TInt retValue( KErrNotFound );
+
+    // GPDS_RESOURCE sub block is skipped since resource is always
+    // GPDS_RES_ID_CC_FOR_GPRS
+    retValue = aIsiMessage.FindSubBlockOffsetById(
+        ISI_HEADER_SIZE + SIZE_GPDS_RESOURCE_CONTROL_IND + SIZE_GPDS_RESOURCE,
+        GPDS_ACTIVATE_PDP_CONTEXT_REQUEST,
+        EIsiSubBlockTypeId8Len16,
+        sbStartOffset );
+
+    if( KErrNone == retValue )
+        {
+        paramsLength = aIsiMessage.Get16bit( sbStartOffset +
+            GPDS_ACTIVATE_PDP_CONTEXT_REQUEST_OFFSET_DATALENGTH );
+        paramsBuffer.Copy( aIsiMessage.GetData( 
+            sbStartOffset + GPDS_ACTIVATE_PDP_CONTEXT_REQUEST_OFFSET_DATA,
+            paramsLength) );
+        }
+
+    // store struct
+    iCallControlArray->Append( callcontrol );
+    // Send envelope
+    SendPdpContextActivationEnvelope( callcontrol.iTransId, paramsBuffer );
+    }
+
+// -----------------------------------------------------------------------------
+// CSatCC::SendGpdsResourceControlReq
+// Creates resource control response for modem GPDS server
+// -----------------------------------------------------------------------------
+//
+void CSatCC::SendGpdsResourceControlReq( 
+        const TCallControl& aTcc,
+        const TUint8 aResult, 
+        TPtrC8 aAtkData )
+    {
+    TFLOGSTRING("TSY: CSatCC::SendGpdsResourceControlReq");
+    OstTrace0( TRACE_NORMAL, CSATCC_SENDGPDSRESOURCECONTROLREQ, "CSatCC::SendGpdsResourceControlReq" );
+
+    TBuf8<KMaximumCcBufferSize> isiMessage;
+    CBerTlv response;
+    response.SetData( aAtkData );
+    RSat::TControlResult internalCcResult = RSat::EAllowedNoModification;
+    // Set initial cc result, e.g. the SIM has responded with sw1/sw2 90 00
+    // without any additional data. In error case reject the initiated action.
+    TUint8 ccresult( KAllowed == aResult ?
+        KCcResultAllowedNoModification : KCcResultNotAllowed );
+    // if provided in SIM response
+    if ( aAtkData.Length() )
+        {
+        ccresult = response.Data()[ 0 ];
+        }
+    TInt retValue( KErrNotFound );
+    CTlv paramsTlv;
+
+    isiMessage.Append( aTcc.iResourceSeqId );
+    switch( ccresult )
+            {
+            case KCcResultAllowedNoModification:
+                {
+                isiMessage.Append( GPDS_ALLOWED );
+                isiMessage.AppendFill( KPadding, 3 );
+                // no of sb's
+                isiMessage.Append( 1 );
+                break;
+                }
+            case KCcResultNotAllowed:
+                {
+                isiMessage.Append( GPDS_REJECTED );
+                isiMessage.AppendFill( KPadding, 3 );
+                // no of sb's
+                isiMessage.Append( 1 );
+                internalCcResult = RSat::ENotAllowed;
+                break;
+                }
+            case KCcResultAllowedWithModifications:
+                {
+                // response is modified in GPDS server terminology only if
+                // new PDP params are provided
+                if ( KCcEmptyResponseLenght < aAtkData.Length() 
+                    && KErrNone == response.TlvByTagValue( &paramsTlv,
+                        KTlvPdpContextActivationParametersTag ) )
+                    {
+                    isiMessage.Append( GPDS_MODIFIED );
+                    isiMessage.AppendFill( KPadding, 3 );
+                    // no of sb's
+                    isiMessage.Append( 2 );
+                    internalCcResult = RSat::EAllowedWithModifications;
+                    }
+                else
+                    {
+                    // No new PDP params provided, hence GPDS_ALLOWED
+                    isiMessage.Append( GPDS_ALLOWED );
+                    isiMessage.AppendFill( KPadding, 3 );
+                    // no of sb's
+                    isiMessage.Append( 1 );
+                    }
+                break;
+                }
+            default:
+                {
+                break;
+                }
+            }
+    isiMessage.Append( GPDS_RESOURCE  );
+    isiMessage.Append( 4 );
+    TSatUtility::AppendWord( GPDS_RES_ID_CC_FOR_GPRS, isiMessage );
+
+    if ( KCcEmptyResponseLenght < aAtkData.Length() )
+        {
+        // GPDS_ACTIVATE_PDP_CONTEXT_REQUEST is shall be present if and only if
+        // Resource is GPDS_CC_FOR_GPRS and Result is GPDS_MODIFIED
+        if ( RSat::EAllowedWithModifications == internalCcResult )
+            {
+            TIsiSubBlock contextParams( 
+                isiMessage,
+                GPDS_ACTIVATE_PDP_CONTEXT_REQUEST,
+                EIsiSubBlockTypeId8Len16 );
+            TInt paramsLength( paramsTlv.GetLength() );
+            // Set data length
+            TSatUtility::AppendWord( paramsLength, isiMessage);
+            // Copy data after tag & length value
+            isiMessage.Append( paramsTlv.Data().Mid( 2, paramsLength ) );
+            //isiMessage.Append( paramsTlv.GetValue() );
+            contextParams.CompleteSubBlock();
+            }
+        // Check if alpha id present and valid
+        CTlv aidTlv;
+        retValue = response.TlvByTagValue( &aidTlv, KTlvAlphaIdentifierTag );
+        if ( KErrNone == retValue && aidTlv.GetLength() )
+            {
+            TPtrC8 sourceString;
+            sourceString.Set( aidTlv.GetData( ETLV_AlphaIdentifier ) );
+            RSat::TAlphaIdBuf alphaId;
+            // convert and set the alpha id
+            TSatUtility::SetAlphaId( sourceString,
+                alphaId );
+            iSatMessaging->NotifyClientAboutGprsCallControlEvent(
+                alphaId,
+                internalCcResult );
+            }
+        }
+    iSatMessHandler->GpdsResourceControlReq( aTcc.iTransId, isiMessage );
+    }
+// End of File
+