--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyserverplugins/multimodetsy/Multimode/sms/mSMSMESS.CPP Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,837 @@
+// Copyright (c) 2001-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:
+// Implements Sms Extensions
+//
+//
+
+#include <etelmm.h>
+#include <etelmmerr.h> // for Multimode specific error codes
+
+#include "ATINIT.H"
+#include "mSMSMESS.H"
+#include "mSLOGGER.H"
+#include "mSMSSEND.H"
+#include "mSMSCSCA.H"
+#include "mSSETSC.H"
+#include "set_cmti_mode.h" // for CATSetPhoneToCMTIMode
+#include "set_cmt_mode.h" // for CATSetPhoneToCMTMode
+#include "sms_rx_queue.h" // for CReceiveSmsQueue
+#include "cmti_stored.h" // for CATSmsWaitForAndHandleCMTIStored
+#include "cmt_unstored.h" // for CATSmsWaitForAndHandleCMTUnstored
+#include "panic.h" // TSY panic codes and ::Panic function
+
+
+//
+// Macros
+//
+#define UNPACK_PCKG(target,source,datatype) datatype& target=(*(TPckg<datatype>*)source)()
+
+#ifdef __LOGDEB__
+_LIT8(KLogEntry,"CMobileSmsMessaging::%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
+
+
+//
+// Class Implementation
+//
+CMobileSmsMessaging* CMobileSmsMessaging::NewL(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+/**
+ * Standard NewL constructor.
+ */
+ {
+ CMobileSmsMessaging* subsession=new(ELeave) CMobileSmsMessaging(aATIO,aInit,aPhoneGlobals);
+ CleanupStack::PushL(subsession);
+ subsession->ConstructL();
+ CleanupStack::Pop();
+ return subsession;
+ }
+
+
+CMobileSmsMessaging::CMobileSmsMessaging(CATIO* aIo,CATInit* aInit,CPhoneGlobals* aGlobals)
+ :iIo(aIo)
+ ,iInit(aInit)
+ ,iGlobals(aGlobals)
+ ,iCurrentRxMode(RMobileSmsMessaging::EReceiveModeUnspecified)
+/**
+ * C++ constructor
+ */
+ {
+ }
+
+void CMobileSmsMessaging::ConstructL()
+/**
+ * Standard 2nd phase constructor.
+ * Creates the AT objects which are used to communicate with phone.
+ */
+ {
+ iATSmsMessagingSend = CATSmsMessagingSend::NewL(iIo,this,iInit,iGlobals);
+ iATSmsMemoryStorage = CATSmsMemoryStorage::NewL(iIo,this,iInit,iGlobals);
+ iATSmsGetSCAddress = CATSmsGetSCAddress::NewL(iIo,this,iInit,iGlobals);
+ iATSmsSetSCAddress = CATSmsSetSCAddress::NewL(iIo,this,iInit,iGlobals);
+ iGetSmspList = new(ELeave) CArrayPtrFlat<CListReadAllAttempt>(1);
+
+ // Create the object which we will use to set the phone to use CMTI mode
+ iATSetPhoneToCMTIMode=CATSetPhoneToCMTIMode::NewL(iIo,this,iInit,iGlobals,iCurrentRxMode);
+
+ // Create the object which we will use to set the phone to use CMT mode
+ iATSetPhoneToCMTMode=CATSetPhoneToCMTMode::NewL(iIo,this,iInit,iGlobals,iCurrentRxMode);
+
+ // Create queue for received SMS messages
+ iReceiveSmsQueue=CReceiveSmsQueue::NewL(iIo,this,iInit,iGlobals,*this);
+
+ // Store pointer to our CReceiveSmsQueue object in CPhoneGlobals
+ // so that the CATCommands::Complete method can prod the object when
+ // the serial port is not being used. This is to allow the CRececiveSmsQueu
+ // object to read any PDUs from the phones memory that it needs to.
+ // Ownership of the iReceiveSmsQueue stays with this class.
+ iGlobals->iReceiveSmsQueuePtr=iReceiveSmsQueue;
+
+ // Create the object that will listen for CMTI commands from the phone
+ // and will populate our received SMS queue
+ iWaitForCMTIStored=CATSmsWaitForAndHandleCMTIStored::NewL(iIo,this,iGlobals,*iReceiveSmsQueue);
+
+ // Create the object that will listen for CMT commands from the phone
+ // and will populate our received SMS queue
+ iWaitForCMTUnstored=CATSmsWaitForAndHandleCMTUnstored::NewL(iIo,this,iGlobals,*iReceiveSmsQueue);
+ }
+
+CMobileSmsMessaging::~CMobileSmsMessaging()
+/**
+ * C++ destructor
+ * Destroys the AT objects created during construction
+ */
+ {
+ delete iWaitForCMTUnstored;
+ delete iWaitForCMTIStored;
+
+ // We gave CPhoneGlobals a copy of the pointer to iReceiveSmsQueue.
+ // So we have to null that copy before we destory the one and only
+ // CReceiveSmsQueue object which this class owns.
+ if(iGlobals)
+ iGlobals->iReceiveSmsQueuePtr=NULL;
+ delete iReceiveSmsQueue;
+
+ delete iATSetPhoneToCMTMode;
+ delete iATSetPhoneToCMTIMode;
+
+ if (iGlobals)
+ iGlobals->iNotificationStore->RemoveClientFromLastEvents(this);
+ delete iATSmsMessagingSend;
+ delete iATSmsMemoryStorage;
+ delete iATSmsGetSCAddress;
+ delete iATSmsSetSCAddress;
+ if(iGetSmspList) // This prevents an Access Violation when CommDB is missing
+ {
+ iGetSmspList->ResetAndDestroy();
+ delete iGetSmspList;
+ }
+ }
+
+
+TInt CMobileSmsMessaging::CancelService(const TInt aIpc,const TTsyReqHandle aTsyReqHandle)
+/**
+ * Attempts to cancel a service.
+ * @param aIpc The number of the IPC to be cancelled
+ * @param aTsyReHandle The handle of the request which started the IPC
+ * @return Standard KErr... codes
+ */ {
+ TInt ret(KErrNone);
+ switch (aIpc)
+ {
+ case EMobileSmsMessagingGetMessageStoreInfo:
+ iATSmsMemoryStorage->CancelCommand(aTsyReqHandle);
+ break;
+
+ case EMobileSmsMessagingSendMessage:
+ iATSmsMessagingSend->CancelCommand(aTsyReqHandle);
+ break;
+
+ case EMobileSmsMessagingReceiveMessage:
+ CancelReceiveMessage();
+ break;
+
+ case EMobileSmsMessagingGetSmspListPhase1:
+ iATSmsGetSCAddress->CancelCommand(aTsyReqHandle);
+ break;
+
+ case EMobileSmsMessagingStoreSmspList:
+ iATSmsSetSCAddress->CancelCommand(aTsyReqHandle);
+ break;
+
+ case EMobileSmsMessagingSetReceiveMode:
+ case EMobileSmsMessagingGetSmspListPhase2:
+ default:
+ // can't do anything to cancel these requests
+ break;
+
+ }
+ return ret;
+ }
+
+void CMobileSmsMessaging::Init()
+/**
+ * TSY Intialization
+ * This method has to be implemented as it is pure virtual in MTelObjectTSY.
+ * In this case there is no intialization that needs to be done.
+ */
+ {}
+
+
+CTelObject* CMobileSmsMessaging::OpenNewObjectByNameL(const TDesC& aName)
+/**
+ * This method responds to request made by a client of Etel to create a new object of some kind.
+ * Known names are defined in ETELMM.H with the following identifiers...
+ * KETelMeSmsStore
+ * KETelCombinedSmsStore
+ * KETelIccSmsStore
+ * @param aName Descriptor holding the name of the new object to be created
+ * @return A pointer to the newly created object or NULL if aName was not recognised
+ */
+ {
+ if (aName.Compare(KETelMeSmsStore)==0)
+ {
+ TStorageType storeType(KMEStorage);
+ return CMobileSmsStore::NewL(iIo,iInit,iGlobals,storeType);
+ }
+
+ if (aName.Compare(KETelIccSmsStore)==0)
+ {
+ TStorageType storeType(KSMStorage);
+ return CMobileSmsStore::NewL(iIo,iInit,iGlobals,storeType);
+ }
+
+ if (aName.Compare(KETelCombinedSmsStore)==0)
+ {
+ TStorageType storeType(KMTStorage);
+ return CMobileSmsStore::NewL(iIo,iInit,iGlobals,storeType);
+ }
+
+ // Store not supported
+ User::Leave(KErrNotFound);
+ return NULL;
+ }
+
+
+CTelObject* CMobileSmsMessaging::OpenNewObjectL(TDes& /*aNewName*/)
+/**
+ * The use of this method is not supported in the MMTSY.
+ * @leave This method always leaves with KErrNotSupported
+ */
+ {
+ User::Leave(KErrNotSupported);
+ return NULL;
+ }
+
+
+CTelObject::TReqMode CMobileSmsMessaging::ReqModeL(const TInt aIpc)
+/**
+ * This method returns the KReq... mode(s) for a given IPC.
+ * @leave This method will leave with KErrNotSupported if aIpc is not recognized.
+ * @param aIpc The number of the IPC which is being queried
+ * @return The request mode to use for aIpc
+ */
+ {
+ // Check the IPC number is valid
+ if(!IsSupportedIPC(aIpc))
+ User::Leave(KErrNotSupported);
+
+ CTelObject::TReqMode ret=0;
+ switch (aIpc)
+ {
+ // TSYs wishing to implement their own buffering algorithm will place all requests in this category.
+ // For SMS - ReceiveMessage is in this category because incoming SMS are queued in TSY
+ case EMobileSmsMessagingReceiveMessage:
+ case EMobileSmsMessagingGetReceiveMode:
+ case EMobileSmsMessagingGetCaps:
+ case EMobileSmsMessagingGetSmspListPhase2:
+ ret=0;
+ break;
+
+ // KReqModeFlowControlObeyed
+ // Commands that change the state of the modem, e.g. setting the monitor volume level; in other words,
+ // those commands that the TSY should only deal with one at a time.
+ case EMobileSmsMessagingSetReceiveMode:
+ case EMobileSmsMessagingSendMessage:
+ case EMobileSmsMessagingEnumerateMessageStores:
+ case EMobileSmsMessagingGetMessageStoreInfo:
+ case EMobileSmsMessagingGetSmspListPhase1:
+ case EMobileSmsMessagingStoreSmspList:
+ ret=KReqModeFlowControlObeyed;
+ break;
+
+ // KReqModeRePostImmediately
+ // Requests that notify a client about a change of state, where the TSY needs to distinguish between
+ // different clients.
+
+
+ // KReqModeMultipleCompletionEnabled
+ // Either (a) commands that may take some time, but which the TSY can handle more than one of concurrently, or
+ // (b) notifications that the TSY does not wish to be re-posted immediately, so the server does no buffering.
+
+ // KReqModeMultipleCompletionEnabled | KReqModeFlowControlObeyed
+ // Commands that request information from the modem that is not cached, hence takes a finite amount of time.
+ // The TSY should only deal with one of these commands at a time.
+
+ // KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately
+ // Requests that notify a client about a change of state. Since these requests do not require the issuing
+ // of any modem commands, they do not have to obey flow control. The TSY never gets more than one of these
+ // outstanding per TelObject.
+ case EMobileSmsMessagingNotifySmspListChange:
+ ret=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately;
+ break;
+ }
+
+ // Check if the data port is currently loaned. If it is and the requested IPC
+ // is flow controlled then block Etel calling the IPC by leaving with KErrInUse
+ if((ret&KReqModeFlowControlObeyed) && iGlobals->iPhoneStatus.iDataPortLoaned)
+ {
+ LOGTEXT2(_L8("ReqModeL Leaving with KErrInUse as data port is loaned (aIpc=%d)"),aIpc);
+ User::Leave(KErrInUse);
+ }
+
+ return ret;
+ }
+
+TInt CMobileSmsMessaging::NumberOfSlotsL(const TInt /*aIpc*/)
+ {
+ // No SMS notifications are supported by this TSY
+ User::Leave(KErrNotSupported);
+ return 1; // Execution should never get here
+ }
+
+TInt CMobileSmsMessaging::RegisterNotification(const TInt /*aIpc*/)
+ {
+ // No SMS notifications are supported by this TSY
+ return KErrNone;
+ }
+
+TInt CMobileSmsMessaging::DeregisterNotification(const TInt /*aIpc*/)
+ {
+ // No SMS notifications are supported by this TSY
+ return KErrNone;
+ }
+
+TInt CMobileSmsMessaging::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc,const TDataPackage& aPackage)
+/**
+ * Sms Read/Send Dispatch Function.
+ *
+ * If this method returns with an KErr code apart from KErrNone then Etel will
+ * complete and destory the clients request for us.
+ *
+ * @param aTsyReqHandle The handle of the request which started the IPC
+ * @param aIpc The IPC being requested
+ * @param aPackage Package of parameters associated with the IPC
+ * @return Standard KErr... codes
+*/
+ {
+ if(!IsSupportedIPC(aIpc))
+ return KErrNotSupported;
+
+ // Prior to dispatch check that we're not setting up or in the middle of a data or fax call
+ if((iGlobals->iPhoneStatus.iPortAccess==EPortAccessDenied) || (iGlobals->iPhoneStatus.iMode == RPhone::EModeOnlineData))
+ {
+ LOGTEXT2(_L8("CMobileSmsMessaging::ExtFunc (aIpc=%d)"),aIpc);
+ LOCAL_LOGTEXT("ExtFunc","Port Access Denied/Mode Online flag detected");
+ switch(aIpc)
+ {
+ // These may interfere with Fax or Data call, so error the request now...
+ case EMobileSmsMessagingSendMessage:
+ case EMobileSmsMessagingSetReceiveMode:
+ case EMobileSmsMessagingStoreSmspList:
+ case EMobileSmsMessagingEnumerateMessageStores:
+ case EMobileSmsMessagingGetSmspListPhase1:
+ case EMobileSmsMessagingGetMessageStoreInfo:
+ LOCAL_LOGTEXT("ExtFunc","Returning KErrAccessDenied as request may intefere with fax");
+ return KErrAccessDenied;
+ }
+ }
+
+ //
+ // Handle IPC which use one parameter
+ __ASSERT_DEBUG(aPackage.Des1n(),Panic(EMobileSmsMessagingNullParameter));
+ switch(aIpc)
+ {
+ case EMobileSmsMessagingSetReceiveMode:
+ return SetReceiveMode(aTsyReqHandle,aPackage.Des1n());
+
+ case EMobileSmsMessagingGetReceiveMode:
+ return GetReceiveMode(aTsyReqHandle,aPackage.Des1n());
+
+ case EMobileSmsMessagingGetCaps:
+ return GetCaps(aTsyReqHandle,aPackage.Des1n());
+
+ case EMobileSmsMessagingStoreSmspList:
+ return StoreSmspList(aTsyReqHandle,aPackage.Des1n());
+
+ case EMobileSmsMessagingEnumerateMessageStores:
+ return EnumerateMessageStores(aTsyReqHandle, aPackage.Des1n());
+ }
+
+ //
+ // Handle IPC which use two parameters
+ __ASSERT_DEBUG(aPackage.Des2n(),Panic(EMobileSmsMessagingNullParameter));
+
+ switch (aIpc)
+ {
+ case EMobileSmsMessagingGetSmspListPhase1:
+ return GetSmspListPhase1(aTsyReqHandle,aPackage.Des1n(),aPackage.Des2n());
+
+ case EMobileSmsMessagingGetSmspListPhase2:
+ return GetSmspListPhase2(aTsyReqHandle,aPackage.Des1n(),aPackage.Des2n());
+
+ case EMobileSmsMessagingSendMessage:
+ return SendMessage(aTsyReqHandle,aPackage.Des1n(),aPackage.Des2n());
+
+ case EMobileSmsMessagingReceiveMessage:
+ return ReceiveMessage(aTsyReqHandle,aPackage.Des1n(),aPackage.Des2n());
+
+ case EMobileSmsMessagingGetMessageStoreInfo:
+ return GetMessageStoreInfo(aTsyReqHandle,aPackage.Des1n(),aPackage.Des2n());
+ }
+
+ // Never expect code to execute this far
+ __ASSERT_DEBUG(EFalse,Panic(EMobileSmsMessagingUnexpectedState));
+ return KErrNotSupported;
+ }
+
+
+//
+// Methods called by ExtFunc...
+//
+TInt CMobileSmsMessaging::SetReceiveMode(const TTsyReqHandle aTsyReqHandle,TDes8* aParam1)
+/**
+ * Called by ExtFunc.
+ */
+ {
+ // Unpack parameters to lowest usable data type and then process them
+ UNPACK_PCKG(mode,aParam1,RMobileSmsMessaging::TMobileSmsReceiveMode);
+ TInt ret(KErrNone);
+
+ switch(mode)
+ {
+ case RMobileSmsMessaging::EReceiveUnstoredPhoneAck:
+ LOCAL_LOGTEXT("SetReceiveMode","Client has requested EReceiveUnstoredPhoneAck mode");
+ iATSetPhoneToCMTMode->ExecuteCommand(aTsyReqHandle,NULL);
+ break;
+
+ case RMobileSmsMessaging::EReceiveStored:
+ LOCAL_LOGTEXT("SetReceiveMode","Client has requested EReceiveStored mode");
+ iATSetPhoneToCMTIMode->ExecuteCommand(aTsyReqHandle,NULL);
+ break;
+
+ default:
+ ret=KErrNotSupported;
+ }
+
+ return ret;
+ }
+
+TInt CMobileSmsMessaging::GetReceiveMode(const TTsyReqHandle aTsyReqHandle,TDes8* aParam1)
+/**
+ * Return the current SMS Reception Mode.
+ */
+ {
+ LOCAL_LOGTEXT("GetReceiveMode","Enter function");
+
+ // Unpack parameters to lowest usable data type and then process them
+ UNPACK_PCKG(recMode,aParam1,RMobileSmsMessaging::TMobileSmsReceiveMode);
+
+ //
+ // Pass current rx mode to client
+ recMode=iCurrentRxMode;
+
+ //
+ // Complete clients request
+ ReqCompleted(aTsyReqHandle,KErrNone);
+
+ LOCAL_LOGTEXT("GetReceiveMode","Exit function");
+ return KErrNone;
+ }
+
+TInt CMobileSmsMessaging::ReceiveMessage(const TTsyReqHandle aReqHandle,TDes8* aParam1,TDes8* aParam2)
+/**
+ * Called by ExtFunc to process a client request to receive an incoming SMS message.
+ */
+ {
+ LOCAL_LOGTEXT("ReceiveMessage","Enter function");
+
+ if (iCurrentRxMode == RMobileSmsMessaging::EReceiveModeUnspecified)
+ {
+ return(KErrNotSupported);
+ }
+
+ // Validate that phone has been put into a known receive mode
+ __ASSERT_DEBUG(iCurrentRxMode==RMobileSmsMessaging::EReceiveStored ||
+ iCurrentRxMode==RMobileSmsMessaging::EReceiveUnstoredPhoneAck,Panic(EMobileSmsMessagingPhoneNotSetToASupportedReceiveMode));
+
+ if (iReceiveSmsQueue->ClientReqOutstanding())
+ {
+ // Client request already posted
+ // TSY only supports one client at a time waiting for an SMS
+ return KErrInUse;
+ }
+
+ // Ensure our CMT or CMTI listener has been enabled (as appropriate)
+ if (iCurrentRxMode == RMobileSmsMessaging::EReceiveStored)
+ {
+ iWaitForCMTIStored->Enable();
+ }
+ else if (iCurrentRxMode == RMobileSmsMessaging::EReceiveUnstoredPhoneAck)
+ {
+ iWaitForCMTUnstored->Enable();
+
+ if (iGlobals->iModemSupportsCMTIMode)
+ // CTMI parsing should be enabled if supported for receive unstored,
+ // phone ack mode. See GSM 07.05 section 3.4.1 and defect SHY-54GFHD
+ {
+ iWaitForCMTIStored->Enable();
+ }
+ }
+
+ // Unpack parameters to lowest usable data type and then process them
+ RMobileSmsMessaging::TMobileSmsGsmTpdu* pdu=STATIC_CAST(RMobileSmsMessaging::TMobileSmsGsmTpdu*,aParam1);
+ UNPACK_PCKG(attr,aParam2,RMobileSmsMessaging::TMobileSmsReceiveAttributesV1);
+
+ iReceiveSmsQueue->PopAndCompleteClientWhenPossible(aReqHandle,pdu,&attr);
+ return KErrNone;
+ }
+
+void CMobileSmsMessaging::CancelReceiveMessage()
+/**
+ * Called by ExtFunc to cancel a ReceiveMessage request
+ */
+ {
+ LOCAL_LOGTEXT("CancelReceiveMessage","Enter function");
+ iWaitForCMTIStored->Disable();
+ iWaitForCMTUnstored->Disable();
+ iReceiveSmsQueue->PopAndCompleteClientWhenPossibleCancel();
+ }
+
+
+TInt CMobileSmsMessaging::GetCaps(const TTsyReqHandle aTsyReqHandle,TDes8* aParam1)
+/**
+ * Called by ExtFunc.
+ */
+ {
+ // Unpack parameters to lowest usable data type and then process them
+ UNPACK_PCKG(caps,aParam1,RMobileSmsMessaging::TMobileSmsCapsV1);
+ switch(caps.ExtensionId())
+ {
+ case KETelExtMultimodeV1:
+ //
+ // We are rely on the phone having been intiialised for the SMS receive caps
+ // If the phone is not initialised complete with KErrNotReady
+ if(iGlobals->iPhoneStatus.iInitStatus != EPhoneInitialised)
+ {
+ // Phone is not yet initialised
+ ReqCompleted(aTsyReqHandle,KErrNotReady);
+ }
+ else
+ {
+ // Phone is initialised
+ caps.iSmsMode=RMobileSmsMessaging::KCapsGsmSms; // This TSY only supports GSM
+ caps.iSmsControl=0;
+ // Supports sending
+ caps.iSmsControl|=RMobileSmsMessaging::KCapsSendNoAck;
+
+ // If Phone supports AT+CSCA so say TSY supports SMSP list
+ if(iGlobals->iModemSupportsCSCAMode)
+ {
+ caps.iSmsControl|=RMobileSmsMessaging::KCapsGetSmspList;
+ caps.iSmsControl|=RMobileSmsMessaging::KCapsSetSmspList;
+ }
+
+ // The receive SMS mode capabiltiies were got during the initialisation of the TSY
+ if(iGlobals->iModemSupportsCMTIMode)
+ caps.iSmsControl|=RMobileSmsMessaging::KCapsReceiveStored;
+ if(iGlobals->iModemSupportsCMTMode)
+ caps.iSmsControl|=RMobileSmsMessaging::KCapsReceiveUnstoredPhoneAck;
+
+ ReqCompleted(aTsyReqHandle, KErrNone);
+ }
+ break;
+
+ default:
+ LOCAL_LOGTEXT("GetCaps","Unknown parameters version");
+ __ASSERT_DEBUG(EFalse,Panic(EMobileSmsMessagingUnknownParamVersion));
+ return KErrUnknown;
+ }
+ return KErrNone;
+ }
+
+
+
+
+TInt CMobileSmsMessaging::SendMessage(const TTsyReqHandle aTsyReqHandle,TDes8* aParam1,TDes8* aParam2)
+/**
+ * Called by ExtFunc to process EMobileSmsMessagingSendMessage IPC.
+ */
+ {
+ // Unpack parameters
+ UNPACK_PCKG(msgAttr,aParam2,RMobileSmsMessaging::TMobileSmsSendAttributesV1);
+
+ // Check if we can handle format of message
+ // Try to be optomistic, only reject message if we know we can't handle it
+ if(msgAttr.iFlags&RMobileSmsMessaging::KSmsDataFormat &&
+ msgAttr.iDataFormat!=RMobileSmsMessaging::EFormatUnspecified &&
+ msgAttr.iDataFormat!=RMobileSmsMessaging::EFormatGsmTpdu)
+ {
+ LOCAL_LOGTEXT("SendMessage","Format of given message not supported");
+ // Put extended error in upper 8-bits and core error in lower 8-bits
+ TInt error = (KErrMMEtelSmsFormatNotSupported << 8) | KErrNotSupported;
+ return error;
+ }
+ else
+ {
+ // Start active object that will do the sending for us
+ LOCAL_LOGTEXT("SendMessage","Starting CATSmsMessagingSend state machine");
+ iATSmsMessagingSend->SetMsgAttributes(&msgAttr);
+ iATSmsMessagingSend->ExecuteCommand(aTsyReqHandle,aParam1);
+ }
+
+ return KErrNone;
+ }
+
+//*********************************************************
+//* Enumerate Message Stores & Get Message Store Info
+//***********************************************************
+
+TInt CMobileSmsMessaging::EnumerateMessageStores(const TTsyReqHandle aTsyReqHandle,
+ TDes8* aParam1)
+ {
+ LOCAL_LOGTEXT("EnumerateMessageStores","Enter function");
+
+ if (iGlobals->iPhoneStatus.iInitStatus != EPhoneInitialised)
+ {
+ ReqCompleted(aTsyReqHandle,KErrNotReady);
+
+ return KErrNone;
+ }
+
+ UNPACK_PCKG(storeCount,aParam1,TInt);
+ iATSmsMemoryStorage->CopyDataFromCATInit(iInit);
+ storeCount = iATSmsMemoryStorage->GetNumberOfMessageStores();
+
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TInt CMobileSmsMessaging::GetMessageStoreInfo(const TTsyReqHandle aTsyReqHandle,
+ TDes8* aParam1, TDes8* aParam2)
+ {
+ LOCAL_LOGTEXT("GetMessageStoreInfo","Enter function");
+
+ if (iGlobals->iPhoneStatus.iInitStatus != EPhoneInitialised)
+ {
+ ReqCompleted(aTsyReqHandle,KErrNotReady);
+
+ return KErrNone;
+ }
+
+ UNPACK_PCKG(storeIndex,aParam1,TInt);
+
+ TInt ret(KErrNone);
+ ret=iATSmsMemoryStorage->WhichPreferredMem(storeIndex);
+ if(ret==KErrNone)
+ iATSmsMemoryStorage->Start(aTsyReqHandle,aParam2);
+
+ return ret;
+ }
+
+//*******************************************
+//* Get SMSP List
+//*******************************************
+TInt CMobileSmsMessaging::GetSmspListPhase1(const TTsyReqHandle aTsyReqHandle,
+ TDes8* aParam1,TDes8* aParam2)
+/** Get SMSP List Phase 1
+ *
+ * If the GetSmspListPhase1L should leave this method takes care of that and
+ * makes a premature ReqCompleted to the client.
+ *
+ * @param aTsyReqHandle the request ID
+ * @param aClient The client sends down a handle that is saved together with the
+ * list so the list can be returned to the right client in phase 2.
+ * @param aBufSiz The size of the retrieved network list. The size is set in
+ * @return error code.
+ */
+ {
+ LOCAL_LOGTEXT("GetSmspListPhase1","Enter function");
+
+ UNPACK_PCKG(clientId,aParam1,RMobilePhone::TClientId);
+ UNPACK_PCKG(bufSize,aParam2,TInt);
+
+ TRAPD(leaveCode,GetSmspListPhase1L(aTsyReqHandle,clientId,bufSize));
+ return leaveCode;
+ }
+
+
+void CMobileSmsMessaging::GetSmspListPhase1L(TTsyReqHandle aTsyReqHandle,
+ RMobilePhone::TClientId& aClient,
+ TInt& aBufSize)
+/** Get SMSP List Phase 1
+ *
+ * Phase 1 retrieves the only parameter support - the service centre addess
+ * with help of AT+CSCA?,
+ * The memory space needed to store the list is then calculated
+ * and returned to the client.The returned list is saved to be
+ * copied to the client in phase 2, when the client has alocated memory for it.
+ * The actual execution of the AT command (AT+CSCA) is done in the CATSmsGetSCAddress class.
+ *
+ * @param aTsyReqHandle const pointer to the request ID
+ * @param aClient The client sends down a handle that is saved together with the
+ * list so the list can be returned to the right client in phase 2.
+ * @param aBufSize The size of the retrieved network. The size is set in CATSmsGetSCAddress::ParseResponseL().
+ * @return error code.
+ */
+ {
+ LOCAL_LOGTEXT("GetSmspListPhase1L","Enter function");
+
+ CListReadAllAttempt* read=CListReadAllAttempt::NewL(&aClient,aTsyReqHandle);
+ CleanupStack::PushL(read);
+
+ iSmspListInfo.iBufSize = &aBufSize;
+ iSmspListInfo.iBufPtr = &(read->iListBuf);
+ iGetSmspList->AppendL(read);
+
+ iATSmsGetSCAddress->ExecuteCommand(aTsyReqHandle, &iSmspListInfo);
+
+ CleanupStack::Pop(read);
+ }
+
+TInt CMobileSmsMessaging::GetSmspListPhase2(const TTsyReqHandle aTsyReqHandle,
+ TDes8* aParam1,TDes8* aParam2)
+/** Get SMSP List phase 2
+ *
+ * In this metod the list which was retrieved during phase 1 is copied to
+ * the memory which the client has allocated for this purose.
+ * @param aTsyReqHandle Const pointer to the request ID
+ * @param aClient Handle to the client which list we are looking for.
+ * @param aBuf Pointer to the memory that the etelmm has allocated.
+ * @return error code.
+ */
+ {
+ LOCAL_LOGTEXT("GetSmspListPhase2","Enter function");
+
+ UNPACK_PCKG(clientId,aParam1,RMobilePhone::TClientId);
+
+ CListReadAllAttempt* read=NULL;
+ const TInt numberOfLists = iGetSmspList->Count();
+
+ // Find the get SMSP attempt from this client
+ for (TInt i = 0; i < numberOfLists; ++i)
+ {
+ read = iGetSmspList->At(i);
+ if ((read->iClient.iSessionHandle==clientId.iSessionHandle) &&
+ (read->iClient.iSubSessionHandle==clientId.iSubSessionHandle))
+ {
+
+ //
+ // We have to check that the listPtr is not NULL as if the phone/modem
+ // responds with a blank service centre listPtr==NULL.
+ CBufBase* listPtr=read->iListBuf;
+ if(listPtr)
+ {
+ TPtr8 bufPtr(listPtr->Ptr(0));
+ aParam2->Copy(bufPtr); // Copy the streamed list to the client
+ }
+
+ delete read;
+ iGetSmspList->Delete(i);
+ ReqCompleted(aTsyReqHandle,KErrNone); // Completes the retrieval of a network list succesfully.
+ return KErrNone;
+ }
+ }
+
+ Panic(EIllegalEvent);
+ return(KErrNotFound);
+ }
+
+TInt CMobileSmsMessaging::CompleteSmspListCancel(const TTsyReqHandle aTsyReqHandle)
+/** CompleteSmspListCancel
+ *
+ * This method is called from the CATSmsGetSCAddress class if a cancel is succesful
+ * It cleans-up the client's stored request data
+ * @param aTsyReqHandle Const pointer to the request ID
+ * @return error code.
+ */
+ {
+ LOGTEXT(_L8("CMobileSmsMessaging::GetSmspListCancel called"));
+ // Remove the read all attempt from iGetSmspList
+ CListReadAllAttempt* read=NULL;
+ for (TInt i=0; i<iGetSmspList->Count(); ++i)
+ {
+ read = iGetSmspList->At(i);
+ if (read->iReqHandle == aTsyReqHandle)
+ {
+ delete read;
+ iGetSmspList->Delete(i);
+ break;
+ }
+ }
+ ReqCompleted(aTsyReqHandle,KErrCancel);
+ return KErrNone;
+ }
+
+TInt CMobileSmsMessaging::StoreSmspList(const TTsyReqHandle aTsyReqHandle, TDes8* aBuffer)
+ {
+ LOGTEXT(_L8("CMobileSmsMessaging::StoreSmspList called"));
+ TInt leaveCode=KErrNone;
+ TRAP(leaveCode, (void)ProcessStoreSmspListL(aTsyReqHandle, aBuffer););
+ return leaveCode;
+ };
+
+TInt CMobileSmsMessaging::ProcessStoreSmspListL(TTsyReqHandle aTsyReqHandle, TDes8* aBuffer)
+ {
+ CMobilePhoneSmspList* smspList=CMobilePhoneSmspList::NewL();
+ CleanupStack::PushL(smspList);
+
+ smspList->RestoreL(*aBuffer);
+
+ // We only support one entry (the default entry)
+ if (smspList->Enumerate() != 1)
+ ReqCompleted(aTsyReqHandle, KErrNotSupported);
+
+ // Just get first entry - this is default entry contain SC address
+ iSCEntry=smspList->GetEntryL(0);
+
+ iATSmsSetSCAddress->ExecuteCommand(aTsyReqHandle,&(iSCEntry.iServiceCentre));
+
+ CleanupStack::PopAndDestroy(); // smspList
+ return KErrNone;
+ }
+
+
+TBool CMobileSmsMessaging::IsSupportedIPC(const TInt aIpc) const
+ {
+ switch(aIpc)
+ {
+ case EMobileSmsMessagingGetCaps:
+ case EMobileSmsMessagingSetReceiveMode:
+ case EMobileSmsMessagingGetReceiveMode:
+ case EMobileSmsMessagingSendMessage:
+ case EMobileSmsMessagingReceiveMessage:
+ case EMobileSmsMessagingEnumerateMessageStores:
+ case EMobileSmsMessagingGetMessageStoreInfo:
+ case EMobileSmsMessagingGetSmspListPhase1:
+ case EMobileSmsMessagingGetSmspListPhase2:
+ case EMobileSmsMessagingStoreSmspList:
+ return ETrue;
+
+ default:
+ return EFalse;
+ }
+ }