diff -r 000000000000 -r 3553901f7fa8 telephonyserverplugins/multimodetsy/Multimode/sms/mSMSWRIT.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/telephonyserverplugins/multimodetsy/Multimode/sms/mSMSWRIT.CPP Tue Feb 02 01:41:59 2010 +0200 @@ -0,0 +1,426 @@ +// 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: +// This writes an SMS message and stores the message location number. AT+CMGW=xx +// +// + +#include "NOTIFY.H" +#include "mSMSMESS.H" +#include "mSMSWRIT.H" +#include "mSLOGGER.H" +#include "ATIO.H" +#include "mSMSSTOR.H" +#include "smsutil.h" +#include "et_phone_util.h" + +_LIT8(KSmsWriteLengthCommand,"AT+CMGW = %d\r"); +_LIT8(KSmsWriteCommand,"AT+CMGW = %d,%d\r"); + +CATSmsMessagingWrite* CATSmsMessagingWrite::NewL(CATIO* aIo, CTelObject* aTelObject, CATInit* aInit, CPhoneGlobals* aMmStatus) + { + CATSmsMessagingWrite* self = new(ELeave) CATSmsMessagingWrite(aIo, aTelObject, aInit, aMmStatus); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +CATSmsMessagingWrite::CATSmsMessagingWrite(CATIO* aIo, CTelObject* aTelObject, CATInit* aInit, CPhoneGlobals* aMmStatus) + :CATSmsCommands(aIo, aTelObject, aInit, aMmStatus) + ,iExpectString(NULL) + ,iSmsEntry(NULL) + ,iCancelled(EFalse) + ,iSmsStore(reinterpret_cast(aTelObject)) + { + } + +CATSmsMessagingWrite::~CATSmsMessagingWrite() + {} + +void CATSmsMessagingWrite::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; + iSmsEntry = reinterpret_cast(aParams); + + iNextAttempt=iPhoneGlobals->iPhoneTestState; + // If undefined, try old standard first + if(iNextAttempt==CPhoneGlobals::EPhoneTestUndefined) + iNextAttempt=CPhoneGlobals::EPhoneTestOldStandard; + + iPhoneGlobals->iEventSignalActive = ETrue; + if (ComparePrefMem(iSmsStore->iStoreName)) + StartPduWrite(); + else // Compared memories are different + { + SetCurrentPrefMem(iSmsStore->iStoreName); + iState = EATWaitForSendingPrefMemComplete; + } + } + +void CATSmsMessagingWrite::EventSignal(TEventSource aSource) + { + LOGTEXT2(_L8("CATSmsMessagingWrite:\tiState = %D"), iState); + + if (aSource == ETimeOutCompletion) + { + LOGTEXT(_L8("CATSmsMessagingWrite:\tTimeout Error during Sms Messaging Write")); + iPhoneGlobals->iPhoneStatus.iModemDetected = RPhone::EDetectedNotPresent; + RemoveStdExpectStrings(); + if ((iState != EATWaitForPrefMemResponse)&&!ComparePrefMem(iSmsStore->iStoreName)) + iPhoneGlobals->iPhonePrefMem = iSmsStore->iStoreName; + Complete(KErrTimedOut, aSource); + return; + } //if + + switch(iState) + { + // the following 3 cases are special cases, occuring only when the PhonePrefMem != ClientPrefMem + case EATWaitForSendingPrefMemComplete: + // + // Finished writing preferred memory, now wait for response + // + { + HandleWriteCompletion(aSource); + iState = EATWaitForPrefMemResponse; + } + break; + + case EATWaitForPrefMemResponse: + // + // Got response from writing preferred memory. Validate response, and if + // successful, then start the write sequence + // + { + TInt ret=HandleResponseCompletion(aSource,EFalse); + if (ret!=KErrNone) + { + Complete(ret,aSource); + return; + } + TInt pos=iIo->BufferFindF(KCPMSResponseString); + if (pos == KErrNotFound) + { + Complete(pos, aSource); + return; + } + LOGTEXT(_L8("CATSmsMessagingWrite:\tPhone's preferred memory successfully set to client's preferred memory.")); + iPhoneGlobals->iPhonePrefMem=iSmsStore->iStoreName; + if (iCancelled) + Complete(KErrCancel,aSource); + else + StartPduWrite(); + } + break; + + case EATWaitForSendingPduLengthComplete: + // + // Finished sending pdu length command, now wait for response + // + { + HandleWriteCompletion(aSource); + iExpectString=iIo->AddExpectString(this,KSmsEnterPduModeResponse,ETrue); // Expecting "> " + iIo->SetTimeOut(this, 5000); + iState=EATReadPduEnterPduModeResponseCompleted; + } + break; + + case EATReadPduEnterPduModeResponseCompleted: + // + // Received a response to the pdu length command. Validate, and if successful + // send the actual pdu in ascii form + // + { + TInt ret=HandleResponseCompletion(aSource,EFalse); + if (ret!=KErrNone) + { + Complete(ret,aSource); + return; + } + ret=ConvertCMSErrorToKErr(CMSErrorValue()); + iIo->RemoveExpectString(iExpectString); + iExpectString=NULL; + if(ret) + { + Complete(ret,aSource); + return; + } + iMsgDataAscii.Append(KCtrlZChar); // Adding the CTRL-Z that indicates the end of the PDU + iIo->Write(this,iMsgDataAscii); + iIo->SetTimeOut(this, 5000); + iState=EATWaitForSendingPduComplete; + } + break; + + case EATWaitForSendingPduComplete: + // + // Finished writing pdu, wait for a response + // + { + HandleWriteCompletion(aSource); + iState=EATReadSmsRefNumCompleted; + } + break; + + case EATReadSmsRefNumCompleted: + // + // Received response to pdu write, validate and if successful set preferred + // memory back to original value if it was changed for this command, + // otherwise on failure try the new format if the current attempt used the + // old ETSI format + // + { + TInt ret=HandleResponseCompletion(aSource,EFalse); + if (ret!=KErrNone) + { + Complete(ret,aSource); + return; + } + TInt err=ConvertCMSErrorToKErr(CMSErrorValue()); + + if (err==KErrNone) + TRAP(err,ParseResponseL()); + + if(err!=KErrNone) + { + if (iCancelled) + Complete(KErrCancel,aSource); + else + { + // Try new standard if old standard failed + LOGTEXT2(_L8("CATSmsMessagingWrite:\tFailed with code %d"),err); + if (iNextAttempt==CPhoneGlobals::EPhoneTestOldStandard) + { + iNextAttempt=CPhoneGlobals::EPhoneTestNewStandard; + StartPduWrite(); + } + else + // Must have tried new standard and this failed too + Complete(err); + } + } + else + { + // If new standard worked then store this is as default for this phone + if (iNextAttempt==CPhoneGlobals::EPhoneTestNewStandard) + iPhoneGlobals->iPhoneTestState=CPhoneGlobals::EPhoneTestNewStandard; + Complete(KErrNone,aSource); + } + } + break; + + + case EATCancellingWaitForWriteComplete: + // + // Finished writing cancel request, now wait for response + // + { + __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected)); + AddStdExpectStrings(); + iIo->SetTimeOut(this); + iState=EATCancellingReadCompleted; + } + break; + + case EATCancellingReadCompleted: + // + // Cancel command response received + // + { + __ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected)); + iIo->WriteAndTimerCancel(this); + Complete(KErrCancel, aSource); + } + break; + + default: + break; + } + } + +void CATSmsMessagingWrite::StartPduWrite() +/** + * Kicks off the writing of the actual pdu. Begins by converting the pdu + * into ascii form, and writing the pdu length and message status to the phone. + */ + { + iMsgDataAscii.Zero(); + + // Convert PDU from binary to ASCII + CATSmsUtils::AppendDataToAscii(iMsgDataAscii,iSmsEntry->iMsgData); + if(iMsgDataAscii.Length()==0) + { + LOGTEXT(_L8("CATSmsMessagingWrite:\tStartPduWrite - Failed to convert binary PDU to ASCII")); + Complete(KErrCorrupt); + return; + } + + // Send PDU length to the phone + const TInt pduLengthSemiOctets(iMsgDataAscii.Length()); + const TInt pduLengthOctets(pduLengthSemiOctets/2+pduLengthSemiOctets%2); + + if (iNextAttempt==CPhoneGlobals::EPhoneTestNewStandard) + { + // Prepend a zero length SCA to PDU - this forces phone to use default SCA + // See GSM 07.05 for details + _LIT8(zeroLengthSca, "00"); + iMsgDataAscii.Insert(0,zeroLengthSca); + } + + iTxBuffer.Zero(); + TInt stat=SetMsgStatus(); + if (stat==KErrNotSupported) + iTxBuffer.Format(KSmsWriteLengthCommand,pduLengthOctets); + else + iTxBuffer.Format(KSmsWriteCommand,pduLengthOctets,stat); + iIo->Write(this,iTxBuffer); + iIo->SetTimeOut(this,5000); + iState=EATWaitForSendingPduLengthComplete; + } + +void CATSmsMessagingWrite::Complete(TInt aError) + { + Complete(aError, EReadCompletion); + } + +void CATSmsMessagingWrite::Complete(TInt aError, TEventSource aSource) + { + iIo->WriteAndTimerCancel(this); + iIo->RemoveExpectStrings(this); + iOKExpectString = NULL; + iErrorExpectString = NULL; + iExpectString = 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); + + iState = EATNotInProgress; + } + +void CATSmsMessagingWrite::ParseResponseL() +// +// Parse the message reference number and return in smsEntry.iIndex +// + { + LOGTEXT(_L8("CATSmsMessagingWrite:\tRetrieving message reference number")); + iBuffer.Set(iIo->Buffer()); + TInt pos = iBuffer.FindF(KCMGWResponseString); + if (pos == KErrNotFound) + { + LOGTEXT(_L8("CATSmsMessagingWrite:\tError - Cannot find '+CMGW:' string")); + pos = iBuffer.FindF(KErrorString); + if (pos != KErrNotFound) + User::Leave(KErrGeneral); + User::Leave(pos); + } + pos += 6; + + // Place the message reference number into buffer (ie: everything after +CMGW: string) + TInt woop = iBuffer.Length()-pos; + iBuffer.Set(iBuffer.Right(woop)); + + TLex8 yyLex(iBuffer); + yyLex.Inc(); // steps over the ':' Should always do this....NEVER falls over! + yyLex.SkipSpace(); + TUint val; + if(yyLex.Val(val)==KErrNone) // Grab the message reference number. + { + iSmsEntry->iIndex = val; + } + else + { + LOGTEXT(_L8("CATSmsMessagingWrite:\tError. Invalid Message Reference Number.")); + User::Leave(KErrGeneral); + } + } + +void CATSmsMessagingWrite::Stop(TTsyReqHandle aTsyReqHandle) +// +// Attempts to halt the process +// + { + __ASSERT_ALWAYS(aTsyReqHandle == iReqHandle,Panic(EIllegalTsyReqHandle)); + LOGTEXT(_L8("CATSmsMessagingWrite:\tCancelling Sms Write")); + + if ((iState==EATWaitForSendingPduLengthComplete) || + (iState==EATReadPduEnterPduModeResponseCompleted) || + (iState==EATWaitForSendingPduComplete) || + (iState==EATReadSmsRefNumCompleted)) + { + // Attempt to cancel write command if we can + RemoveStdExpectStrings(); + iIo->WriteAndTimerCancel(this); + iTxBuffer.Format(KEscapeChar); + iIo->Write(this,iTxBuffer); + iIo->SetTimeOut(this); + iState = EATCancellingWaitForWriteComplete; + } + else + // Wait until safe point to cancel the write + iCancelled=ETrue; + } + +void CATSmsMessagingWrite::CompleteWithIOError(TEventSource /*aSource*/,TInt aStatus) + { + if (iState!=EATNotInProgress) + { + iIo->WriteAndTimerCancel(this); + iTelObject->ReqCompleted(iReqHandle, aStatus); + iState = EATNotInProgress; + } + } + +TInt CATSmsMessagingWrite::SetMsgStatus() +// +// Sets the message status +// + { + TInt status; + switch(iSmsEntry->iMsgStatus) + { + case (RMobileSmsStore::EStoredMessageUnread): + status = 0; + break; + + case (RMobileSmsStore::EStoredMessageRead): + status = 1; + break; + + case (RMobileSmsStore::EStoredMessageUnsent): + status = 2; + break; + + case (RMobileSmsStore::EStoredMessageSent): + case (RMobileSmsStore::EStoredMessageDelivered): + status = 3; + break; + + default: + status = KErrNotSupported; + break; + } + return status; + } +