diff -r 000000000000 -r 3553901f7fa8 telephonyserverplugins/multimodetsy/Multimode/sms/cmt_unstored.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/telephonyserverplugins/multimodetsy/Multimode/sms/cmt_unstored.cpp Tue Feb 02 01:41:59 2010 +0200 @@ -0,0 +1,310 @@ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "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 // for RMobileSmsMessaging::TMobileSmsReceiveAttributesV1 +#include "mSLOGGER.H" // for LOGTEXT2 and other logging utilities +#include "ATIO.H" +#include "Matstd.h" +#include "cmt_unstored.h" // header file for this cpp file +#include "sms_rx_queue.h" // for CReceiveSmsQueue + +#ifdef __LOGDEB__ +_LIT8(KLogEntry,"CATSmsWaitForAndHandleCMTUnstored::%S\t%S"); +#define LOCAL_LOGTEXT(function,text) {_LIT8(F,function);_LIT8(T,text);LOGTEXT3(KLogEntry,&F,&T);} +#else +#define LOCAL_LOGTEXT(function,text) +#endif + + +CATSmsWaitForAndHandleCMTUnstored* CATSmsWaitForAndHandleCMTUnstored::NewL(CATIO* aIo,CTelObject* aTelObject, CPhoneGlobals* aGlobals, + CReceiveSmsQueue& aReceiveQueue) + { + CATSmsWaitForAndHandleCMTUnstored* wait=new(ELeave) CATSmsWaitForAndHandleCMTUnstored(aIo,aTelObject,aGlobals,aReceiveQueue); + // Currently no need for a ConstructL call + return wait; + } + +CATSmsWaitForAndHandleCMTUnstored::CATSmsWaitForAndHandleCMTUnstored(CATIO* aIo, CTelObject* aTelObject, + CPhoneGlobals* aGlobals, CReceiveSmsQueue& aReceiveQueue) + :CATBase(aIo,aTelObject,aGlobals) + ,iReceiveQueue(aReceiveQueue) + {} + + +CATSmsWaitForAndHandleCMTUnstored::~CATSmsWaitForAndHandleCMTUnstored() + { + iIo->RemoveExpectStrings(this); + // We do not need to NULL iCMTExpectString and iCDSExpectString + // as this object is about to de destroyed + } + +void CATSmsWaitForAndHandleCMTUnstored::Enable() + { + LOCAL_LOGTEXT("Enable","Enabled listening for CMT & CDS"); + + if (iState==ENoState) + { + iState=EWaitForCMT; + + // Add +CMT:* expect string + if (!iCMTExpectString) + iCMTExpectString=iIo->AddExpectString(this,KCMTMatchString); + + // Add +CDS:* expect string + if (!iCDSExpectString) + iCDSExpectString=iIo->AddExpectString(this,KCDSMatchString); + } + } + +void CATSmsWaitForAndHandleCMTUnstored::Disable() + { + LOCAL_LOGTEXT("Disable","Disabled listening for CMT & CDS"); + + if (iState!=EWaitForCmtSecondLine) + { + iIo->RemoveExpectStrings(this); + iCMTExpectString=NULL; + iCDSExpectString=NULL; + iState=ENoState; + } + else + { + // wait to receive message we're half-way through before disabling + iState=EWaitForCmtSecondLineThenDisable; + } + } + + +void CATSmsWaitForAndHandleCMTUnstored::EventSignal(TEventSource aSource) +/** + * Called when a '+CMT:' or '+CDS:' is received. + * +CMT: [], + * +CDS: + * + * This is a two state machine that first waits for the +CMT: [], + * and then waits for the final + * + * When a PDU has been read from the phone, it is pushed into the CReceiveSmsQueue. + */ + { + TInt ret(KErrNone); + iIo->WriteAndTimerCancel(this); + LOCAL_LOGTEXT("EventSignal","Enter function"); + + switch(iState) + { + case EWaitForCMT: + LOCAL_LOGTEXT("EventSignal","EWaitForCMT"); + __ASSERT_ALWAYS(aSource == EReadCompletion, Panic(EATCommand_IllegalCompletionReadExpected)); + + TRAP(ret,ParseFirstCMTLineL(iPduLen)); + if(ret!=KErrNone) + { + LOCAL_LOGTEXT("EventSignal","Failed to parse 1st line"); + // No need for more error handling - just wait for next CMT + } + else + { + // + // Add the expect string * so that we receive whatever is on the next line + // (the conditional expression below ensures no memory leak if "+CMT:" + // is found on consecutive lines) + if(!iWaitForAnything) + iWaitForAnything=iIo->AddExpectString(this,KAsterisk); + + // + // We need to keep the buffered data so we... + iIo->SetPreserveBufferFlag(ETrue); + + // + // Wait for the reception of the second line + iState=EWaitForCmtSecondLine; + } + break; + + case EWaitForCmtSecondLine: + case EWaitForCmtSecondLineThenDisable: + + LOCAL_LOGTEXT("EventSignal","EWaitForCmtSecondLine"); + __ASSERT_ALWAYS(aSource == EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected)); + iIo->RemoveExpectString(iWaitForAnything); + iWaitForAnything=NULL; + iIo->SetPreserveBufferFlag(EFalse); // We've got the PDU, and will delete the buffer when the line is parsed + + { // Curly brackets used to scope pdu and attr local data + // + // Parse and Push received message into CReceiveSmsQueue + RMobileSmsMessaging::TMobileSmsGsmTpdu pdu; + RMobileSmsMessaging::TMobileSmsReceiveAttributesV1 attr; + TRAPD(ret,ParseSecondCMTLineL(pdu,attr)); + if(ret!=KErrNone) + { + LOCAL_LOGTEXT("EventSignal","Failed to parse 2nd line"); + } + else + { + LOCAL_LOGTEXT("EventSignal","Adding SMS to iReceiveQueue"); + iReceiveQueue.Push(pdu,attr); + } + } + + // + // We are done, but there is no client request to complete + // we just return and wait until we get our next CMT command + // unless we should disable now + if (iState==EWaitForCmtSecondLineThenDisable) + Disable(); + else + iState=EWaitForCMT; + break; + + case ENoState: + default: + // We should never get here, but we don't need to panic in release code. + __ASSERT_DEBUG(EFalse,Panic(EATWaitForCMTNoState)); + break; + } + } + + + +void CATSmsWaitForAndHandleCMTUnstored::ParseFirstCMTLineL(TInt& aPduLen) +/** + * Parse 1st line of CMT response, of the format: "+CMT: [], " + * Stores the in aPduLen + */ + { + ParseLineLC(); + + CATParamListEntry* entry; + CATParamListEntry* alpha; + TDblQueIter iter(iRxResults); + + entry=iter++; + if (entry==NULL || (entry->iResultPtr!=KCMTResponseString && entry->iResultPtr!=KCDSResponseString)) + { + LOCAL_LOGTEXT("ParseFirstCMTLineL","Failed to find response +CMT: or +CDS:"); + User::Leave(KErrGeneral); + } + + // + // Get the token, optional this token may return the message length token + alpha=iter++; + if(alpha==NULL) + { + LOCAL_LOGTEXT("ParseFirstCMTLineL","Failed with 1st argument"); + User::Leave(KErrGeneral); + } + + // + // Get the message length token + entry=iter++; + if(entry==NULL) + entry=alpha; // The alpha token must have been missing and thus alpha holds the message length + + if(entry==NULL) + { + LOCAL_LOGTEXT("ParseFirstCMTLineL","Failed with 2nd argument"); + User::Leave(KErrGeneral); + } + + // + // Process the message length + aPduLen=CATParamListEntry::EntryValL(entry); + LOGTEXT2(_L8("New SMS detected of length %d"),iPduLen); + + CleanupStack::PopAndDestroy(); // ParseLineLC pushed object + } + + +void CATSmsWaitForAndHandleCMTUnstored::ParseSecondCMTLineL(RMobileSmsMessaging::TMobileSmsGsmTpdu& aPdu,RMobileSmsMessaging::TMobileSmsReceiveAttributesV1& aAttr) +/** + * Parse second line of CMT or DS response, of the format: "" + * The is saved to aPdu. If the is found to have a prefixed SCA + * then that is removed before the save to aPdu. + */ + { + LOCAL_LOGTEXT("ParseSecondCMTLineL","Enter funciton"); + + // Intiailise the attributes + aAttr.iFlags=0; + // + // Copy the received pdu to local storage so that we can process + // and modify it. + // Buffer size calculated as follows; + // (max pdu size + max prefixed SCA size) * number of ASCII chars used to code an octet + TBuf8<(RMobileSmsMessaging::KGsmTpduSize+12)*2> localPdu; + { + ParseLineLC(); + TDblQueIter iter(iRxResults); + CATParamListEntry* entry=iter++; // Have to increment iter so it returns a pointer + if(entry==NULL) + User::Leave(KErrGeneral); // Would prefer not to leave and return an error + // but this function has to be trapped as we + // have the ParseLineLC() call. + localPdu.Copy(entry->iResultPtr); + CleanupStack::PopAndDestroy(); // ParseLineLC pushed object + } + + // Nokia 9210 sometimes aborts the CMT frame in the middle of pdu. + // Worst, it is sometimes contains odd number of nibbles which + // causes panic in ConvertAsciiToBinary() method. This type of + // frames will simply be discarded. + if(localPdu.Length()<(iPduLen*2)) + User::Leave(KErrUnderflow); + + // + // Check if we have a prefixed SCA on our pdu. + // If we do then remove it. + if(localPdu.Length()>(iPduLen*2)) + { + if(CATSmsUtils::ReadAndRemoveAddressFromAscii(localPdu,aAttr.iGsmServiceCentre,ETrue)!=KErrNone) + { + LOCAL_LOGTEXT("ParseAndStoreCMGRResponseL","Failed to read and remove SCA from PDU"); + } + else + { + aAttr.iFlags|=RMobileSmsMessaging::KGsmServiceCentre; + } + } + + // + // Convert received pdu from ASCII into binary + if (CATSmsUtils::ConvertAsciiToBinary(localPdu,aPdu)!=KErrNone) + { + LOCAL_LOGTEXT("ParseAndStoreCMGRResponseL","Failed to code PDU into binary"); + } + else + { + aAttr.iDataFormat=RMobileSmsMessaging::EFormatGsmTpdu; + aAttr.iFlags|=RMobileSmsMessaging::KSmsDataFormat; + aAttr.iStatus=RMobileSmsMessaging::EMtMessageUnstoredPhoneAck; + aAttr.iFlags|=RMobileSmsMessaging::KIncomingStatus; + } + } + + + +void CATSmsWaitForAndHandleCMTUnstored::CompleteWithIOError(TEventSource /*aSource*/,TInt aStatus) + { + LOCAL_LOGTEXT("CompleteWithIOError","Enter function"); + // CATIO removes expect strings in event of IO error so don't do it here + iCMTExpectString=NULL; + iCDSExpectString=NULL; + // inform client of error so that it does not continue to wait for incoming SMS + // now that this wait object has been disabled + iReceiveQueue.CompleteClientReqWithError(aStatus); + } +