--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/adaptationlayer/tsy/nokiatsy_dll/src/cmmdtmfmesshandler.cpp Fri Nov 06 17:28:23 2009 +0000
@@ -0,0 +1,829 @@
+/*
+* 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 "cmmdtmfmesshandler.h"
+#include "cmmcallmesshandler.h"
+#include "cmmphonetsender.h"
+#include "cmmstaticutility.h"
+#include "cmmmessagerouter.h"
+#include "tsylogger.h" // logging
+#include "osttracedefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "cmmdtmfmesshandlertraces.h"
+#endif
+
+#include <etelmm.h>
+#include <ctsy/pluginapi/cmmdatapackage.h>
+#include <ctsy/serviceapi/mmtsy_defaults.h> // KDtmfStringMaxLength constant needed
+#include <ctsy/rmmcustomapi.h> // Custom API's NotifyDtmfEvent implemented here
+#include <tisi.h>
+#include <call_modemisi.h>
+
+
+
+// EXTERNAL DATA STRUCTURES
+ //none
+
+// EXTERNAL FUNCTION PROTOTYPES
+ //none
+
+// CONSTANTS
+// hard-coded transaction id for ISA messages
+const TUint8 KDtmfTransId = 3;
+const TUint8 KDtmfPadding = 0x00;
+
+// For shifting by one byte
+const TUint8 KShiftByOneByte = 8;
+
+// MACROS
+ //none
+
+// LOCAL CONSTANTS AND MACROS
+ //none
+
+// MODULE DATA STRUCTURES
+ //none
+
+// LOCAL FUNCTION PROTOTYPES
+ //none
+
+// FORWARD DECLARATIONS
+ //none
+
+// ============================= LOCAL FUNCTIONS ===============================
+ //none
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::CMmDtmfMessHandler
+// C++ default constructor
+// -----------------------------------------------------------------------------
+//
+CMmDtmfMessHandler::CMmDtmfMessHandler()
+ {
+ //none
+
+TFLOGSTRING("TSY: CMmDtmfMessHandler::CMmDtmfMessHandler");
+OstTrace0( TRACE_NORMAL, CMMDTMFMESSHANDLER_CMMDTMFMESSHANDLER, "CMmDtmfMessHandler::CMmDtmfMessHandler" );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::ConstructL
+// Symbian 2nd phase constructor. Initialises internal attributes.
+// -----------------------------------------------------------------------------
+//
+void CMmDtmfMessHandler::ConstructL()
+ {
+TFLOGSTRING("TSY: CMmDtmfMessHandler::ConstructL");
+OstTrace0( TRACE_NORMAL, CMMDTMFMESSHANDLER_CONSTRUCTL, "CMmDtmfMessHandler::ConstructL" );
+ iDTMFStringAfterW.Zero();
+ }
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMmDtmfMessHandler* CMmDtmfMessHandler::NewL(
+ CMmPhoNetSender* aPhoNetSender, //pointer to the phonet sender
+ CMmPhoNetReceiver* aPhoNetReceiver, // pointer to the phoner receiver
+ CMmMessageRouter* aMessageRouter ) // pointer to the message router
+ {
+TFLOGSTRING("TSY: CMmDtmfMessHandler::NewL");
+OstTrace0( TRACE_NORMAL, CMMDTMFMESSHANDLER_NEWL, "CMmDtmfMessHandler::NewL" );
+
+ CMmDtmfMessHandler* dtmfMessHandler =
+ new ( ELeave ) CMmDtmfMessHandler();
+
+ CleanupStack::PushL( dtmfMessHandler );
+ dtmfMessHandler->iPhoNetSender = aPhoNetSender;
+ dtmfMessHandler->iMessageRouter = aMessageRouter;
+ dtmfMessHandler->ConstructL();
+
+ aPhoNetReceiver->RegisterL( dtmfMessHandler, PN_MODEM_CALL, CALL_MODEM_DTMF_STATUS_IND );
+ aPhoNetReceiver->RegisterL( dtmfMessHandler, PN_MODEM_CALL, CALL_MODEM_DTMF_SEND_RESP );
+ aPhoNetReceiver->RegisterL( dtmfMessHandler, PN_MODEM_CALL, CALL_MODEM_DTMF_STOP_RESP );
+ aPhoNetReceiver->RegisterL( dtmfMessHandler, PN_MODEM_CALL, CALL_MODEM_DTMF_TONE_IND );
+
+ CleanupStack::Pop( dtmfMessHandler );
+
+ return dtmfMessHandler;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::~CMmDtmfMessHandler
+// Destructor
+// -----------------------------------------------------------------------------
+//
+
+CMmDtmfMessHandler::~CMmDtmfMessHandler()
+ {
+
+TFLOGSTRING("TSY: CMmDtmfMessHandler::~CMmDtmfMessHandler");
+OstTrace0( TRACE_NORMAL, DUP1_CMMDTMFMESSHANDLER_CMMDTMFMESSHANDLER, "CMmDtmfMessHandler::~CMmDtmfMessHandler" );
+ }
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::ExtFuncL
+// Forwards requests coming from the Symbian OS layer to the
+// specific method.
+// -----------------------------------------------------------------------------
+//
+TInt CMmDtmfMessHandler::ExtFuncL(
+ TInt aIpc, // request ipc
+ const CMmDataPackage* aDataPackage ) //request data
+ {
+
+TFLOGSTRING2("TSY: CMmDtmfMessHandler::ExtFuncL. IPC:%d", aIpc);
+OstTrace1( TRACE_NORMAL, CMMDTMFMESSHANDLER_EXTFUNCL, "CMmDtmfMessHandler::ExtFuncL;aIpc=%d", aIpc );
+
+ //*************************************************************//
+ // NOTE:
+ //
+ // LICENSEE SPECIFIC MESSAGE HANDLER IMPLEMENTATION STARTS HERE
+ //
+ //*************************************************************//
+
+ TInt ret( KErrNone );
+
+ TUint8 transId( KDtmfTransId );
+
+ switch ( aIpc )
+ {
+ case EMobilePhoneStartDTMFTone:
+ {
+TFLOGSTRING("TSY: CMmDtmfMessHandler::ExtFuncL -- EMobilePhoneStartDTMFTone");
+OstTrace0( TRACE_NORMAL, DUP1_CMMDTMFMESSHANDLER_EXTFUNCL, "CMmDtmfMessHandler::ExtFuncL, EMobilePhoneStartDTMFTone" );
+ //unpack parameter: DTMF tone to be sent
+ TChar* tone( NULL );
+ aDataPackage->UnPackData ( &tone );
+ // CallDtmfSendReq needs a descriptor of length one
+ // instead of a TChar
+ TBuf<1> toneDes;
+ toneDes.SetLength(0);
+ toneDes.Append(*tone);
+ //forward the request to the specific method
+ ret = CallDtmfSendReqL ( transId, &toneDes, EDtmfTypeDigit );
+ break;
+ }
+ case EMobilePhoneStopDTMFTone:
+ {
+TFLOGSTRING("TSY: CMmDtmfMessHandler::ExtFuncL -- EMobilePhoneStopDTMFTone");
+OstTrace0( TRACE_NORMAL, DUP2_CMMDTMFMESSHANDLER_EXTFUNCL, "CMmDtmfMessHandler::ExtFuncL, EMobilePhoneStopDTMFTone" );
+ //no packed parameters
+ //forward the request to the specific method
+ CallDtmfStopReq ( transId );
+ break;
+ }
+
+ case EMobilePhoneContinueDTMFStringSending:
+ {
+TFLOGSTRING("TSY: CMmDtmfMessHandler::ExtFuncL -- EMobilePhoneContinueDTMFStringSending");
+OstTrace0( TRACE_NORMAL, DUP3_CMMDTMFMESSHANDLER_EXTFUNCL, "CMmDtmfMessHandler::ExtFuncL, EMobilePhoneContinueDTMFStringSending" );
+ }
+ case EMobilePhoneSendDTMFTones:
+ {
+TFLOGSTRING("TSY: CMmDtmfMessHandler::ExtFuncL -- EMobilePhoneSendDTMFTones");
+OstTrace0( TRACE_NORMAL, DUP4_CMMDTMFMESSHANDLER_EXTFUNCL, "CMmDtmfMessHandler::ExtFuncL, EMobilePhoneSendDTMFTones" );
+ if ( !iDtmfSendOngoing || EMobilePhoneContinueDTMFStringSending == aIpc )
+ {
+ //unpack parameter: DTMF tones to be sent
+ TDesC* tonesDes ( NULL );
+ aDataPackage->UnPackData ( &tonesDes );
+ //forward the request to the specific method
+ ret = CallDtmfSendReqL ( transId, tonesDes, EDtmfTypeString );
+ if ( KErrNone == ret && EMobilePhoneSendDTMFTones == aIpc )
+ {
+ iDtmfSendOngoing = ETrue;
+ }
+ //no else
+ }
+ else
+ {
+TFLOGSTRING("TSY: CMmDtmfMessHandler::ExtFuncL -- dtmf send already ongoing");
+OstTrace0( TRACE_NORMAL, DUP5_CMMDTMFMESSHANDLER_EXTFUNCL, "CMmDtmfMessHandler::ExtFuncL, DTMF sending already ongoing" );
+ ret = KErrServerBusy;
+ }
+ break;
+ }
+ case EMobilePhoneSendDTMFTonesCancel:
+ {
+TFLOGSTRING("TSY: CMmDtmfMessHandler::ExtFuncL -- EMobilePhoneSendDTMFTonesCancel");
+OstTrace0( TRACE_NORMAL, DUP6_CMMDTMFMESSHANDLER_EXTFUNCL, "CMmDtmfMessHandler::ExtFuncL, EMobilePhoneSendDTMFTonesCancel" );
+ iDtmfSendOngoing = EFalse;
+ //no packed parameters
+ //forward the request to the specific method
+ ret = CallDtmfStopReq( transId );
+ break;
+ }
+ default:
+ {
+ // this method should only be called for DTMF cases
+TFLOGSTRING2("TSY: CMmDtmfMessHandler::ExtFuncL - Unknown IPC: %d", aIpc);
+OstTrace1( TRACE_NORMAL, DUP7_CMMDTMFMESSHANDLER_EXTFUNCL, "CMmDtmfMessHandler::ExtFuncL;Unknown IPC=%d", aIpc );
+ ret = KErrArgument;
+ break;
+ }
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::ReceiveMessageL
+// Called when an ISI message has been received.
+// -----------------------------------------------------------------------------
+//
+void CMmDtmfMessHandler::ReceiveMessageL(
+ const TIsiReceiveC &aIsiMessage ) //received ISI message
+ {
+ TInt resource (aIsiMessage.Get8bit( ISI_HEADER_OFFSET_RESOURCEID ));
+ TInt messageId(aIsiMessage.Get8bit( ISI_HEADER_OFFSET_MESSAGEID ));
+
+TFLOGSTRING3("TSY: CMmDtmfMessHandler::ReceiveMessageL. Resource:%d. MsgId:%d",resource, messageId);
+OstTraceExt2( TRACE_NORMAL, CMMDTMFMESSHANDLER_RECEIVEMESSAGEL, "CMmDtmfMessHandler::ReceiveMessageL;resource=%d;messageId=%d", resource, messageId );
+
+ // DTMF functionality is implemented in CALL server
+ if ( PN_MODEM_CALL == resource )
+ {
+ switch ( messageId )
+ {
+ case CALL_MODEM_DTMF_STATUS_IND:
+ {
+ CallDtmfStatusInd( aIsiMessage );
+ break;
+ }
+ case CALL_MODEM_DTMF_SEND_RESP:
+ {
+ CallDtmfSendResp( aIsiMessage );
+ break;
+ }
+ case CALL_MODEM_DTMF_STOP_RESP:
+ {
+ CallDtmfStopResp( aIsiMessage );
+ break;
+ }
+ case CALL_MODEM_DTMF_TONE_IND:
+ {
+ CallDtmfToneInd( aIsiMessage );
+ break;
+ }
+ default:
+ {
+
+TFLOGSTRING("TSY: CMmDtmfMessHandler::ReceiveMessageL. PN_MODEM_CALL: Switch messageID case default");
+OstTrace0( TRACE_NORMAL, DUP1_CMMDTMFMESSHANDLER_RECEIVEMESSAGEL, "CMmDtmfMessHandler::ReceiveMessageL,PN_MODEM_CALL: Switch messageID case default" );
+
+ break;
+ }
+ } // switch( messageId )
+ } // if ( PN_MODEM_CALL == resource )
+ }
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::SendPostAddressL
+// Called by call message handler when a call goes active and there
+// is a post address string to send.
+// -----------------------------------------------------------------------------
+//
+void CMmDtmfMessHandler::SendPostAddressL(
+ const TDesC* aDtmfString ) //dtmf character(s) to be sent
+ {
+
+TFLOGSTRING("TSY: CMmDtmfMessHandler::SendPostAddressL");
+OstTrace0( TRACE_NORMAL, CMMDTMFMESSHANDLER_SENDPOSTADDRESSL, "CMmDtmfMessHandler::SendPostAddressL" );
+
+ if ( !iDtmfSendOngoing )
+ {
+ iDtmfSendOngoing = ETrue;
+ CallDtmfSendReqL( KDtmfTransId, aDtmfString, EDtmfTypeString );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::CallDtmfSendReq
+// Called by MmDtmfTsy to construct a CALL_MODEM_DTMF_SEND_REQ ISI
+// message and to send it to Phonet. Can be used with strings and single
+// digits.
+// -----------------------------------------------------------------------------
+//
+TInt CMmDtmfMessHandler::CallDtmfSendReqL(
+ TUint8 aTransactionId, //transaction id
+ const TDesC* aDtmfString, //dtmf character(s) to be sent
+ TNOSDtmfType aDtmfType ) // Type of dtmf to send
+ {
+TFLOGSTRING3("TSY: CMmDtmfMessHandler::CallDtmfSendReqL. TransId:%d, DtmfString:%S", aTransactionId, aDtmfString);
+OstTraceExt2( TRACE_NORMAL, DUP1_CMMDTMFMESSHANDLER_CALLDTMFSENDREQL, "CMmDtmfMessHandler::CallDtmfSendReqL;aTransactionId=%hhu;aDtmfString=%s", aTransactionId, ( TUint )( aDtmfString ) );
+
+ TInt ret( KErrNone );
+
+ // Get dtmf character(s) length
+ TInt length( aDtmfString->Length() );
+
+ if ( ( KDtmfStringMaxLength >= length ) && ( 0 < length ) )
+ {
+ // Create isi message
+ TIsiSend callDtmfSendReq( iPhoNetSender->SendBufferDes() );
+ callDtmfSendReq.Set8bit( ISI_HEADER_OFFSET_RESOURCEID, PN_MODEM_CALL );
+
+ // Set the call Dtmf Send Req data
+ callDtmfSendReq.Set8bit(
+ ISI_HEADER_OFFSET_TRANSID, aTransactionId );
+ callDtmfSendReq.Set8bit(
+ ISI_HEADER_OFFSET_MESSAGEID, CALL_MODEM_DTMF_SEND_REQ );
+ callDtmfSendReq.Set8bit(
+ ISI_HEADER_SIZE + CALL_MODEM_DTMF_SEND_REQ_OFFSET_CALLID,
+ CALL_MODEM_ID_ACTIVE );
+
+ // Initialize message offset and subblock count
+ TUint currentMsgOffset(
+ ISI_HEADER_SIZE + SIZE_CALL_MODEM_DTMF_SEND_REQ );
+ TUint8 numOfSbInMessage( 0 );
+
+ iDtmfType = aDtmfType;
+
+ //get call dtmf send req sub blocks
+ TBool createReq( GetCallDtmfSendReqSubBlockL(
+ aDtmfString,
+ callDtmfSendReq,
+ currentMsgOffset,
+ numOfSbInMessage ) );
+
+ callDtmfSendReq.Set8bit(
+ ISI_HEADER_SIZE + CALL_MODEM_DTMF_SEND_REQ_OFFSET_SUBBLOCKS,
+ numOfSbInMessage );
+
+ //createReq flag is set to TRUE so request will be sent
+ if ( createReq )
+ {
+ //send message via phonet
+ ret = iPhoNetSender->Send( callDtmfSendReq.Complete() );
+ }
+ }
+ else
+ {
+ ret = KErrArgument;
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::CallDtmfSendResp
+// Breaks a CALL_MODEM_DTMF_SEND_RESP ISI-message. Handles error
+// situations of DTMF sending.
+// -----------------------------------------------------------------------------
+//
+void CMmDtmfMessHandler::CallDtmfSendResp(
+ const TIsiReceiveC &aIsiMessage ) //received ISI message
+ {
+
+TFLOGSTRING("TSY: CMmDtmfMessHandler::CallDtmfSendResp");
+OstTrace0( TRACE_NORMAL, DUP1_CMMDTMFMESSHANDLER_CALLDTMFSENDRESP, "CMmDtmfMessHandler::CallDtmfSendResp" );
+
+ TUint sbStartOffSet( 0 );
+
+ if( KErrNone == aIsiMessage.FindSubBlockOffsetById(
+ ISI_HEADER_SIZE + SIZE_CALL_MODEM_DTMF_SEND_RESP, CALL_MODEM_SB_CAUSE,
+ EIsiSubBlockTypeId8Len8, sbStartOffSet ) )
+ {
+ //get cause type
+ TUint8 causeType( aIsiMessage.Get8bit( sbStartOffSet +
+ CALL_MODEM_SB_CAUSE_OFFSET_CAUSETYPE) );
+
+ //get cause value
+ TUint8 causeValue( aIsiMessage.Get8bit( sbStartOffSet +
+ CALL_MODEM_SB_CAUSE_OFFSET_CAUSE ) );
+
+ if ( ( EDtmfTypeString == iDtmfType ) && ( !iCharWFound ) )
+ {
+ iDtmfSendOngoing = EFalse;
+ TInt result( CMmStaticUtility::CSCauseToEpocError(
+ PN_MODEM_CALL, causeType, causeValue ) );
+ iMessageRouter->Complete(
+ EMobilePhoneSendDTMFTones,
+ result );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::CallDtmfStopReq
+// Called by CMmDtmfTsy to construct a CALL_MODEM_DTMF_STOP_REQ ISI
+// message
+// -----------------------------------------------------------------------------
+//
+TInt CMmDtmfMessHandler::CallDtmfStopReq(
+ TUint8 aTransactionId ) //transaction id
+ {
+
+TFLOGSTRING("TSY: CMmDtmfMessHandler::CallDtmfStopReq");
+OstTrace0( TRACE_NORMAL, DUP1_CMMDTMFMESSHANDLER_CALLDTMFSTOPREQ, "CMmDtmfMessHandler::CallDtmfStopReq" );
+
+ //create dtmf stop request message
+ //Append data for ISI message
+ TBuf8<2> data;
+ data.Append( CALL_MODEM_ID_ACTIVE ); // CallId
+ data.Append( 0x00 ); // Number of Subblocks
+
+ // Send Isi message via Phonet
+ return iPhoNetSender->Send( PN_MODEM_CALL, aTransactionId, CALL_MODEM_DTMF_STOP_REQ, data );
+ }
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::CallDtmfStopResp
+// Breaks a CALL_MODEM_DTMF_STOP_RESP ISI message
+// -----------------------------------------------------------------------------
+//
+void CMmDtmfMessHandler::CallDtmfStopResp(
+ const TIsiReceiveC &aIsiMessage ) //received ISI message
+ {
+
+TFLOGSTRING("TSY: CMmDtmfMessHandler::CallDtmfStopResp");
+OstTrace0( TRACE_NORMAL, DUP1_CMMDTMFMESSHANDLER_CALLDTMFSTOPRESP, "CMmDtmfMessHandler::CallDtmfStopResp" );
+
+ TUint8 nbrOfsubBlocks( aIsiMessage.Get8bit( ISI_HEADER_SIZE +
+ CALL_MODEM_DTMF_STOP_RESP_OFFSET_SUBBLOCKS ) );
+
+ if ( 0 < nbrOfsubBlocks )
+ {
+ TUint sbStartOffSet( 0 );
+
+ //check that is this response to Cancel request
+ if( KErrNone == aIsiMessage.FindSubBlockOffsetById(
+ ISI_HEADER_SIZE + SIZE_CALL_MODEM_DTMF_STOP_RESP, CALL_MODEM_SB_DTMF_STRING,
+ EIsiSubBlockTypeId8Len8, sbStartOffSet ) )
+ {
+ iMessageRouter->Complete(
+ EMobilePhoneStopDTMFTone,
+ KErrNone );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::CallDtmfStatusInd
+// Called by PhonetReceiver to break a CALL_MODEM_DTMF_STATUS_IND
+// ISI message.
+// -----------------------------------------------------------------------------
+//
+void CMmDtmfMessHandler::CallDtmfStatusInd(
+ const TIsiReceiveC &aIsiMessage ) // Received ISI message
+ {
+
+TFLOGSTRING("TSY: CMmDtmfMessHandler::CallDtmfStatusInd");
+OstTrace0( TRACE_NORMAL, DUP2_CMMDTMFMESSHANDLER_CALLDTMFSTATUSIND, "CMmDtmfMessHandler::CallDtmfStatusInd" );
+
+ TUint sbStartOffSet( 0 );
+
+ //get call dtmf status sub block
+ if( KErrNone == aIsiMessage.FindSubBlockOffsetById(
+ ISI_HEADER_SIZE + CALL_MODEM_DTMF_STATUS_IND_OFFSET_STATUS, CALL_MODEM_SB_DTMF_STATUS,
+ EIsiSubBlockTypeId8Len8, sbStartOffSet ) )
+ {
+ // DTMF event information
+ RMobilePhone::TMobilePhoneDTMFEvent event;
+ CMmDataPackage eventDataPackage;
+ //get dtmf status
+ TUint8 dtmfStatus( aIsiMessage.Get8bit( sbStartOffSet +
+ CALL_MODEM_SB_DTMF_STATUS_OFFSET_STATUS) );
+
+TFLOGSTRING2("TSY: CMmDtmfMessHandler::CallDtmfStatusInd. dtmfStatus:%d",dtmfStatus);
+OstTraceExt1( TRACE_NORMAL, DUP3_CMMDTMFMESSHANDLER_CALLDTMFSTATUSIND, "CMmDtmfMessHandler::CallDtmfStatusInd;dtmfStatus=%hhu", dtmfStatus );
+
+ if( CALL_MODEM_DTMF_IDLE == dtmfStatus )
+ {
+ if( EDtmfTypeUnknown != iDtmfType )
+ {
+ TUint8 causeType( 0 );
+ TUint8 causeValue( 0 );
+
+ if( KErrNone == aIsiMessage.FindSubBlockOffsetById(
+ ISI_HEADER_SIZE + SIZE_CALL_MODEM_DTMF_STATUS_IND, CALL_MODEM_SB_CAUSE,
+ EIsiSubBlockTypeId8Len8, sbStartOffSet ) )
+ {
+ //Get Cause Type
+ causeType = aIsiMessage.Get8bit( sbStartOffSet +
+ CALL_MODEM_SB_CAUSE_OFFSET_CAUSETYPE);
+ //Get Cause Value
+ causeValue = aIsiMessage.Get8bit( sbStartOffSet +
+ CALL_MODEM_SB_CAUSE_OFFSET_CAUSE );
+ }
+
+ //If sub block found, DTMF string sending has been pause with 'w'
+ //mark in the DTMF string
+ if ( iCharWFound )
+ {
+ CMmDataPackage dataPackage;
+ dataPackage.PackData( &iDTMFStringAfterW );
+ iMessageRouter->Complete(
+ EMobilePhoneNotifyStopInDTMFString,
+ &dataPackage,
+ KErrNone );
+
+ // Set iCharWFound flag to False
+ iCharWFound = EFalse;
+ iDTMFStringAfterW.Zero();
+ }
+ //Complete sending DTMF string
+ else if ( EDtmfTypeString == iDtmfType )
+ {
+ iDtmfSendOngoing = EFalse;
+ TInt result( CMmStaticUtility::CSCauseToEpocError(
+ PN_MODEM_CALL, causeType, causeValue ) );
+
+ CMmDataPackage dataPackage;
+ iMessageRouter->Complete(
+ EMobilePhoneSendDTMFTones,
+ &dataPackage,
+ result );
+ }
+ }
+ iDtmfType = EDtmfTypeUnknown;
+ iDtmfDigitSent = 0;
+ event = RMobilePhone::EStopDtmfTone;
+ }
+ else
+ {
+ event = RMobilePhone::EStartDtmfTone;
+ }
+ // Complete DTMF Event
+ eventDataPackage.PackData( &event );
+ iMessageRouter->Complete(
+ EMobilePhoneNotifyDTMFEvent,
+ &eventDataPackage,
+ KErrNone );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::GetCallDtmfSendReqSubBlock
+// Appends the sub blocks for CALL_MODEM_DTMF_SEND_REQ ISI message.
+// if iDtmfType is DTMF_TYPE_DIGIT
+// append digit to temporary buffer
+// append callDtmfSubBlock subblock to the message using the temporary
+// buffer
+// set iDtmfDigitSent to point to the aDtmfString (input parameter)
+// else
+// append dtmf timer sub block (minimum duration and gap)
+// append DTMF string to temporary buffer
+// append callDtmfSubBlock subblock to the message using the temporary
+// buffer
+// -----------------------------------------------------------------------------
+//
+TBool CMmDtmfMessHandler::GetCallDtmfSendReqSubBlockL(
+ const TDesC* aDtmfString, //dtmf character(s)
+ TIsiSend &aIsiMessage, //IsiMsg to be build
+ TUint &aCurrentMsgOffset,
+ TUint8 &aNumOfSbInMessage )
+ {
+TFLOGSTRING2("TSY: CMmDtmfMessHandler::GetCallDtmfSendReqSubBlockL. DtmfType:%d", iDtmfType );
+OstTrace1( TRACE_NORMAL, CMMDTMFMESSHANDLER_GETCALLDTMFSENDREQSUBBLOCKL, "CMmDtmfMessHandler::GetCallDtmfSendReqSubBlockL;iDtmfType=%d", iDtmfType );
+ // createReq flag is set to 'false' only in case the first character is 'w'
+ // in DTMF string. If 'true' CALL_DTMF_SEND_REQ will be sent.
+ TBool createReq( ETrue );
+
+ if( EDtmfTypeDigit == iDtmfType )
+ {
+ TBuf8< SIZE_CALL_MODEM_SB_DTMF_DIGIT > callDtmfDigitBuf( 0 );
+ TIsiSubBlock dtmfDigitSubBlock( callDtmfDigitBuf,
+ CALL_MODEM_SB_DTMF_DIGIT, EIsiSubBlockTypeId8Len8 );
+
+ TIsiUtility::CopyToBigEndian( *aDtmfString, callDtmfDigitBuf );
+
+ aIsiMessage.CopyData(
+ aCurrentMsgOffset, dtmfDigitSubBlock.CompleteSubBlock() );
+
+ // Set new offset and increase subblock count
+ aCurrentMsgOffset =
+ aCurrentMsgOffset + SIZE_CALL_MODEM_SB_DTMF_DIGIT;
+ aNumOfSbInMessage++;
+
+ iDtmfDigitSent = *aDtmfString->Ptr();
+ }
+ else
+ {
+ // This flag indicates is 'w' found in DTMF string.
+ iCharWFound = EFalse;
+
+ // Buffer length for pause length, string length(unicode)
+ // and 16-bit data.
+ TBuf8<KAddressSubBlockMaxLength> dataString( 0 );
+ TIsiSubBlock callDtmfStringSubBlock( dataString,
+ CALL_MODEM_SB_DTMF_STRING, EIsiSubBlockTypeId8Len8 );
+
+ // Pause length
+ dataString.Append( CALL_MODEM_DTMF_PAUSE_3S );
+
+ // Get dtmf character(s) length
+ TInt length( aDtmfString->Length() );
+
+ // Check if character 'w' is found in the DTMF string
+ TInt positionCharW( aDtmfString->Locate('w') );
+
+ // Character 'w' was found, the string after 'w' must must be stored,
+ // it will be sent back to client when CALL_DTMF_STATUS_IND with
+ // CALL_DTMF_IDLE is received.
+ if ( KErrNotFound != positionCharW )
+ {
+ // Copy string after 'w' for later use.
+ iDTMFStringAfterW.Copy(
+ aDtmfString->Right( length - ( positionCharW + 1 ) ) );
+
+ // If 'w' was received as the first character, complete
+ // immediately with remaining string.
+ if ( 0 == positionCharW )
+ {
+ // Notify about the stop mark in the DTMF string.
+ CMmDataPackage dataPackage;
+ dataPackage.PackData( &iDTMFStringAfterW );
+ iMessageRouter->Complete(
+ EMobilePhoneNotifyStopInDTMFString,
+ &dataPackage,
+ KErrNone );
+ iDTMFStringAfterW.Zero();
+ // Don't send the request in this case.
+ createReq = EFalse;
+ }
+ else
+ {
+ // Length of the datastring including character 'w'.
+ length = positionCharW + 1;
+ // 'w' was found, set the flag.
+ iCharWFound = ETrue;
+ }
+ }
+ // No else. If 'w' was not found, iCreateReq is set to 'true' by
+ // default and iCharWFound to 'false'. Whole string will be sent.
+
+ // First append number length
+ dataString.Append( length ); // DTMF length
+
+ // Create buffer for dtmf data. Max data buffer size is 256.
+ TBuf8<KMaxDataBufferSize> tempdata;
+ // Copy 16 to 8
+ TIsiUtility::CopyToBigEndian( *aDtmfString, tempdata );
+ // Append data to the buffer which contains unicode string
+ dataString.Append( tempdata.Left( length * 2 ) );
+
+ aIsiMessage.CopyData( aCurrentMsgOffset,
+ callDtmfStringSubBlock.CompleteSubBlock() );
+
+ // Set new offset and increase subblock count
+ aCurrentMsgOffset =
+ aCurrentMsgOffset + dataString.Length();
+ aNumOfSbInMessage++;
+
+ //Sub Block CALL_MODEM_SB_DTMF_TIMERS
+ TBuf8< SIZE_CALL_MODEM_SB_DTMF_TIMERS > dataTimers( 0 ); //data timers is a unicode character
+ TIsiSubBlock callDtmfTimersSubBlock( dataTimers,
+ CALL_MODEM_SB_DTMF_TIMERS, EIsiSubBlockTypeId8Len8 );
+
+ //DTFM duration in milliseconds
+ dataTimers.Append( static_cast<TUint8>( CALL_MODEM_DTMF_NO_DELAY >> KShiftByOneByte ) );
+ dataTimers.Append( static_cast<TUint8>( CALL_MODEM_DTMF_NO_DELAY ) );
+ //DTMF gap in milliseconds
+ dataTimers.Append( static_cast<TUint8>( CALL_MODEM_DTMF_NO_DELAY >> KShiftByOneByte ) );
+ dataTimers.Append( static_cast<TUint8>( CALL_MODEM_DTMF_NO_DELAY ) );
+ //append padding
+ dataTimers.AppendFill( KDtmfPadding, 2 );
+
+ aIsiMessage.CopyData( aCurrentMsgOffset,
+ callDtmfTimersSubBlock.CompleteSubBlock() );
+
+ // Set new offset and increase subblock count
+ aCurrentMsgOffset =
+ aCurrentMsgOffset + SIZE_CALL_MODEM_SB_DTMF_TIMERS;
+ aNumOfSbInMessage++;
+ }
+
+ return createReq;
+ }
+
+// NOTE:
+// The following methods are part of Custom Tsy
+//
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::CallDtmfToneInd
+// Breaks a CALL_MODEM_DTMF_TONE_IND ISI message and completes NotifyDtmfEvent
+// with gathered data.
+// -----------------------------------------------------------------------------
+//
+void CMmDtmfMessHandler::CallDtmfToneInd(
+ const TIsiReceiveC &aIsiMessage ) //received ISI message
+ {
+
+TFLOGSTRING("TSY: CMmDtmfMessHandler::CallDtmfToneInd");
+OstTrace0( TRACE_NORMAL, CMMDTMFMESSHANDLER_CALLDTMFTONEIND, "CMmDtmfMessHandler::CallDtmfToneInd" );
+
+ //create and initialize TDtmfInfo
+ RMmCustomAPI::TDtmfInfo dtmfInfo;
+ dtmfInfo.iType = RMmCustomAPI::EDtmfSequence;
+ dtmfInfo.iEvent = RMmCustomAPI::EDtmfAbort;
+ dtmfInfo.iTone = CALL_MODEM_DTMF_NO_TONE;
+
+ TUint sbStartOffSet( 0 );
+
+ // get dtmf tone sub block
+ TInt returnValue( aIsiMessage.FindSubBlockOffsetById(
+ ISI_HEADER_SIZE + CALL_MODEM_DTMF_TONE_IND_OFFSET_TONE, CALL_MODEM_SB_DTMF_TONE,
+ EIsiSubBlockTypeId8Len8, sbStartOffSet ) );
+
+ // if subblock was found
+ if ( KErrNone == returnValue )
+ {
+ // get DTMF tone
+ TUint16 dtmfTone ( aIsiMessage.Get16bit( sbStartOffSet +
+ CALL_MODEM_SB_DTMF_TONE_OFFSET_TONE ) );
+
+ //map the values into a TDtmfInfo
+ //set the event type
+ switch ( iDtmfType )
+ {
+ case EDtmfTypeString:
+ {
+ //dtmfInfo.iType already initialized as EDtmfSequence
+ break;
+ }
+ case EDtmfTypeDigit:
+ {
+ dtmfInfo.iType = RMmCustomAPI::EDtmfManual;
+ break;
+ }
+ default:
+ {
+ returnValue = KErrGeneral;
+ break;
+ }
+ }
+ //set the event
+ if ( CALL_MODEM_DTMF_NO_TONE == dtmfTone )
+ {
+ dtmfInfo.iEvent = RMmCustomAPI::EDtmfStop;
+ //valus of dtmfInfo.iTone has been already set as KCallDtmfNoTone;
+TFLOGSTRING("TSY: CMmDtmfMessHandler::CallDtmfToneInd-> No Tone");
+OstTrace0( TRACE_NORMAL, DUP1_CMMDTMFMESSHANDLER_CALLDTMFTONEIND, "CMmDtmfMessHandler::CallDtmfToneInd, No Tone" );
+ }
+ else
+ {
+ dtmfInfo.iEvent = RMmCustomAPI::EDtmfStart;
+ dtmfInfo.iTone = dtmfTone;
+//In this logging the MSB are not wanted to be shown. This clarifies testing.
+TFLOGSTRING2("TSY: CMmDtmfMessHandler::CallDtmfToneInd. Tone: %x", 0x0F&dtmfTone);
+// following lines flagged out just get rid of
+// compiler warning when trace compiler is not
+// in use.
+#ifdef OST_TRACE_COMPILER_IN_USE
+
+TUint16 tempDtmfTone( 0x0F&dtmfTone ); // Parameter just for tracing
+OstTraceExt1( TRACE_NORMAL, DUP2_CMMDTMFMESSHANDLER_CALLDTMFTONEIND, "CMmDtmfMessHandler::CallDtmfToneInd;dtmfTone=%hx",tempDtmfTone );
+#endif // OST_TRACE_COMPILER_IN_USE
+ }
+ }
+ // complete with return value
+ // parameter for SOS layer: a RMmCustomAPI::TDtmfInfo
+ CMmDataPackage dataPackage;
+ dataPackage.PackData( &dtmfInfo );
+ iMessageRouter->Complete( ECustomNotifyDtmfEventIPC, &dataPackage, returnValue );
+ }
+
+// -----------------------------------------------------------------------------
+// CMmDtmfMessHandler::HandleError
+// Handles CMmDtmfMessHandler's errors that comes via PhoNetReceiver RunError
+// method.
+// -----------------------------------------------------------------------------
+//
+void CMmDtmfMessHandler::HandleError(
+ const TIsiReceiveC& /*aIsiMessage*/, // Isi message
+ TInt /*aError*/ ) // Error code
+ {
+
+TFLOGSTRING("TSY: CMmDtmfMessHandler::HandleError");
+OstTrace0( TRACE_NORMAL, CMMDTMFMESSHANDLER_HANDLEERROR, "CMmDtmfMessHandler::HandleError" );
+
+ }
+
+// End of File
+