telephonyserverplugins/multimodetsy/Multimode/sms/mSMSREAD.CPP
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyserverplugins/multimodetsy/Multimode/sms/mSMSREAD.CPP	Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,363 @@
+// 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:
+// Reads an SMS message present on the ME (mobile equipment). AT+CMGR=xx 
+// 
+//
+
+#include <et_phone.h>		// for TSY_HANDLE_INIT_VALUE
+
+#include "panic.h"	// Panic codes
+#include "NOTIFY.H"
+#include "mSMSMESS.H"
+#include "mSMSREAD.H"
+#include "mSLOGGER.H"
+#include "ATIO.H"
+#include "mSMSSTOR.H"
+#include "ATINIT.H"
+
+#ifdef __LOGDEB__
+_LIT8(KLogEntry,"CATSmsMessagingRead::%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
+
+
+
+CATSmsMessagingRead* CATSmsMessagingRead::NewL (CATIO* aIo, CTelObject* aTelObject,
+												CATInit* aInit, CPhoneGlobals* aMmStatus)
+	{
+	CATSmsMessagingRead* self = new (ELeave) CATSmsMessagingRead(aIo, aTelObject, aInit, aMmStatus);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+CATSmsMessagingRead::CATSmsMessagingRead(CATIO* aIo, CTelObject* aTelObject,
+										 CATInit* aInit, CPhoneGlobals* aMmStatus)
+	:CATSmsCommands(aIo, aTelObject, aInit, aMmStatus),
+	iSmsStore(reinterpret_cast<CMobileSmsStore*>(aTelObject)),
+	iCancelled(EFalse)
+	{}
+
+
+void CATSmsMessagingRead::Start(TTsyReqHandle aTsyReqHandle, TAny* aParams)	
+	{
+	__ASSERT_DEBUG(aParams,Panic(EMobileSmsMessagingNullParameter));
+	__ASSERT_DEBUG(aTsyReqHandle!=TSY_HANDLE_INIT_VALUE,Panic(EMobileSmsMessagingNullParameter));
+
+	// Save the parameters into our class data
+	iReqHandle = aTsyReqHandle;
+	iCancelled=EFalse;
+	iMsgEntry = reinterpret_cast<RMobileSmsStore::TMobileGsmSmsEntryV1*>(aParams);
+	
+	iMsgLocation=iMsgEntry->iIndex;
+
+	iShortStoreName = iSmsStore->iStoreName;
+
+	// Change iPhoneGlobals->iMmTsyEventSignalActive so system knows that our EventSignal
+	// is active and requires sole use of the serial link to the phone.
+	if (ComparePrefMem(iShortStoreName))
+		{
+		// the compared memories are the same, so we can 
+		// start reading the message from the phone
+		StartReadSequence();
+		}
+	else 
+		{
+		// the compared memories are different, must change 
+		// phone mem to temporary mem.
+		SetCurrentPrefMem(iShortStoreName);
+		iState = EATWaitForSendingPrefMemComplete;
+		}
+	}
+
+
+void CATSmsMessagingRead::StartReadSequence()
+	{
+	iTxBuffer.Format(KSmsReadCommand, iMsgLocation);
+	iIo->Write(this, iTxBuffer);
+	iIo->SetTimeOut(this, 5000);
+	iState = EATWaitForSendingCMGRRequestComplete;
+	}
+
+
+void CATSmsMessagingRead::EventSignal(TEventSource aSource)
+//
+// Finite State Machine for handling events from the comm port
+//
+	{
+	LOGTEXT2(_L8("CATSmsMessagingRead:\tiState = %D"), iState);
+	if (aSource == ETimeOutCompletion)
+		{
+		LOGTEXT(_L8("CATSmsMessagingRead:\tTimeout Error during Sms Messaging Read"));
+		iPhoneGlobals->iPhoneStatus.iModemDetected = RPhone::EDetectedNotPresent;
+		RemoveStdExpectStrings();
+		if ((iState != EATWaitForPrefMemResponse) && (!ComparePrefMem(iShortStoreName)))
+			iPhoneGlobals->iPhonePrefMem = iShortStoreName;
+		if (iCancelled)
+			Complete(KErrCancel, aSource);
+		else
+			Complete(KErrTimedOut, aSource);
+		return;
+		}
+
+	switch (iState)
+		{
+		case EATWaitForSendingPrefMemComplete:
+			__ASSERT_ALWAYS(aSource == EWriteCompletion, Panic(EATCommand_IllegalCompletionWriteExpected));
+				{
+				iIo->WriteAndTimerCancel(this);
+				StandardWriteCompletionHandler(aSource, 5);
+				iState = EATWaitForPrefMemResponse;
+				}
+			break;
+
+	case EATWaitForPrefMemResponse:
+			__ASSERT_ALWAYS(aSource == EReadCompletion, Panic(EATCommand_IllegalCompletionReadExpected));
+				{
+				iIo->WriteAndTimerCancel(this);
+				RemoveStdExpectStrings();
+				TInt pos=iIo->BufferFindF(KCPMSResponseString);
+				if (pos == KErrNotFound)
+					{
+					LOGTEXT(_L8("CATSmsMessagingRead:\tCould not set preferred memory to client's pref'd mem"));
+					Complete(pos, aSource);
+					return;
+					}
+				LOGTEXT(_L8("CATSmsMessagingRead:\tPhone's pref'd memory successfully set to client's pref'd mem"));
+				iPhoneGlobals->iPhonePrefMem=iShortStoreName;
+				if (iCancelled)
+					Complete(KErrCancel,aSource);
+				else
+					StartReadSequence();
+				}
+			break;
+
+	case EATWaitForSendingCMGRRequestComplete:
+		__ASSERT_ALWAYS(aSource == EWriteCompletion, Panic(EATCommand_IllegalCompletionWriteExpected));
+		iIo->WriteAndTimerCancel(this);
+		StandardWriteCompletionHandler(aSource, 50);
+		AddCmsErrorExpectString();					// Defect fix 2/7/00, see "release.txt"
+		iState=EATWaitForCMGRResponseComplete;
+		break;
+	
+	case EATWaitForCMGRResponseComplete:
+		__ASSERT_ALWAYS(aSource == EReadCompletion, Panic(EATCommand_IllegalCompletionReadExpected));
+			{
+			iIo->WriteAndTimerCancel(this);
+			RemoveStdExpectStrings();
+			RemoveCmsErrorExpectString();			// Defect fix 2/7/00, see "release.txt"
+			TRAPD(ret, CMGRResponseL());
+
+			if ((iMsgLength==0) && (ret==KErrNone))
+				{
+				LOGTEXT(_L8("CATSmsMessagingRead:\tThe Client has Read from a message location that is empty"));
+				ret=KErrNotFound;
+				}
+			Complete(ret,aSource);
+			}
+		break;
+
+	default:
+		break;
+		}
+	}
+
+void CATSmsMessagingRead::CMGRResponseL()
+//
+// Parse the +CMGR: message from the ME.
+// It is of the form +CMGR: <Msg Status>,<Msg Length> <New line> PDU
+//
+	{
+	ParseBufferLC();
+	CATParamListEntry* entry;
+	TDblQueIter<CATParamListEntry> iter(iRxResults);
+	iMsgLength = 0;
+
+	entry=iter++;
+	if((!entry)||(entry->iResultPtr!=KCMGRResponseString))
+		User::Leave(KErrNotFound);
+
+	LOGTEXT(_L8("CATSmsMessagingRead:\tFound +CMGR String!"));
+
+// Read the message status
+	entry=iter++;
+	if(!entry)
+		User::Leave(KErrGeneral);
+	TLex8 msgStatLex((entry->iResultPtr).Ptr());
+	TUint msgStat;
+	(void)User::LeaveIfError(msgStatLex.Val(msgStat));
+
+// Read the message length
+	entry=iter++;
+	if(!entry)
+		User::Leave(KErrGeneral);
+	if(entry->iResultPtr.Length()==0)
+		{
+		entry=iter++;
+		if(!entry)
+			User::Leave(KErrGeneral);
+		}
+
+	TLex8 msgLenLex((entry->iResultPtr).Ptr());
+	(void)User::LeaveIfError(msgLenLex.Val(iMsgLength));
+
+	entry=iter++;
+	if(!entry)
+		User::Leave(KErrGeneral);
+
+	TSpecialPdu asciiPdu;
+	asciiPdu = entry->iResultPtr;
+
+	(void)User::LeaveIfError(CATSmsUtils::ConvertAsciiToBinary(asciiPdu,iPdu));
+	TPtrC8 pduPtr(iPdu);
+
+	if (iMsgLength*2 != asciiPdu.Length())
+		{
+		// There is an SCA prepended so remove this and store it in iGsmServiceCentre
+		PopulateScaFieldsAndRemove(pduPtr,iGsmServiceCentre);
+		}
+
+	if(iMsgEntry)
+		{
+		iMsgEntry->iMsgData.Copy(pduPtr);
+		iMsgEntry->iMsgStatus = GsmMsgStatusToStoreStatus(msgStat);
+		}
+
+	CleanupStack::PopAndDestroy();
+	}
+
+
+void CATSmsMessagingRead::PopulateScaFieldsAndRemove(TPtrC8& aPdu, RMobilePhone::TMobileAddress& aGsmServiceCentre)
+//
+// Populate the SCA field in the MM ETel structure from the SCA prepended in a received PDU.
+//
+	{
+	const TUint8 KTONBitMask =0x70;
+	const TUint8 KNPIBitMask=0x0f;
+	const TUint8 KTONBitShift=4;
+	const TUint8 KNPIBitShift=0;
+	_LIT(KInternationalPrefix,"+");
+
+	__ASSERT_ALWAYS(aPdu.Length()>0,Panic(ECMTHandlerDesPassedWithZeroLength));
+
+	aGsmServiceCentre.iTypeOfNumber=(RMobilePhone::TMobileTON)0;
+	aGsmServiceCentre.iNumberPlan=(RMobilePhone::TMobileNPI)0;
+	aGsmServiceCentre.iTelNumber.Zero();
+	
+	TUint8 len=aPdu[0];
+	
+	if(len==0)
+		{
+		// A zero length SCA has been prepended - just strip this first byte off
+		aPdu.Set(aPdu.Mid(len+1));
+		return;
+		}
+
+	TUint8 numDes=aPdu[1];
+	aGsmServiceCentre.iTypeOfNumber=(RMobilePhone::TMobileTON)((numDes&KTONBitMask)>>KTONBitShift);
+	aGsmServiceCentre.iNumberPlan=(RMobilePhone::TMobileNPI)((numDes&KNPIBitMask)>>KNPIBitShift);
+
+	if(aGsmServiceCentre.iTypeOfNumber==RMobilePhone::EInternationalNumber)
+		aGsmServiceCentre.iTelNumber.Append(KInternationalPrefix);
+
+	TInt i;
+	TUint16 digit;
+	for(i=2;i<(len+1);i++)
+		{
+		digit=(TUint16)((aPdu[i]&0x0f)+0x30);
+		aGsmServiceCentre.iTelNumber.Append(digit);
+		digit=(TUint16)(((aPdu[i]&0xf0)>>4)+0x30);
+		if(digit==0x003f)		// 'F' is the padding digit at the end of a number
+			break;
+		aGsmServiceCentre.iTelNumber.Append(digit);
+		}
+	aPdu.Set(aPdu.Mid(len+1));
+	}
+
+void CATSmsMessagingRead::Stop(TTsyReqHandle aTsyReqHandle)
+//
+//	Attempts to halt the process
+//
+	{
+	LOCAL_LOGTEXT("Stop","Enter function");
+	__ASSERT_ALWAYS(aTsyReqHandle == iReqHandle,Panic(EIllegalTsyReqHandle));		
+
+	LOGTEXT2(_L8("Current state TSY is cancelling from %d"), iState);
+	// Wait for convenient place in state machine to cancel
+	iCancelled=ETrue;
+	}
+
+void CATSmsMessagingRead::Complete(TTsyReqHandle aReqHandle,TInt aError)
+	{
+	iReqHandle=aReqHandle;
+	Complete(aError, EReadCompletion);
+	}
+
+void CATSmsMessagingRead::Complete(TInt aError,TEventSource aSource)
+	{
+	LOCAL_LOGTEXT("Complete","Enter function");
+	iIo->WriteAndTimerCancel(this);
+	iIo->RemoveExpectStrings(this);
+	iOKExpectString = NULL;
+	iErrorExpectString = NULL;
+	iPhoneGlobals->iEventSignalActive = EFalse;
+	if (iReqHandle != 0)
+		iTelObject->ReqCompleted(iReqHandle, aError);
+	if (aSource==EWriteCompletion)
+		iIo->Read();
+
+	//
+	// Call our base classes Complete so that
+	// we allow it do what ever it needs to do.
+	CATCommands::Complete(aError,aSource);
+
+	LOCAL_LOGTEXT("Complete","Exit function");
+	}
+
+
+void CATSmsMessagingRead::CompleteWithIOError(TEventSource /*aSource*/,TInt aStatus)
+	{
+	if (iState!=EATNotInProgress)
+		{
+		iIo->WriteAndTimerCancel(this);
+		iMsgLocation=NULL;
+		iTelObject->ReqCompleted(iReqHandle, aStatus);
+		iState = EATNotInProgress;
+		}
+	}
+
+RMobileSmsStore::TMobileSmsStoreStatus CATSmsMessagingRead::GsmMsgStatusToStoreStatus(TInt aMsgStat)
+/** 
+ * This method converts a GSM message status to Multimode message satus. 
+ */
+	{
+	switch (aMsgStat)
+		{
+		case 0: // The SMS is received but unread
+			return RMobileSmsStore::EStoredMessageUnread;
+		case 1: // The SMS is received and read
+			return RMobileSmsStore::EStoredMessageRead;
+		case 2: // The SMS is stored but unsent
+			return RMobileSmsStore::EStoredMessageUnsent;
+		case 3: // The SMS is stored and Sent
+			return RMobileSmsStore::EStoredMessageSent;
+
+		default: // All other status values
+			return RMobileSmsStore::EStoredMessageUnknownStatus;
+		}
+	}
+