--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyserverplugins/common_tsy/commontsy/src/mmsms/cmmsmstsy.cpp Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,3154 @@
+// Copyright (c) 2006-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 FILES
+#include "cmmsmstsy.h"
+#include "cmmphonetsy.h"
+#include "cmmsmsstoragetsy.h"
+#include "cmmsmsgsmext.h"
+#include "cmmtsyreqhandlestore.h"
+#include <ctsy/serviceapi/mmtsy_ipcdefs.h>
+#include "MmTsy_numberOfSlots.h"
+#include <ctsy/serviceapi/cmmsmsutility.h>
+#include "cmmsmssendrequest.h"
+#include <ctsy/serviceapi/mstktsysatservice.h>
+#include "CMmCommonStaticUtility.h"
+#include <ctsy/serviceapi/gsmerror.h>
+#include <ctsy/pluginapi/cmmdatapackage.h>
+#include <etelsat.h> // for Sat MO SM Control error values
+
+
+// ======== MEMBER FUNCTIONS ========
+
+CMmSmsTsy::CMmSmsTsy()
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::CMmSmsTsy: constructor");
+ }
+
+void CMmSmsTsy::ConstructL()
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::ConstructL");
+#ifdef REQHANDLE_TIMER
+ //create req handle store
+ iTsyReqHandleStore = CMmTsyReqHandleStore::NewL( this, iMmPhone,
+ EMultimodeSmsMaxNumOfRequests, iSmsReqHandles );
+#else
+ // create req handle store
+ iTsyReqHandleStore = CMmTsyReqHandleStore::NewL(
+ EMultimodeSmsMaxNumOfRequests, iSmsReqHandles );
+#endif // REQHANDLE_TIMER
+
+ // Reset all CMmSmsTsy variables
+ ResetVariables();
+
+ // SMS message array
+ iSmsMsgArray = new ( ELeave ) CArrayPtrFlat<TSmsMsg>( 1 );
+
+ // Create GSM mode SMS extension
+ iMmSmsExtInterface = CMmSmsGsmExt::NewL();
+
+
+ // register sms tsy in the message manager
+ iMmPhone->MessageManager()->RegisterTsyObject(
+ CMmMessageManagerBase::ESmsMessagingTsy, this );
+
+ // at startup, there is no pending Send request
+ iSmsSendReq = NULL;
+
+ // Initialise off-line/on-line mode variable with information
+ // from PhoneTsy. After object construction, this information
+ // will be updated using DOS indications.
+ TRfStateInfo phoneRfInfo = iMmPhone->GetRfStateInfo();
+ if ( ERfsStateInfoInactive == phoneRfInfo )
+ {
+ iIsOffline = ETrue;
+ }
+ else
+ {
+ iIsOffline = EFalse;
+ }
+TFLOGSTRING2("TSY: CMmSmsTsy::ConstructL: iIsOffline has been initialised to %d", iIsOffline);
+
+ // there's no pending ResumeSmsReception request at startup
+ iResumeSmsReceptionPending = EFalse;
+
+ // Initialization for sms NoFdnCheck
+ iSmsNoFdnCheckFlag = ESmsNoFdnCheckUnknown;
+
+ iExpectAckOrNack = 0;
+
+ }
+
+CMmSmsTsy* CMmSmsTsy::NewL(
+ CMmPhoneTsy* aMmPhone )
+ {
+ CMmSmsTsy* aMmSmsTsy = new ( ELeave ) CMmSmsTsy();
+ CleanupClosePushL(*aMmSmsTsy);
+ aMmSmsTsy->iMmPhone = aMmPhone;
+ aMmSmsTsy->ConstructL();
+ CleanupStack::Pop();
+
+ return aMmSmsTsy;
+ }
+
+CMmSmsTsy::~CMmSmsTsy()
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::~CMmSmsTsy");
+ if ( iMmPhone )
+ {
+ // deregister tsy object from message manager
+ iMmPhone->MessageManager()->DeregisterTsyObject(this);
+
+ // Release the SMS routing from DOS to TSY.
+ // Send request to the Domestic OS layer. Ignore if it leaves
+ TInt trapError = KErrNone;
+ TRAP( trapError, iMmPhone->MessageManager()->HandleRequestL(
+ EMmTsyDeactivateSmsRouting ); );
+ }
+
+ // try to complete send sms message.
+ if ( iTsySatMessaging )
+ {
+ iTsySatMessaging->CompleteSendSmsMessage( KErrAccessDenied );
+ }
+
+ if ( iTsyReqHandleStore )
+ {
+ delete iTsyReqHandleStore;
+ iTsyReqHandleStore = NULL;
+ }
+
+ if ( iSmsMsgArray )
+ {
+ iSmsMsgArray->ResetAndDestroy();
+ delete iSmsMsgArray;
+ iSmsMsgArray = NULL;
+ }
+
+ // Delete extension object
+ if ( iMmSmsExtInterface )
+ {
+ delete iMmSmsExtInterface;
+ iMmSmsExtInterface = NULL;
+ }
+
+ if ( iMmPhone )
+ {
+ iMmPhone->SetSmsSession( NULL );
+ iMmPhone = NULL;
+ }
+
+ if ( iSmsSendReq )
+ {
+ delete iSmsSendReq;
+ iSmsSendReq = NULL;
+ }
+
+ if ( iSMSPClientId )
+ {
+ delete iSMSPClientId;
+ iSMSPClientId = NULL;
+ }
+
+ // set pointers to NULL
+ iMmSmsStorageTsy = NULL;
+ iTsySatMessaging = NULL;
+ iNotifyReceiveModeChangePtr = NULL;
+ iReceiveMessageParamsPtr = NULL;
+ iReceiveMessagePduPtr = NULL;
+ iNotifySmsBearerPtr = NULL;
+ iSendMessageMsgAttrPckgPtr = NULL;
+ iGetMessageStoreInfoPtr = NULL;
+ iStoreSmspBufferPtr = NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmSmsTsy::Init
+// Initialisation method that is called from ETel Server
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::Init()
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// CMmSmsTsy::OpenNewObjectByNameL
+// Creates new object and returns a pointer to it
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CTelObject* CMmSmsTsy::OpenNewObjectByNameL(
+ const TDesC& aName )
+ {
+ if ( aName.Compare( KETelIccSmsStore ) == KErrNone )
+ {
+ iMmSmsStorageTsy = CMmSmsStorageTsy::NewL( this, iMmPhone,
+ iMmSmsExtInterface, iTsyReqHandleStore );
+
+ return iMmSmsStorageTsy;
+ }
+
+ // ME memory (KETelMeSmsStore) and combined memory (KETelCombinedSmsStore)
+ // are not supported
+ User::Leave( KErrNotSupported );
+ //lint -e{527} "unreachable code"
+
+ return NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmSmsTsy::OpenNewObjectL
+// Creates new object and returns a pointer to it
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CTelObject* CMmSmsTsy::OpenNewObjectL(
+ TDes& /*aNewName*/ )
+ {
+ // Not supported
+ User::Leave( KErrNotSupported );
+ //lint -e{527} "unreachable code"
+
+ return NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmSmsTsy::ExtFunc
+// ExtFunc is called by the server when it has a "extended",
+// i.e. non-core ETel request for the TSY. To process a request handle,
+// request type and request data are passed to the TSY
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::ExtFunc(
+ const TTsyReqHandle aTsyReqHandle,
+ const TInt aIpc,
+ const TDataPackage& aPackage )
+ {
+ TAny* dataPtr = aPackage.Ptr1();
+ TInt ret( KErrNone );
+
+ // before processing further the request, check if offline mode status
+ // is enabled and if the given request can be perfomed in that case.
+ if ( ERfsStateInfoInactive == iMmPhone->GetRfStateInfo() &&
+ !IsRequestPossibleInOffline( aIpc ) )
+ {
+TFLOGSTRING2 ("TSY: Offline mode ON, request is not allowed: %d", aIpc );
+ TInt error = CMmCommonStaticUtility::EpocErrorCode( KErrGeneral,
+ KErrGsmOfflineOpNotAllowed );
+
+ // Complete the request with appropiate error
+ ReqCompleted ( aTsyReqHandle, error );
+ }
+ else
+ {
+ switch ( aIpc )
+ {
+ // SMS messaging requests that doesn't need trapping
+ case EMobileSmsMessagingGetCaps:
+ ret = GetCaps( aTsyReqHandle, aPackage.Des1n() );
+ break;
+ case EMobileSmsMessagingGetReceiveMode:
+ ret = GetReceiveMode( aTsyReqHandle, reinterpret_cast<
+ RMobileSmsMessaging::TMobileSmsReceiveMode* >( dataPtr ) );
+ break;
+ case EMobileSmsMessagingGetMoSmsBearer:
+ ret = GetMoSmsBearer( aTsyReqHandle, reinterpret_cast<
+ RMobileSmsMessaging::TMobileSmsBearer* >( dataPtr) );
+ break;
+ case EMobileSmsMessagingSetMoSmsBearer:
+ ret = SetMoSmsBearer( aTsyReqHandle, reinterpret_cast<
+ RMobileSmsMessaging::TMobileSmsBearer*>( dataPtr) );
+ break;
+ case EMobileSmsMessagingEnumerateMessageStores:
+ ret = EnumerateMessageStores( aTsyReqHandle,
+ reinterpret_cast< TInt* >( dataPtr ) );
+ break;
+ case EMobileSmsMessagingGetSmspListPhase2:
+ ret = ReadSmspListPhase2( aTsyReqHandle, reinterpret_cast<
+ RMobilePhone::TClientId*>( dataPtr ), aPackage.Des2n() );
+ break;
+ // SMS messaging requests that need trapping
+ default:
+ // reset last tsy request type
+ iReqHandleType = EMultimodeSmsReqHandleUnknown;
+
+ TInt leaveCode( KErrNone );
+ TRAP( leaveCode, ret = DoExtFuncL( aTsyReqHandle, aIpc,
+ aPackage ); );
+
+ if ( KErrNone != leaveCode )
+ {
+TFLOGSTRING3("CMmSmsTsy: Leave trapped!, IPC=%d, error value:%d", aIpc, leaveCode );
+ ReqCompleted( aTsyReqHandle, leaveCode );
+ }
+
+ //save request handle
+ if ( EMultimodeSmsReqHandleUnknown != iReqHandleType )
+ {
+#ifdef REQHANDLE_TIMER
+ SetTypeOfResponse( iReqHandleType, aTsyReqHandle );
+#else
+ //Never comes here. See SetTypeOfResponse.
+ iTsyReqHandleStore->SetTsyReqHandle( iReqHandleType,
+ aTsyReqHandle );
+#endif // REQHANDLE_TIMER
+ }
+ break;
+ }
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmSmsTsy::DoExtFuncL
+// DoExtFuncL calls messaging methods that can leave
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::DoExtFuncL(
+ const TTsyReqHandle aTsyReqHandle,
+ const TInt aIpc,
+ const TDataPackage& aPackage )
+ {
+ TAny* dataPtr = aPackage.Ptr1();
+ TAny* dataPtr2 = aPackage.Ptr2();
+
+ TInt ret( KErrNone );
+
+ switch ( aIpc )
+ {
+ // SMS messaging requests
+ case EMobileSmsMessagingSetReceiveMode:
+ ret = SetReceiveMode( aTsyReqHandle, reinterpret_cast<
+ RMobileSmsMessaging::TMobileSmsReceiveMode* >( dataPtr ) );
+ break;
+ case EMobileSmsMessagingNotifyReceiveModeChange:
+ ret = NotifyReceiveModeChange( reinterpret_cast<
+ RMobileSmsMessaging::TMobileSmsReceiveMode*>( dataPtr) );
+ break;
+ case EMobileSmsMessagingReceiveMessage:
+ ret = ReceiveMessageL( aTsyReqHandle, aPackage.Des1n(),
+ aPackage.Des2n() );
+ break;
+ case EMobileSmsMessagingAckSmsStored:
+ ret = AckSmsStoredL( aTsyReqHandle, aPackage.Des1n(),
+ reinterpret_cast< TBool* >( dataPtr2 ) );
+ break;
+ case EMobileSmsMessagingNackSmsStored:
+ ret = NackSmsStoredL( aTsyReqHandle, aPackage.Des1n(),
+ reinterpret_cast< TInt* >( dataPtr2 ) );
+ break;
+ case EMobileSmsMessagingResumeSmsReception:
+ ret = ResumeSmsReceptionL( aTsyReqHandle );
+ break;
+ case EMobileSmsMessagingNotifyMoSmsBearerChange:
+ ret = NotifyMoSmsBearerChange( reinterpret_cast<
+ RMobileSmsMessaging::TMobileSmsBearer*> ( dataPtr ) );
+ break;
+ case EMobileSmsMessagingSendMessage:
+ {
+ iSmsNoFdnCheckFlag = ESmsNoFdnCheckNotUsed;
+ ret = SendMessageL( aTsyReqHandle, aPackage.Des1n(),
+ aPackage.Des2n() );
+ }
+ break;
+ case EMobileSmsMessagingSendMessageNoFdnCheck:
+ {
+ iSmsNoFdnCheckFlag = ESmsNoFdnCheckUsed;
+ ret = SendMessageL( aTsyReqHandle, aPackage.Des1n(),
+ aPackage.Des2n() );
+ }
+ break;
+ case EMobileSmsMessagingGetMessageStoreInfo:
+ ret = GetMessageStoreInfoL( aTsyReqHandle,
+ reinterpret_cast< TInt* >( dataPtr ), aPackage.Des2n() );
+ break;
+ case EMobileSmsMessagingGetSmspListPhase1:
+ ret = ReadSmspListPhase1L( aTsyReqHandle,
+ reinterpret_cast< RMobilePhone::TClientId*>( dataPtr ),
+ reinterpret_cast< TInt* >( dataPtr2 ) );
+ break;
+ case EMobileSmsMessagingNotifySmspListChange:
+ ret = NotifySmspListChange();
+ break;
+ case EMobileSmsMessagingStoreSmspList:
+ ret = StoreSmspList( aTsyReqHandle, aPackage.Des1n() );
+ break;
+ default:
+ ret = KErrNotSupported;
+ break;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmSmsTsy::ReqModeL
+// When the ETel server receives an "extension" client request,
+// it will pass the IPC request number down to the TSY in order to find out
+// what type of request it is
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CTelObject::TReqMode CMmSmsTsy::ReqModeL(
+ const TInt aIpc )
+ {
+ CTelObject::TReqMode ret = 0;
+ switch ( aIpc )
+ {
+ // Non-flow Controlled Services
+ case EMobileSmsMessagingGetCaps:
+ case EMobileSmsMessagingGetMoSmsBearer:
+ case EMobileSmsMessagingSetMoSmsBearer:
+ case EMobileSmsMessagingGetReceiveMode:
+ case EMobileSmsMessagingEnumerateMessageStores:
+ case EMobileSmsMessagingGetSmspListPhase2:
+ case EMobileSmsMessagingAckSmsStored:
+ case EMobileSmsMessagingNackSmsStored:
+ case EMobileSmsMessagingSendMessage:
+ case EMobileSmsMessagingSendMessageNoFdnCheck:
+ case EMobileSmsMessagingResumeSmsReception:
+ case EMobileSmsMessagingGetMessageStoreInfo:
+ case EMobileSmsMessagingGetSmspListPhase1:
+ case EMobileSmsMessagingStoreSmspList:
+ case EMobileSmsMessagingSetReceiveMode:
+ break;
+ // Immediate Server Repost - but not multiple completion enabled
+ case EMobileSmsMessagingReceiveMessage:
+ ret = KReqModeRePostImmediately;
+ break;
+ // Multiple Completion Services with Immediate Server Repost
+ case EMobileSmsMessagingNotifyReceiveModeChange:
+ case EMobileSmsMessagingNotifyMoSmsBearerChange:
+ case EMobileSmsMessagingNotifySmspListChange:
+ ret = KReqModeMultipleCompletionEnabled |
+ KReqModeRePostImmediately;
+ break;
+ default:
+ User::Leave( KErrNotSupported );
+ break;
+ }
+
+ return ret;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::NumberOfSlotsL
+// When the ETel server discovers that a request is "repost
+// immediately" it will ask the TSY how big a buffer it wants.
+// NumberOfSlotsL Returns number of slots to be used for given requests
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::NumberOfSlotsL(
+ const TInt aIpc )
+ {
+ TInt numberOfSlots = 1;
+ switch ( aIpc )
+ {
+ case EMobileSmsMessagingReceiveMessage:
+ numberOfSlots = KMmSmsMessagingReceiveMessageSlots;
+ break;
+ // It is safer that normal notification trigger value is three
+ // => Slotlimits are defined according to the requirements of
+ // environment, five for messagereception and three for normal
+ // notifications
+ case EMobileSmsMessagingNotifyReceiveModeChange:
+ numberOfSlots = KMmSmsMessagingNotifyReceiveModeChangeSlots;
+ break;
+ case EMobileSmsMessagingNotifyMoSmsBearerChange:
+ numberOfSlots = KMmSmsMessagingNotifyMoSmsBearerChangeSlots;
+ break;
+ case EMobileSmsMessagingNotifySmspListChange:
+ numberOfSlots = KMmSmsMessagingNotifySmspListChangeSlots;
+ break;
+ default:
+ User::Leave( KErrNotSupported );
+ break;
+ }
+
+ return numberOfSlots;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CancelService
+// CancelService is called by the server when it is
+// "cleaning-up" any still outstanding asynchronous requests before closing
+// a client's sub-session. This will happen if a client closes its R-class
+// handle without cancelling outstanding asynchronous requests on
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::CancelService(
+ const TInt aIpc,
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ TInt ret( KErrNone );
+
+ switch ( aIpc )
+ {
+ case EMobileSmsMessagingSetReceiveMode:
+ ret = SetReceiveModeCancel( aTsyReqHandle );
+ break;
+ case EMobileSmsMessagingNotifyReceiveModeChange:
+ ret = NotifyReceiveModeChangeCancel( aTsyReqHandle );
+ break;
+ case EMobileSmsMessagingSetMoSmsBearer:
+ ret = SetMoSmsBearerCancel( aTsyReqHandle );
+ break;
+ case EMobileSmsMessagingNotifyMoSmsBearerChange:
+ ret = NotifyMoSmsBearerChangeCancel( aTsyReqHandle );
+ break;
+ case EMobileSmsMessagingGetMessageStoreInfo:
+ ret = GetMessageStoreInfoCancel( aTsyReqHandle );
+ break;
+ case EMobileSmsMessagingGetSmspListPhase1:
+ case EMobileSmsMessagingGetSmspListPhase2:
+ ret = ReadAllSmspCancel( aTsyReqHandle );
+ break;
+ case EMobileSmsMessagingNotifySmspListChange:
+ ret = NotifySmspListChangeCancel( aTsyReqHandle );
+ break;
+ case EMobileSmsMessagingSendMessage:
+ case EMobileSmsMessagingAckSmsStored:
+ case EMobileSmsMessagingNackSmsStored:
+ case EMobileSmsMessagingResumeSmsReception:
+ case EMobileSmsMessagingStoreSmspList:
+ break;
+ case EMobileSmsMessagingReceiveMessage:
+ ret = ReceiveMessageCancel( aTsyReqHandle );
+ break;
+ case EMobileSmsMessagingSendMessageNoFdnCheck:
+ ret = SendMessageNoFdnCheckCancel( aTsyReqHandle );
+ break;
+ default:
+ ret = KErrGeneral;
+ break;
+ }
+
+ return ret;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::RegisterNotification
+// Called when the server recognises that this notification
+// is being posted for the first time on this sub-session object.It enables
+// the TSY to "turn on" any regular notification messages that it may
+// receive from DOS
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::RegisterNotification(
+ const TInt aIpc )
+ {
+ TInt ret( KErrNotSupported );
+
+ switch ( aIpc )
+ {
+ case EMobileSmsMessagingReceiveMessage:
+ case EMobileSmsMessagingNotifyReceiveModeChange:
+ case EMobileSmsMessagingNotifyMoSmsBearerChange:
+ case EMobileSmsMessagingNotifySmspListChange:
+ ret = KErrNone;
+ break;
+ default:
+ ret = KErrNotSupported;
+ }
+
+ return ret;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::DeregisterNotification
+// Called when the server recognises that this notification
+// will not be posted again because the last client to have
+// a handle on this sub-session object has just closed the handle.
+// It enables the TSY to "turn off" any regular notification messages that
+// it may receive from the DOS
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::DeregisterNotification(
+ const TInt aIpc )
+ {
+ TInt ret( KErrNotSupported );
+
+ switch ( aIpc )
+ {
+ case EMobileSmsMessagingReceiveMessage:
+ case EMobileSmsMessagingNotifyReceiveModeChange:
+ case EMobileSmsMessagingNotifyMoSmsBearerChange:
+ case EMobileSmsMessagingNotifySmspListChange:
+ ret = KErrNone;
+ break;
+ default:
+ ret = KErrNotSupported;
+ }
+
+ return ret;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::GetCaps
+// This method returns SMS messaging capabilities of the phone
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::GetCaps(
+ const TTsyReqHandle aTsyReqHandle,
+ TDes8* aCaps )
+ {
+ if(sizeof(RMobileSmsMessaging::TMobileSmsCapsV1) > aCaps->Size())
+ {
+ return KErrArgument;
+ }
+
+ RMobileSmsMessaging::TMobileSmsCapsV1Pckg* smsCapsPckg =
+ reinterpret_cast< RMobileSmsMessaging::TMobileSmsCapsV1Pckg* >( aCaps );
+ RMobileSmsMessaging::TMobileSmsCapsV1& smsCaps = ( *smsCapsPckg )();
+
+ // Capabilities depend on the TSY implementation.
+ smsCaps.iSmsMode = KSmsGsmModeCaps;
+ smsCaps.iSmsControl = KSmsControlCaps;
+
+ ReqCompleted( aTsyReqHandle, KErrNone );
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::GetReceiveMode
+// This method retrieves the current setting of the TSY-phone
+// incoming SMS receive mode
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::GetReceiveMode(
+ const TTsyReqHandle aTsyReqHandle,
+ RMobileSmsMessaging::TMobileSmsReceiveMode* aReceiveMode )
+ {
+ *aReceiveMode = iMobileSmsReceiveMode;
+
+ ReqCompleted( aTsyReqHandle, KErrNone );
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::SetReceiveMode
+// This method sets the setting of the TSY-phone incoming SMS receive mode
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::SetReceiveMode(
+ const TTsyReqHandle aTsyReqHandle,
+ RMobileSmsMessaging::TMobileSmsReceiveMode const* aReceiveMode )
+ {
+ if ( RMobileSmsMessaging::EReceiveUnstoredClientAck == *aReceiveMode )
+ {
+ iMobileSmsReceiveMode = *aReceiveMode;
+
+ CompleteNotifyReceiveModeChange();
+
+ ReqCompleted( aTsyReqHandle, KErrNone );
+ }
+ else
+ {
+ // EReceiveModeUnspecified, EReceiveStored, EReceiveUnstoredPhoneAck &
+ // EReceiveAny modes not supported because of CS functionality.
+ ReqCompleted( aTsyReqHandle, KErrNotSupported );
+ }
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::SetReceiveModeCancel
+// This method is used to cancel the outstanding asynchronous
+// SetReceiveMode request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::SetReceiveModeCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::NotifyReceiveModeChange
+// This method is used to notify the client if there is a
+// change to the receive mode setting
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::NotifyReceiveModeChange(
+ RMobileSmsMessaging::TMobileSmsReceiveMode* aReceiveMode )
+ {
+ iReqHandleType = EMultimodeSmsNotifyReceiveModeChange;
+ iNotifyReceiveModeChangePtr = aReceiveMode;
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::NotifyReceiveModeChangeCancel
+// This method cancel notify receive mode change request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::NotifyReceiveModeChangeCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsNotifyReceiveModeChange );
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+ iNotifyReceiveModeChangePtr = NULL;
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteNotifyReceiveModeChange
+// This method completes notify receive mode change request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteNotifyReceiveModeChange()
+ {
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsNotifyReceiveModeChange );
+
+ if ( reqHandle )
+ {
+ if ( iNotifyReceiveModeChangePtr )
+ {
+ *iNotifyReceiveModeChangePtr = iMobileSmsReceiveMode;
+ }
+ ReqCompleted( reqHandle, KErrNone );
+ iNotifyReceiveModeChangePtr = NULL;
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::ReceiveMessageL
+// This method starts the reception of incoming unstored SMS
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::ReceiveMessageL(
+ const TTsyReqHandle aTsyReqHandle,
+ TDes8* aMsgData,
+ TDes8* aMsgAttributes )
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::ReceiveMessageL\n");
+
+ if(sizeof(RMobileSmsMessaging::TMobileSmsReceiveAttributesV1) > aMsgAttributes->Size())
+ {
+ return KErrArgument;
+ }
+
+ iReceiveMessagePduPtr = aMsgData;
+ iReceiveMessageParamsPtr = aMsgAttributes;
+
+ if ( iMmPhone->IsModemStatusReady() )
+ {
+ // activate smsrouting only when modem status is ready
+ ActivateSmsRoutingL();
+ }
+
+ // Store request handle here. DeliverClass2ToSmsStack-method may complete
+ // ReceiveMessage request
+#ifdef REQHANDLE_TIMER
+ SetTypeOfResponse( EMultimodeSmsReceiveMessage, aTsyReqHandle );
+#else
+ iTsyReqHandleStore->SetTsyReqHandle(
+ EMultimodeSmsReceiveMessage, aTsyReqHandle );
+#endif // REQHANDLE_TIMER
+
+ // Check if there is class 2 messages waiting in TSY's internal memory.
+ DeliverClass2ToSmsStack();
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::ReceiveMessageCancel
+// This method cancels an MT message routing to the SMS
+// stack. TSY can not stop routing from SMS server because
+// otherwise SMS server routes incoming messages to SIM server.
+// Negative acknowledgement is sent to the network if message
+// comes when SMS stack routing is not activated
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::ReceiveMessageCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeSmsReceiveMessage );
+
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::ActivateSmsRoutingL
+// Activate SMS routing
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::ActivateSmsRoutingL()
+ {
+ if ( ( ERoutingNotActivated == iServerRoutingActivity ) ||
+ ( ERoutingActivating == iServerRoutingActivity ) )
+ {
+ //Send request to the Domestic OS layer..
+ User::LeaveIfError( iMmPhone->MessageManager()->HandleRequestL(
+ EMmTsyActivateSmsRouting ) );
+ iServerRoutingActivity = ERoutingActivating;
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteActivateSmsRouting
+// This method completes Activation of SMS routing
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteActivateSmsRouting(
+ TInt aError,
+ CMmDataPackage* aDataPackage )
+ {
+ TUint8 aSmsRoutingStatus ( 0 );
+ aDataPackage->UnPackData( aSmsRoutingStatus ) ;
+
+ if ( ( KErrNone == aError ) &&
+ ( KSmsRoutingActivated == aSmsRoutingStatus ) )
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::CompleteActivateSmsRouting SMS routing activated");
+ iServerRoutingActivity = ERoutingActivated;
+ }
+ else if ( ( KErrNone == aError ) &&
+ ( KSmsRoutingDeactivated == aSmsRoutingStatus ) )
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::CompleteActivateSmsRouting SMS routing not activated");
+ iServerRoutingActivity = ERoutingNotActivated;
+ }
+ else
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::CompleteActivateSmsRouting SMS routing activation failed");
+ iServerRoutingActivity = ERoutingNotActivated;
+
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsReceiveMessage );
+
+ if ( reqHandle )
+ {
+ ReqCompleted( reqHandle, aError );
+ }
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteReceiveMessage
+// This method completes reception of incoming unstored SMS
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteReceiveMessage(
+ TInt aError,
+ CMmDataPackage* aDataPackage )
+ {
+ TInt ret( KErrNone );
+ TBool smsInd( EFalse );
+ TSmsMsg* smsMsg;
+
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->GetTsyReqHandle(
+ EMultimodeSmsReceiveMessage );
+
+TFLOGSTRING2("TSY: CMmSmsTsy::CompleteReceiveMessage. iClientStorageFull: %d", iClientStorageFull );
+
+ // SMS successfully received
+ if ( KErrNone == aError )
+ {
+ //unpack received data
+ aDataPackage->UnPackData( smsInd, smsMsg );
+
+ // is the SMS a class2 SMS or not.
+ TBool smsClass2 = smsMsg->iSmsClass2;
+
+ // if store is not full, receive new class2 message and get
+ // notification
+ if ( smsClass2 && ( 0 != smsMsg->iLocation ) && iMmSmsStorageTsy )
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::CompleteReceiveMessage. CompleteNotifyStoreEvent happens");
+ iMmSmsStorageTsy->CMmSmsStorageTsy::CompleteNotifyStoreEvent(
+ smsMsg->iLocation, RMobilePhoneStore::KStoreEntryAdded );
+ }
+
+ // if SMS is a Class2 and SMS Memories are full and SIM SMS Memory
+ // not full
+ if ( iClientStorageFull && smsClass2 )
+ {
+ if ( reqHandle )
+ {
+ // Store SMS in TSY's internal memory
+ TRAP( ret, StoreClass2MessageL( smsMsg ) );
+
+ // Message is not delivered to SMS Stack.Deliver message to
+ // SMS. Stack after SMS Stack has called ReceiveMessage..
+ smsMsg->iDeleteAfterClientAck = EFalse;
+
+#ifdef USING_CTSY_DISPATCHER
+ CMmDataPackage package;
+ TDesC8* msgData = NULL;
+ package.PackData( &msgData );
+
+ // ignore if Acking fails
+ TRAP_IGNORE(
+ ret = iMmPhone->MessageManager()->HandleRequestL(EMobileSmsMessagingAckSmsStored, &package);
+ );
+ iTsyReqHandleStore->ResetTsyReqHandle(EMultimodeSmsReceiveMessage);
+ ReqCompleted(reqHandle, aError);
+#else
+ // ignore if Acking fails
+ TRAP_IGNORE(
+ ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingAckSmsStored );
+ );
+#endif //USING_CTSY_DISPATCHER
+ }
+ else
+ {
+ // Routing is activated, but SMS stack hasn't called
+ // ReceiveMessage. Nack received message internally with cause
+ // value "protocol error", otherwise SMS server releases
+ // routings.
+ CMmDataPackage package;
+ TSmsMsg* nullSms = NULL;
+ TInt rpCause( KErrGsmSMSMemoryCapacityExceeded );
+ package.PackData( &nullSms, &rpCause );
+
+ // ignore if Nacking fails
+ TRAP_IGNORE(
+ ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingNackSmsStored, &package );
+ );
+ }
+ }
+ else
+ {
+ // Class 0 or Class 1 or Class 2 message received.
+ // This message has to be acknowledged to the network
+ TInt rpError( KErrNone );
+
+ if ( reqHandle && !iClientStorageFull )
+ {
+ // Deliver message to SMS stack
+ if(smsMsg->iSmsMsg.Length() > iReceiveMessagePduPtr->MaxLength())
+ {
+ ret = KErrArgument;
+ }
+ else
+ {
+ ret = iMmSmsExtInterface->CompleteReceiveMessage( smsMsg,
+ iReceiveMessageParamsPtr, iReceiveMessagePduPtr );
+ }
+
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsReceiveMessage );
+
+TFLOGSTRING("TSY: CMmSmsTsy::CompleteReceiveMessage. Deliver SMS to the SMS stack");
+ ReqCompleted( reqHandle, ret );
+
+ // increase the count of expected acknowledgements
+ if(ret == KErrNone)
+ {
+ iExpectAckOrNack++;
+ }
+ }
+ else
+ {
+ // Routing is activated, but SMS stack hasn't called
+ // ReceiveMessage. Nack received message internally with cause
+ // value "protocol error", otherwise SMS server releases
+ // routings.
+ if (iClientStorageFull)
+ {
+ // SMS stack's memory is full. Nack message with error
+ // MemoryExceeded
+ rpError = KErrGsmSMSMemoryCapacityExceeded;
+ }
+ else
+ {
+ rpError = KErrGsmSMSUnspecifiedProtocolError;
+ }
+ }
+
+ if ( KErrNone != rpError )
+ {
+ CMmDataPackage package;
+ TSmsMsg* nullSms = NULL;
+ package.PackData( &nullSms, &rpError );
+
+ // ignore if Nacking fails
+ TRAP_IGNORE(
+ ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingNackSmsStored, &package );
+ );
+ }
+ }
+
+ // end of successful SMS reception
+ }
+ // error in SMS reception
+ else
+ {
+ //unpack received data - only one parameter information is needed
+ aDataPackage->UnPackData( smsInd );
+
+ // if SIM SMS Memory is full
+ if ( ( KErrGsmSMSUnspecifiedProtocolError == aError ) &&
+ ( reqHandle ) )
+ {
+ // SMS Memories not full
+ if ( !iClientStorageFull )
+ {
+ CMmDataPackage package;
+ TSmsMsg* nullSms = NULL;
+ TInt rpCause( KErrGsmSMSUnspecifiedProtocolError );
+ package.PackData( &nullSms, &rpCause );
+
+ // ignore if Nacking fails
+ TRAPD( trapError,
+ ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingNackSmsStored, &package ); );
+ if ( KErrNone != trapError )
+ {
+ ret = trapError;
+ }
+TFLOGSTRING("TSY: CMmSmsTsy::CompleteReceiveMessage.KErrGsmSMSUnspecifiedProtocolError ");
+ }
+ else // SMS Memory is full
+ {
+ CMmDataPackage package;
+ TSmsMsg* nullSms = NULL;
+ TInt rpCause( KErrGsmSMSMemoryCapacityExceeded );
+ package.PackData( &nullSms, &rpCause );
+
+ // ignore if Nacking fails
+ TRAPD( trapError,
+ ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingNackSmsStored, &package ); );
+ if ( KErrNone != trapError )
+ {
+ ret = trapError;
+ }
+ }
+ }
+ else if ( ( KErrGsmSMSMemoryCapacityExceeded == aError ) &&
+ ( reqHandle ) )
+ {
+ CMmDataPackage package;
+ TSmsMsg* nullSms = NULL;
+ TInt rpCause( KErrGsmSMSMemoryCapacityExceeded );
+ package.PackData( &nullSms, &rpCause );
+
+ // ignore if Nacking fails
+ TRAPD( trapError,
+ ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingNackSmsStored, &package );
+ );
+ if ( KErrNone != trapError )
+ {
+ ret = trapError;
+ }
+TFLOGSTRING("TSY: CMmSmsTsy::CompleteReceiveMessage.KErrGsmSMSMemoryCapacityExceeded ");
+ }
+ else if ( !reqHandle )
+ {
+ // Routing is activated, but SMS stack hasn't called
+ // ReceiveMessage. Nack received message internally with cause
+ // value "protocol error", otherwise SMS server releases
+ // routings
+ CMmDataPackage package;
+ TSmsMsg* nullSms = NULL;
+ TInt rpCause;
+ if (iClientStorageFull)
+ {
+ rpCause = KErrGsmSMSMemoryCapacityExceeded;
+ }
+ else
+ {
+ rpCause = KErrGsmSMSUnspecifiedProtocolError;
+ }
+ package.PackData( &nullSms, &rpCause );
+
+ // ignore if Nacking fails
+ TRAPD( trapError,
+ ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingNackSmsStored, &package );
+ );
+ if ( KErrNone != trapError )
+ {
+ ret = trapError;
+ }
+ }
+ else if ( !smsInd )
+ {
+ // Error occurred while handling incoming message or acknowledging
+ // received message
+ // Request handle exists (already checked above)
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsReceiveMessage );
+
+ ReqCompleted( reqHandle, aError );
+
+ // Incoming message handling failed. If client or TSY doesn't .
+ // ack incoming message, SMS Server may release all routings.
+ // Set iSmsServerRoutingActivity to FALSE so client can activate
+ // routings again.
+ iServerRoutingActivity = ERoutingNotActivated;
+ }
+
+ if ( KErrNone != ret )
+ {
+ // Nack of received message failed. SMS Server releases all
+ // routings. Set iSmsServerRoutingActivity to FALSE so client
+ // can activate routings again
+ iServerRoutingActivity = ERoutingNotActivated;
+ }
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::StoreClass2MessageL
+// This method stores received Class 2 message in TSY's internal memory
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::StoreClass2MessageL(
+ TSmsMsg const* aSmsMsg )
+ {
+ TSmsMsg* smsMsg = new ( ELeave ) TSmsMsg();
+ CleanupStack::PushL( smsMsg );
+
+ smsMsg->iDeleteAfterClientAck = aSmsMsg->iDeleteAfterClientAck;
+ smsMsg->iLocation = aSmsMsg->iLocation;
+ smsMsg->iMessageStatus = aSmsMsg->iMessageStatus;
+ smsMsg->iMobileScNPI = aSmsMsg->iMobileScNPI;
+ smsMsg->iMobileScTON = aSmsMsg->iMobileScTON;
+ smsMsg->iServiceCentre.Copy( aSmsMsg->iServiceCentre );
+ smsMsg->iSmsMsg.Copy( aSmsMsg->iSmsMsg );
+
+ iSmsMsgArray->AppendL( smsMsg );
+
+ CleanupStack::Pop( smsMsg );
+ // note: Lint doesn't understand the use of Pop and 'thinks'
+ // that there is a memory leak for smsMsg, we disable that warning with
+ // the following command
+ // lint -e429
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::DeliverClass2ToSmsStack
+// This method delivers a received Class 2 messages that are
+// stored in TSY's internal memory to the SMS stack
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::DeliverClass2ToSmsStack()
+ {
+ // Check if there is Class 2 messages in TSY's internal memory that can be
+ // now delivered to the SMS stack
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->GetTsyReqHandle(
+ EMultimodeSmsReceiveMessage );
+
+ if ( reqHandle && !iClientStorageFull )
+ {
+ for ( TInt i = 0; i < iSmsMsgArray->Count(); i++ )
+ {
+ if ( EFalse == iSmsMsgArray->At( i )->iDeleteAfterClientAck )
+ {
+TFLOGSTRING2("TSY: CMmSmsTsy::DeliverClass2ToSmsStack. Deliver SMS to the SMS stack. Array count: %d", iSmsMsgArray->Count());
+ // TSY can now delete the message if SMS stack ack message
+ // successfully
+ iSmsMsgArray->At( i )->iDeleteAfterClientAck = ETrue;
+
+ TInt ret = iMmSmsExtInterface->CompleteReceiveMessage(
+ iSmsMsgArray->At( i ), iReceiveMessageParamsPtr,
+ iReceiveMessagePduPtr );
+
+ // ReceiveMessage request completed Reset request handle
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsReceiveMessage );
+
+ // increase the count of expected acknowledgements
+ if(ret == KErrNone)
+ {
+ iExpectAckOrNack++;
+ }
+
+ ReqCompleted( reqHandle, ret );
+ break;
+ }
+ }
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::AckSmsStoredL
+// Route RP-Ack request to active messagehandler
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::AckSmsStoredL(
+ const TTsyReqHandle aTsyReqHandle,
+ const TDesC8* aMsgData,
+ TBool const * aMemoryFull )
+ {
+TFLOGSTRING2("TSY: CMmSmsTsy::AckSmsStored. aMemoryFull: %d",*aMemoryFull);
+ TTsyReqHandle getAckStoredMessageHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeSmsAckStored );
+
+ if ( EMultimodeSmsReqHandleUnknown < getAckStoredMessageHandle )
+ {
+ // Send request is already ongoing
+ ReqCompleted( aTsyReqHandle, KErrServerBusy );
+ }
+ else
+ if ( iExpectAckOrNack <= 0 )
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::AckSmsStoredL. -> ReceiveMessage not requested - error returned ");
+ ReqCompleted( aTsyReqHandle, KErrNotReady );
+ return KErrNone;
+ }
+ else
+ {
+ iClientStorageFull = *aMemoryFull;
+ TBool ackMessage( ETrue );
+
+ // Check if TSY has stored received Class 2 message to it's internal
+ // memory. TSY can now delete message from it's internal memory
+ // because SMS stack received message successfully.
+ for ( TInt i = 0; i < iSmsMsgArray->Count(); i++ )
+ {
+ if ( EFalse != iSmsMsgArray->At( i )->iDeleteAfterClientAck &&
+ KErrNone == aMsgData->CompareF(
+ iSmsMsgArray->At( i )->iSmsMsg ) )
+ {
+TFLOGSTRING3("TSY: CMmSmsTsy::AckSmsStored. Delete SMS: %d, Array count: %d",i,iSmsMsgArray->Count());
+ delete iSmsMsgArray->At( i ); // Delete object from memory
+ iSmsMsgArray->Delete( i ); // Delete pointer from array
+ iSmsMsgArray->Compress();
+
+ // Class 2 message is already acknowledged to the network
+ // Complete request here and don't send ack to the .
+ // network.
+ ReqCompleted( aTsyReqHandle, KErrNone );
+ ackMessage = EFalse;
+
+ // Check if there is more class 2 messages waiting in TSY's
+ // internal memory
+ DeliverClass2ToSmsStack();
+ break;
+ }
+ }
+
+ if ( ackMessage )
+ {
+ // Pack data
+ CMmDataPackage package;
+ TDesC8* msgData = const_cast<TDesC8*>( aMsgData );
+ package.PackData( &msgData );
+
+ TInt ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingAckSmsStored, &package );
+
+ if ( KErrNone == ret )
+ {
+ iReqHandleType = EMultimodeSmsAckStored;
+ }
+ else
+ {
+ // Message construction failed or phonet returned error
+ ReqCompleted( aTsyReqHandle, ret );
+
+ // Acknowledging failed. SMS Server will now release routings.
+ // Complete receive message request with KErrGeneral and
+ // set routing activity to false. SMS Stack makes new
+ // ReceiveMessage request.
+ TBool smsInd( EFalse );
+ CMmDataPackage data;
+ TSmsMsg* nullSms = NULL;
+ data.PackData( &smsInd, &nullSms );
+ CompleteReceiveMessage( KErrGeneral, &data );
+ }
+ }
+ }
+
+ // decrease the count of expeced acknowledgements
+ iExpectAckOrNack--;
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteAckSmsStored
+// Complete clients AckSmsStored request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteAckSmsStored(
+ TInt aError )
+ {
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsAckStored );
+ if ( reqHandle )
+ {
+ ReqCompleted( reqHandle, aError );
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::NackSmsStored
+// Route RP-Error request to messagehandler
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::NackSmsStoredL(
+ const TTsyReqHandle aTsyReqHandle,
+ const TDesC8* aMsgData,
+ TInt* aRpCause )
+ {
+TFLOGSTRING2("TSY: CMmSmsTsy::NackSmsStored. aRpCause: %d",*aRpCause);
+ TTsyReqHandle nackHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeSmsNackStored );
+
+ if ( 0 < nackHandle )
+ {
+ // The request is already in processing because of previous request
+ // Complete request with status value informing the client about
+ // the situation.
+ ReqCompleted( aTsyReqHandle, KErrServerBusy );
+ }
+ else
+ if ( iExpectAckOrNack <= 0 )
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::AckSmsStoredL. -> ReceiveMessage not requested - error returned ");
+ ReqCompleted( aTsyReqHandle, KErrNotReady );
+ return KErrNone;
+ }
+ else
+ {
+ TBool nackMessage( ETrue );
+
+ // Check if TSY has stored received Class 2 message to it's internal
+ // memory. TSY can now delete message from it's internal memory
+ // because SMS stack received message successfully
+ for ( TInt i = 0; i < iSmsMsgArray->Count(); i++ )
+ {
+ // Check if message is waiting SMS stack's acknowledging and
+ // message contents is same as aMsgData.
+ if ( EFalse != iSmsMsgArray->At( i )->iDeleteAfterClientAck &&
+ KErrNone == aMsgData->CompareF(
+ iSmsMsgArray->At( i )->iSmsMsg ) )
+ {
+ switch ( *aRpCause )
+ {
+ // ETel specific value
+ case KErrGsmSMSMemoryCapacityExceeded:
+ // Defect in SMS stack. Stack sets TP cause value to the
+ // RP cause value TP-FCS 0xD3, RP cause 0x16
+ // 0xD3:Memory Capacity Exceeded
+ iClientStorageFull = ETrue;
+ // without break statement, it will run "iSmsMsgArray->At( i )->iDeleteAfterClientAck = EFalse" in next case block.
+ case 0xD3:
+ // Deliver this message to SMS stack when SMS stack
+ // has enough memory.
+ iSmsMsgArray->At( i )->iDeleteAfterClientAck = EFalse;
+ break;
+ default:
+ // Delete message because SMS stack couldn't handle it.
+ // Delete object from memory
+ delete iSmsMsgArray->At( i );
+ // Delete pointer from array
+ iSmsMsgArray->Delete( i );
+ iSmsMsgArray->Compress();
+ break;
+ }
+
+ // Class 2 message is already acknowledged to the network by
+ // adaptation. Complete request here and don't send ack to the
+ // network.
+ ReqCompleted( aTsyReqHandle, KErrNone );
+ nackMessage = EFalse;
+ break;
+ }
+ }
+
+ if ( nackMessage )
+ {
+ CMmDataPackage package;
+ // packed parameter: pointer to TDesC8 (TPDU data)
+ // and TInt (RP cause)
+ TDesC8* tempMsgDataPtr = const_cast<TDesC8*>( aMsgData );
+ package.PackData( &tempMsgDataPtr, aRpCause );
+
+ TInt ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingNackSmsStored, &package );
+
+ if ( KErrNone == ret )
+ {
+ iReqHandleType = EMultimodeSmsNackStored;
+ }
+ else
+ {
+ // Message construction failed or phonet sender returned
+ // error
+ ReqCompleted( aTsyReqHandle, ret );
+
+ // Acknowledging failed. SMS Server will now release routings.
+ // Complete receive message request with KErrGeneral and
+ // set routing activity to false. SMS Stack makes new
+ // ReceiveMessage request.
+ TBool smsInd( EFalse );
+ CMmDataPackage data;
+ TSmsMsg* nullSms = NULL;
+ data.PackData( &smsInd, &nullSms );
+ CompleteReceiveMessage( KErrGeneral, &data );
+ }
+ }
+ }
+
+
+ // decrease the count of expeced acknowledgements
+ iExpectAckOrNack--;
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteNackSmsStored
+// Complete clients NackSmsStored request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteNackSmsStored(
+ TInt aError )
+ {
+ // reset req handle. Returns the deleted req handle
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsNackStored );
+ if ( reqHandle )
+ {
+ ReqCompleted( reqHandle, aError );
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::ResumeSmsReception
+// Notify SMS Server, that client have again free memory for incoming SMSes
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::ResumeSmsReceptionL(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::ResumeSmsReceptionL");
+ TTsyReqHandle resumeHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeSmsResumeReception );
+
+ if ( 0 < resumeHandle )
+ {
+ // The request is already in processing because of previous request
+ // Complete request with status value informing the client about
+ // the situation
+ ReqCompleted( aTsyReqHandle, KErrServerBusy );
+ }
+ else if ( iIsOffline )
+ {
+ // CS hardware is in off-line mode. We cannot issue this request
+ // now, but we will do it as soon as we are on-line again. See
+ // method SetOffline.
+ iResumeSmsReceptionPending = ETrue;
+
+ // Complete with KErrNone. Client will never notice that the
+ // request was not yet sent to DOS.
+ ReqCompleted( aTsyReqHandle, KErrNone );
+ }
+ else
+ {
+ TInt ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingResumeSmsReception );
+
+ if ( KErrNone == ret )
+ {
+ iReqHandleType = EMultimodeSmsResumeReception;
+ }
+ else
+ {
+ // Message construction failed or phonet sender returned error
+ ReqCompleted( aTsyReqHandle, ret );
+ }
+ }
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteResumeSmsReception
+// This method completes clients ResumeSmsReception request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteResumeSmsReception(
+ TInt aError )
+ {
+ if ( KErrNone == aError )
+ {
+ iClientStorageFull = EFalse;
+ }
+
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsResumeReception );
+ if ( reqHandle )
+ {
+ ReqCompleted( reqHandle, aError );
+ }
+
+ // Suspended SMS reception resumed. Check if there is class 2 messages
+ // waiting in TSY's internal memory.
+ DeliverClass2ToSmsStack();
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::SetOffline
+// Sets information about CS hardware mode (off-line/on-line)
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::SetOffline(
+ TBool aIsOffline )
+ {
+TFLOGSTRING2("TSY: CMmSmsTsy::SetOffline has been called with %d", aIsOffline);
+
+ if ( !aIsOffline && iIsOffline )
+ {
+ // changing from off-line to on-line
+ if ( iResumeSmsReceptionPending )
+ {
+ // now send the pending ResumeSmsReception
+ // request to DOS. We are not interested if the
+ // request has failed, and it has already been completed
+ // to the client (with KErrNone). See method ResumeSmsReception.
+ TInt trapError = KErrNone;
+ TRAP( trapError, iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingResumeSmsReception );
+ );
+ iResumeSmsReceptionPending = EFalse;
+ }
+ }
+ iIsOffline = aIsOffline;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::GetMoSmsBearer
+// This method is used to retrieve the current setting for the
+// bearer type used for sending SMS messages
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::GetMoSmsBearer(
+ const TTsyReqHandle /*aTsyReqHandle*/,
+ RMobileSmsMessaging::TMobileSmsBearer* /*aBearer*/ )
+ {
+ return KErrNotSupported;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::SetMoSmsBearer
+// This method sets the bearer type for sending SMS messages
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::SetMoSmsBearer(
+ const TTsyReqHandle aTsyReqHandle,
+ RMobileSmsMessaging::TMobileSmsBearer* aBearer )
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::SetMoSmsBearer called");
+
+ TTsyReqHandle setMoSmsBearerHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeSmsSetMoSmsBearer );
+
+ if ( 0 < setMoSmsBearerHandle )
+ {
+ // The request is already processing because of previous request.
+ // Complete request with status value informing the client about
+ // the situation.
+ ReqCompleted( aTsyReqHandle, KErrServerBusy );
+ }
+ else
+ {
+ if ( ( *aBearer == RMobileSmsMessaging::ESmsBearerPacketOnly ) ||
+ ( *aBearer == RMobileSmsMessaging::ESmsBearerCircuitOnly ) ||
+ ( *aBearer == RMobileSmsMessaging::ESmsBearerPacketPreferred ) ||
+ ( *aBearer == RMobileSmsMessaging::ESmsBearerCircuitPreferred ) )
+ {
+ TInt ret = KErrNone;
+
+ CMmDataPackage package;
+ package.PackData( aBearer );
+
+ // Send request to the DOS layer.
+ TRAP_IGNORE( ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingSetMoSmsBearer, &package ); );
+
+ if ( KErrNone == ret )
+ {
+#ifdef REQHANDLE_TIMER
+ SetTypeOfResponse( EMultimodeSmsSetMoSmsBearer, aTsyReqHandle );
+#else
+ iTsyReqHandleStore->SetTsyReqHandle(
+ EMultimodeSmsSetMoSmsBearer, aTsyReqHandle );
+#endif // REQHANDLE_TIMER
+ }
+ else
+ {
+ // Call to DOS failed
+ ReqCompleted( aTsyReqHandle, ret );
+ }
+ }
+ else
+ {
+ ReqCompleted( aTsyReqHandle, KErrNotSupported );
+ }
+ }
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteSetMoSmsBearer
+// Complete clients SetMoSmsBearer request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteSetMoSmsBearer(
+ TInt aResult )
+ {
+ // reset req handle. Returns the deleted req handle
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsSetMoSmsBearer );
+
+ if ( reqHandle )
+ {
+ ReqCompleted( reqHandle, aResult );
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::SetMoSmsBearerCancel
+// This method is used to cancel an outstanding asynchronous
+// SetMoSmsBearer request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::SetMoSmsBearerCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeSmsSetMoSmsBearer );
+
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::NotifyMoSmsBearerChange
+// This method is used to notify the client if there is a
+// change to the setting for the bearer type used for sending SMS messages
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::NotifyMoSmsBearerChange(
+ RMobileSmsMessaging::TMobileSmsBearer* /*aBearer*/ )
+ {
+ return KErrNotSupported;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::NotifyMoSmsBearerChangeCancel
+// This method is used to cancel an outstanding asynchronous
+// NotifyMoSmsBearerChange request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::NotifyMoSmsBearerChangeCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsNotifyMoSmsBearerChange );
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+ iNotifySmsBearerPtr = NULL;
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::SendMessageL
+// Routes send message to network request to message handler
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::SendMessageL(
+ const TTsyReqHandle aTsyReqHandle,
+ TDes8* aMsgData,
+ TDes8* aMsgAttributes )
+ {
+ TInt ret( KErrNone );
+
+ TTsyReqHandle getSendMessageHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeSmsSendMessage );
+ TTsyReqHandle getSendSatMessageHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeSmsSendSatMessage );
+
+ TTsyReqHandle getSendMessageNoFdnHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeSmsSendMessageNoFdnCheck );
+ if ( ( EMultimodeSmsReqHandleUnknown < getSendMessageHandle )
+ || ( EMultimodeSmsReqHandleUnknown < getSendSatMessageHandle )
+ || ( EMultimodeSmsReqHandleUnknown < getSendMessageNoFdnHandle ) )
+ {
+ // Send request is already ongoing
+ // (through ETel messaging or through SAT)
+ ReqCompleted( aTsyReqHandle, KErrServerBusy );
+ }
+ else if(sizeof(RMobileSmsMessaging::TMobileSmsReceiveAttributesV1) > aMsgAttributes->Size())
+ {
+ ReqCompleted( aTsyReqHandle, KErrArgument );
+ }
+ else
+ {
+ iSendMessageMsgAttrPckgPtr = aMsgAttributes;
+
+ // Create package
+ CMmDataPackage package;
+
+ // typecast for aMsgAttributes
+ RMobileSmsMessaging::TMobileSmsSendAttributesV1Pckg* attsPckg =
+ reinterpret_cast<
+ RMobileSmsMessaging::TMobileSmsSendAttributesV1Pckg* >(
+ aMsgAttributes );
+ RMobileSmsMessaging::TMobileSmsSendAttributesV1& msgAttr =
+ ( *attsPckg )();
+
+ // structure for all sms parameters and data
+ TSendSmsDataAndAttributes sendData;
+
+ sendData.iAttributes = &msgAttr;
+ sendData.iMsgData = aMsgData;
+
+ if ( iSmsNoFdnCheckFlag == ESmsNoFdnCheckUsed )
+ {
+ //set ipc
+ sendData.iIpc = EMobileSmsMessagingSendMessageNoFdnCheck;
+ }
+ if ( iSmsNoFdnCheckFlag == ESmsNoFdnCheckNotUsed )
+ {
+ //set ipc
+ sendData.iIpc = EMobileSmsMessagingSendMessage;
+ }
+
+ // Pack parameters
+ package.PackData( &sendData );
+
+ CSmsSendRequest* smsSendReq = new (ELeave) CSmsSendRequest();
+ smsSendReq->SetSmsDataAndAttributes( sendData );
+
+ // save send request
+ iSmsSendReq = smsSendReq;
+TFLOGSTRING("TSY: CMmSmsTsy::SendMessageL: Send request saved");
+
+ // send request to DOS
+ // packed parameter: TSendSmsDataAndAttributes
+ if ( iSmsNoFdnCheckFlag == ESmsNoFdnCheckUsed )
+ {
+ ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingSendMessageNoFdnCheck, &package );
+ }
+ if ( iSmsNoFdnCheckFlag == ESmsNoFdnCheckNotUsed )
+ {
+ ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingSendMessage, &package );
+ }
+
+ if ( KErrNone == ret )
+ {
+ if ( iSmsNoFdnCheckFlag == ESmsNoFdnCheckUsed )
+ {
+ //set request type
+ iReqHandleType = EMultimodeSmsSendMessageNoFdnCheck;
+ }
+ if ( iSmsNoFdnCheckFlag == ESmsNoFdnCheckNotUsed )
+ {
+ //set request type
+ iReqHandleType = EMultimodeSmsSendMessage;
+ }
+ smsSendReq->IncreaseSendCounter();
+ }
+ else
+ {
+ // Phonet returned error
+ delete smsSendReq; // Delete object
+ iSmsSendReq = NULL; // Reset pointer
+ // Message construction failed or phonet sender returned error
+ ReqCompleted( aTsyReqHandle, ret );
+ // reset pointer to client memory
+ iSendMessageMsgAttrPckgPtr = NULL;
+
+ iSmsNoFdnCheckFlag = ESmsNoFdnCheckUnknown;
+ }
+ }
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteSendMessage
+// Complete SendMessage request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteSendMessage(
+ TInt aError,
+ CMmDataPackage* aDataPackage )
+ {
+ if ( ( KErrNone != aError ) && ( KErrTimedOut != aError )
+ && ( KErrGsmSMSOperationNotAllowed !=
+ CMmCommonStaticUtility::ExtendedErrorCode ( aError ) )
+ // FDB check failed
+ && ( KErrGsmSMSUnspecifiedProtocolError !=
+ CMmCommonStaticUtility::ExtendedErrorCode ( aError ) )
+ && ( KErrSatControl !=
+ CMmCommonStaticUtility::ExtendedErrorCode ( aError ) )
+ && ( !( iMmPhone->GetSatMessaging() &&
+ iMmPhone->GetSatMessaging()->IsMoSmControlBySimActivated() ) )
+ && ( NULL != iSmsSendReq ) && ( 2 >=
+ iSmsSendReq->GetSendCounter() ) )
+ {
+ // DOS returned error to send request. Message might be tried to be
+ // resent (see method ResendSms).
+ // Timeout mechanism cannot access this part of code, ever.
+TFLOGSTRING2("TSY: CMmSmsTsy::CompleteSendMessage. Resend counter: %d", iSmsSendReq->GetSendCounter());
+ }
+ else
+ {
+ // This is executed
+ // - if sending was successful
+ // - if there are no more resending attempts
+ // - if timer expires (called from the Complete of CMmSmsTsy class)
+
+ // Delete send message entry from send array
+ if ( iSmsSendReq )
+ {
+ delete iSmsSendReq; // Delete object
+ iSmsSendReq = NULL; // Reset pointer
+ }
+
+ // reset req handle and complete request
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsSendMessage );
+
+ if ( EMultimodeSmsReqHandleUnknown < reqHandle )
+ {
+ // get values only if there was no error, and if return pointer to
+ // client is available
+ if ( KErrNone == aError && iSendMessageMsgAttrPckgPtr )
+ {
+ TInt16 msgRef( 0 );
+ TBuf8<RMobileSmsMessaging::KGsmTpduSize> smsMsg;
+
+ aDataPackage->UnPackData( msgRef, smsMsg );
+
+ RMobileSmsMessaging::TMobileSmsSendAttributesV1Pckg* attsPckg =
+ reinterpret_cast<
+ RMobileSmsMessaging::TMobileSmsSendAttributesV1Pckg* >(
+ iSendMessageMsgAttrPckgPtr );
+ RMobileSmsMessaging::TMobileSmsSendAttributesV1& msgAttr =
+ ( *attsPckg )();
+
+ msgAttr.iFlags = RMobileSmsMessaging::KMessageReference;
+ msgAttr.iMsgRef = static_cast< TUint16 >( msgRef );
+
+ if ( NULL != smsMsg.Length() )
+ {
+ msgAttr.iSubmitReport.Copy(smsMsg);
+ msgAttr.iFlags |= RMobileSmsMessaging::KGsmSubmitReport;
+ }
+ }
+
+ ReqCompleted( reqHandle, aError );
+ // reset pointer to client memory
+ iSendMessageMsgAttrPckgPtr = NULL;
+ iSmsNoFdnCheckFlag = ESmsNoFdnCheckUnknown;
+ }
+ }
+
+ // Resend unsent message
+ ResendSms();
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::SendSatMessage
+// SimAtkTsy can send SMS messages to the network by calling this method
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::SendSatMessage(
+ MStkTsySatService& aStkTsySatService,
+ TDes8* aSmsTpdu,
+ TDes16* aScAddress,
+ RMobilePhone::TMobileTON* aMobileTON,
+ RMobilePhone::TMobileNPI* aMobileNPI,
+ TBool aMoreToSend,
+ TTsyReqHandle aTsyReqHandle )
+ {
+ iTsySatMessaging = &aStkTsySatService;
+
+ TTsyReqHandle getSendMessageHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeSmsSendMessage );
+ TTsyReqHandle getSendSatMessageHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeSmsSendSatMessage );
+
+ if ( ( EMultimodeSmsReqHandleUnknown < getSendMessageHandle )
+ || ( EMultimodeSmsReqHandleUnknown < getSendSatMessageHandle ) )
+ {
+ // Send request is already ongoing
+ // (through ETel messaging or through SAT)
+ iTsySatMessaging->CompleteSendSmsMessage( KErrServerBusy );
+ }
+ else
+ {
+
+ TRAPD( leaveCode, DoSendSatMessageL( aSmsTpdu, aScAddress, aMobileTON,
+ aMobileNPI, aMoreToSend, aTsyReqHandle ); );
+
+ if ( KErrNone != leaveCode )
+ {
+ // Call to DOS failed
+ CompleteSendSatMessage( leaveCode );
+ }
+ }
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::DoSendSatMessageL
+// SimAtkTsy can send SMS messages to the network by calling this method.
+// This method TRAPs failures.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::DoSendSatMessageL(
+ TDes8* aSmsTpdu,
+ TDes16* aScAddress,
+ RMobilePhone::TMobileTON* aMobileTON,
+ RMobilePhone::TMobileNPI* aMobileNPI,
+ TBool aMoreToSend,
+ TTsyReqHandle aTsyReqHandle )
+ {
+ // Leave if SendSatMessageL returns an error
+ User::LeaveIfError( SendSatMessageL( iMmPhone, aSmsTpdu,
+ aScAddress, aMobileTON, aMobileNPI, aMoreToSend ) );
+
+#ifdef REQHANDLE_TIMER
+ SetTypeOfResponse( EMultimodeSmsSendSatMessage, aTsyReqHandle );
+#endif // REQHANDLE_TIMER
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteSendSatMessage
+// Compelete SendSatMessage request to the MMSAT
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteSendSatMessage(
+ TInt aError )
+ {
+TFLOGSTRING2("TSY: CMmSmsTsy::CompleteSendSatMessage. Complete SAT SMS send Error: %d", aError);
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeSmsSendSatMessage );
+
+ if ( iTsySatMessaging )
+ {
+ iTsySatMessaging->CompleteSendSmsMessage( aError );
+ }
+
+#ifdef USING_CTSY_DISPATCHER
+
+ //the iTsySatMessaging is now Nulled on the complete
+ //open issue that if the iTsySatMessaging pointer (to the SIM ATK) is not nulled (i.e. the callback is
+ //not completed) and the CTSY is destructed after the SIM ATK then the CMmSmsTsy has a invalid pointer which
+ //is used in the CMmSmsTsy destructor
+
+ iTsySatMessaging = NULL;
+#endif //USING_CTSY_DISPATCHER
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::EnumerateMessageStores
+// This methods returns the number of phone-side SMS message
+// stores supported by the phone
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::EnumerateMessageStores(
+ const TTsyReqHandle aTsyReqHandle,
+ TInt* aCount )
+ {
+ *aCount = KSmsStoreNumber;
+ ReqCompleted( aTsyReqHandle, KErrNone );
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::GetMessageStoreInfo
+// This method gets used SMS entries and total number of SMS entries on SIM
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::GetMessageStoreInfoL(
+ const TTsyReqHandle aTsyReqHandle,
+ TInt const* aIndex,
+ TDes8* aInfo )
+ {
+ TTsyReqHandle getStoreInfoHandle =
+ iTsyReqHandleStore->GetTsyReqHandle(
+ EMultimodeSmsGetMessageStoreInfo );
+
+ if ( EMultimodeSmsReqHandleUnknown < getStoreInfoHandle )
+ {
+ // The request is already in processing because of previous request.
+ // Complete request with status value informing the client about
+ // the situation.
+ ReqCompleted( aTsyReqHandle, KErrServerBusy );
+ }
+ else if ( (*aIndex >= KSmsStoreNumber) || (*aIndex < 0) )
+ {
+ // First store number is "0" and SIM is only supported store
+ ReqCompleted( aTsyReqHandle, KErrArgument );
+ }
+ else
+ {
+ iGetMessageStoreInfoPtr = aInfo;
+ // allow for EMobileSmsMessagingGetMessageStoreInfo immediate
+ // completion
+#ifdef REQHANDLE_TIMER
+ SetTypeOfResponse( EMultimodeSmsGetMessageStoreInfo, aTsyReqHandle );
+#else
+ // Never comes here. See SetTypeOfResponse.
+ iTsyReqHandleStore->SetTsyReqHandle( EMultimodeSmsGetMessageStoreInfo,
+ aTsyReqHandle );
+#endif // REQHANDLE_TIMER
+
+ //Send request to the Domestic OS layer.
+ TInt ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingGetMessageStoreInfo );
+
+ // DOS layer returned with error without completing request
+ if ( KErrNone != ret && iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsGetMessageStoreInfo) )
+ {
+ ReqCompleted( aTsyReqHandle, ret );
+ }
+ }
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::GetMessageStoreInfoCancel
+// Cancel pending GetMessagestoreInfo request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::GetMessageStoreInfoCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeSmsGetMessageStoreInfo );
+
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteGetMessageStoreInfo
+// Complete GetMessageStoreInfo request to client
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteGetMessageStoreInfo(
+ TInt aError,
+ CMmDataPackage* aDataPackage )
+ {
+ TUint8 totalEntries( 0 );
+ TInt usedEntries( 0 );
+
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsGetMessageStoreInfo );
+
+ if ( reqHandle )
+ {
+ // Request was successful
+ if ( ( KErrNone == aError ) || ( KErrNotFound == aError ) )
+ {
+ aDataPackage->UnPackData( totalEntries, usedEntries );
+
+ aError = iMmSmsExtInterface->MessageStoreInfo(
+ iGetMessageStoreInfoPtr, totalEntries, usedEntries );
+ }
+
+ iSmsNumOfLoc = totalEntries;
+
+ ReqCompleted( reqHandle, aError );
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::ReadSmspListPhase1L
+// This method starts first phase of SMS Parameter sets
+// retrieval On the first phase method store locations
+// temporarely to the TSY. On the second phase method copies the
+// list to the client
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::ReadSmspListPhase1L(
+ const TTsyReqHandle aTsyReqHandle,
+ RMobilePhone::TClientId const* aId,
+ TInt* aBufSize )
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::ReadSmspListPhase1L");
+
+ TTsyReqHandle readSmspHandle = iTsyReqHandleStore->GetTsyReqHandle(
+ EMultimodeSmsReadSmspListPhase1 );
+
+ if ( 0 < readSmspHandle )
+ {
+ // The request is already processing because of previous request
+ // Complete request with status value informing the client about
+ // the situation.
+ ReqCompleted( aTsyReqHandle, KErrServerBusy );
+ }
+ else
+ {
+ // Lets check how many SMSP sets are there.
+ TInt ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingGetSmspListPhase1 );
+
+ if ( KErrNone == ret )
+ {
+ iReqHandleType = EMultimodeSmsReadSmspListPhase1;
+
+ iRetSMSPSize = aBufSize;
+
+ // Copy client id (session and subsession handle). it's used for
+ // matching phase 1 and 2 of a request
+
+ if ( iSMSPClientId )
+ {
+ delete iSMSPClientId;
+ iSMSPClientId = NULL;
+ }
+
+ iSMSPClientId = new ( ELeave ) RMobilePhone::TClientId( *aId );
+ }
+ else
+ {
+ // Call to DOS failed
+ ReqCompleted( aTsyReqHandle, ret );
+ }
+ }
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::ReadSmspListPhase2
+// This method starts second phase of SMS Parameter sets retrieval. It is
+// guaranteed that this is only called if phase 1 was completed with KErrNone.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::ReadSmspListPhase2(
+ TTsyReqHandle aTsyReqHandle,
+ RMobilePhone::TClientId const* aId,
+ TDes8* aBuffer )
+ {
+ // Check if client id matches between phase 1 and phase 2
+ if ( ( iSMSPClientId->iSessionHandle == aId->iSessionHandle ) &&
+ ( iSMSPClientId->iSubSessionHandle == aId->iSubSessionHandle ) )
+ {
+ // Copy the streamed list to the client
+ aBuffer->Copy( iSMSPList->Ptr( 0 ) );
+
+ iMmPhone->ReqCompleted( aTsyReqHandle, KErrNone );
+ }
+ else
+ {
+ iMmPhone->ReqCompleted( aTsyReqHandle, KErrCorrupt );
+ }
+
+ // Reset the client Id
+ delete iSMSPClientId;
+ iSMSPClientId = NULL;
+
+ // Reset the streamed list
+ delete iSMSPList;
+ iSMSPList = NULL;
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::ReadAllSmspCancel
+// This method cancels read all SMS Parameter sets request.
+// This method can be called between phase1 and phase2
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::ReadAllSmspCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeSmsReadSmspListPhase1 );
+
+ iRetSMSPSize = NULL;
+
+ if ( iSMSPClientId )
+ {
+ delete iSMSPClientId;
+ iSMSPClientId = NULL;
+ }
+
+ if ( iSMSPList )
+ {
+ delete iSMSPList;
+ iSMSPList = NULL;
+ }
+
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CreateSmspListL
+// This method creates SMSP list from read entries.
+// Method reads the list, and stores its content in iSMSPList.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CreateSmspListL(
+ CArrayPtrFlat<TSmsParameters>& aSmspList )
+ {
+ CMobilePhoneSmspList* list = CMobilePhoneSmspList::NewL();
+ CleanupStack::PushL( list );
+
+ TUint8 amountOfSets = static_cast< TUint8 >( aSmspList.Count() );
+
+ RMobileSmsMessaging::TMobileSmspEntryV1 entry;
+
+ // Runs until TSY's internal SMSP storage is empty
+ while ( 0 != aSmspList.Count() )
+ {
+ TSmsParameters* smsParam = aSmspList.At( 0 );
+ entry.iIndex = ( smsParam->iLocationNumber );
+
+ if ( smsParam->iAlphaTagPresent )
+ {
+ entry.iText.Copy( smsParam->iAlphaTagData );
+ }
+ else
+ {
+ entry.iText.SetLength( 0 );
+ }
+
+ entry.iValidParams = ( smsParam->iParameterIndicator );
+
+ TInt paramask =
+ KSmsGsmParametersIndMask & ( smsParam->iParameterIndicator );
+
+ if ( paramask & KDestinationAddress )
+ {
+ entry.iDestination.iTypeOfNumber = ( smsParam->iMobileDeTON );
+ entry.iDestination.iNumberPlan = ( smsParam->iMobileDeNPI );
+ entry.iDestination.iTelNumber = ( smsParam->iDestinationAddress );
+ }
+
+ if ( paramask & KServiceCentreAddress )
+ {
+ entry.iServiceCentre.iTypeOfNumber = ( smsParam->iMobileScTON );
+ entry.iServiceCentre.iNumberPlan = ( smsParam->iMobileScNPI );
+ entry.iServiceCentre.iTelNumber =
+ ( smsParam->iServiceCenterAddress );
+ }
+
+ if ( paramask & KProtocolID )
+ {
+ entry.iProtocolId = ( smsParam->iProtocolId );
+ }
+
+ if ( paramask & KDataCodingScheme )
+ {
+ entry.iDcs = ( smsParam->iDataCodingScheme );
+ }
+
+ if ( paramask & KValidityPeriod )
+ {
+ entry.iValidityPeriod = ( smsParam->iValidityPeriod );
+ }
+
+ list->AddEntryL( entry );
+
+ // Delete handled SMSP set
+ delete smsParam; // Delete object
+ aSmspList.Delete( 0 ); // Delete pointer from array
+ aSmspList.Compress();
+ }
+
+ // Set maximum amount of SMSP sets to the list.
+ list->SetMaxNumberEntries( amountOfSets );
+
+ iSMSPList = list->StoreLC(); // creates new CBufFlat buffer and
+ // pushes it on cleanup stack
+ CleanupStack::Pop(); // pop the iSMSPList
+
+ CleanupStack::PopAndDestroy(); // pop&destroy CMobilePhoneSmspList* list
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteReadAllSmspPhase1
+// Complete first phase of read all SMSP sets request, i.e. returns
+// size of iSMSPList buffer to client.
+// Parameter aDataPackage contains SMSP list in CArrayPtrFlat<TSmsParameters>.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteReadAllSmspPhase1(
+ TInt aError,
+ CMmDataPackage* aDataPackage )
+ {
+ CArrayPtrFlat<TSmsParameters>* smsParams;
+
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsReadSmspListPhase1 );
+
+TFLOGSTRING2("TSY: CMmSmsTsy::CompleteReadAllSmspPhase1 Complete read first phase error: %d",aError);
+ if ( KErrNone == aError )
+ {
+ aDataPackage->UnPackData( &smsParams );
+ if ( reqHandle )
+ {
+ // Create the Smsp list
+ TInt trapError;
+ if( NULL == smsParams)
+ {
+ trapError = KErrGeneral;
+ }
+ else
+ {
+ TRAP( trapError, CreateSmspListL( *smsParams ); );
+ }
+
+ if ( KErrNone == trapError )
+ {
+ *iRetSMSPSize = iSMSPList->Size();
+TFLOGSTRING("TSY: CMmSmsTsy::CompleteReadAllSmspPhase1: Phase 1 OK.");
+ // Complete first phase of read all SMSP sets
+ ReqCompleted( reqHandle, KErrNone );
+ }
+ else
+ {
+TFLOGSTRING2("TSY: CMmSmsTsy::CompleteReadAllSmspPhase1: Could not create SMSP list, trapError=%d",trapError);
+ // Complete with error
+ ReqCompleted( reqHandle, trapError );
+ }
+ }
+ }
+ else
+ {
+ if ( reqHandle )
+ {
+ // Complete first phase of read all SMSP sets.
+ ReqCompleted( reqHandle, aError );
+ }
+ }
+ iRetSMSPSize = NULL;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::StoreSmspList
+// This method start storing of new version of the entire list
+// of SMSP entries prosess
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::StoreSmspList(
+ const TTsyReqHandle aTsyReqHandle,
+ TDes8* aBuffer )
+ {
+ TTsyReqHandle storeSmspListHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeSmsStoreSmspList );
+
+ if ( 0 < storeSmspListHandle )
+ {
+ // The request is already processing because of previous request.
+ // Complete request with status value informing the client about
+ // the situation.
+ ReqCompleted( aTsyReqHandle, KErrServerBusy );
+ }
+ else
+ {
+ iStoreSmspBufferPtr = aBuffer;
+ iStoreSmspIndex = 0;
+
+ // We must store request handle here and not in ExtFunc-method.
+ // If SMSP list is empty we must complete store SMSP list request in
+ // ProcessStoreSmspListL-method and then we need request handle.
+#ifdef REQHANDLE_TIMER
+ SetTypeOfResponse( EMultimodeSmsStoreSmspList, aTsyReqHandle );
+#else
+ iTsyReqHandleStore->SetTsyReqHandle( EMultimodeSmsStoreSmspList,
+ aTsyReqHandle );
+#endif // REQHANDLE_TIMER
+ CallProcessStoreSmspList();
+ }
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::InternalStoreSmspList
+// This method check if there was error while updating last SMSP
+//set. If there was no error it calls CompleteStoreSmspListL- method
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::InternalStoreSmspList(
+ TInt aError )
+ {
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->GetTsyReqHandle(
+ EMultimodeSmsStoreSmspList );
+
+ if ( reqHandle )
+ {
+ if ( KErrNone == aError )
+ {
+ // Lets continue storing prosess
+ CallProcessStoreSmspList();
+ }
+ else
+ {
+ CompleteStoreSmspList( aError );
+ }
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CallProcessStoreSmspList
+// This method calls ProcessStoreSmspListL-method
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CallProcessStoreSmspList()
+ {
+ TRAPD ( ret, ProcessStoreSmspListL(); );
+ if ( ret != KErrNone )
+ {
+ CompleteStoreSmspList( ret );
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::ProcessStoreSmspListL
+// This method gets one SMSP sets from clients list and calls
+// DOS OR completes client's request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::ProcessStoreSmspListL()
+ {
+ CMobilePhoneSmspList* smspList = CMobilePhoneSmspList::NewL();
+ CleanupStack::PushL( smspList );
+
+ smspList->RestoreL( *iStoreSmspBufferPtr );
+
+ if ( smspList->Enumerate() > iStoreSmspIndex )
+ {
+ RMobileSmsMessaging::TMobileSmspEntryV1 smsParam;
+ CMmDataPackage package;
+
+ // Clients SMSP lists first location is 0
+ smsParam = smspList->GetEntryL( iStoreSmspIndex );
+
+ iStoreSmspIndex++;
+
+ // Pack parameters
+ package.PackData( &smsParam );
+
+ // Lets make new routing request so new CBMI list can be delivered to
+ // DOS
+ TInt ret = iMmPhone->MessageManager()->HandleRequestL(
+ EMobileSmsMessagingStoreSmspList, &package );
+
+ if ( KErrNone != ret )
+ {
+ // Message construction failed or phonet sender
+ // returned error. Complete request in CallProsessStoreSmspList
+ // method
+ CompleteStoreSmspList( ret );
+ }
+ }
+
+ // All SMSP sets have successfully been stored
+ else
+ {
+ // Notify that SMSP set was updated in the store
+ CompleteNotifySmspListChange();
+
+ // Complete store SMSP list request to the client
+ CompleteStoreSmspList( KErrNone );
+ }
+
+ CleanupStack::PopAndDestroy(); // aSmspList
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteStoreSmspList
+// Complete store SMSP list request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteStoreSmspList(
+ TInt aError )
+ {
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsStoreSmspList );
+ if ( reqHandle )
+ {
+ ReqCompleted( reqHandle, aError );
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::NotifySmspListChange
+// This method activates notifying of SMS Parameter store events
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::NotifySmspListChange()
+ {
+ iReqHandleType = EMultimodeSmsNotifySmspListChange;
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::NotifySmspListChangeCancel
+// This method cancels NotifyStoreEventCancel request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::NotifySmspListChangeCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsNotifySmspListChange );
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteNotifySmspListChange
+// This method is called when some of SMS parameter store events happen
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteNotifySmspListChange()
+ {
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsNotifySmspListChange );
+ if ( reqHandle )
+ {
+ ReqCompleted( reqHandle, KErrNone );
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::GetSmsNumOfLoc
+// Get SMS number of Location on SIM card
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt16 CMmSmsTsy::GetSmsNumOfLoc()
+ {
+ return static_cast< TInt16 >( iSmsNumOfLoc );
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::SetSmsNumOfLoc
+// Set SMS number of Location on SIM card to member variable
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::SetSmsNumOfLoc(
+ TInt aSmsNumOfLoc )
+ {
+ iSmsNumOfLoc = static_cast< TUint8 >( aSmsNumOfLoc );
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::GetSmsStorageTsy
+// Returns a pointer to the SMS Storage sub-session
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CMmSmsStorageTsy* CMmSmsTsy::GetSmsStorageTsy()
+ {
+ return iMmSmsStorageTsy;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::SetSmsStorageTsy
+// Sets a new pointer to the SMS Storage sub-session
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::SetSmsStorageTsy(
+ CMmSmsStorageTsy* aNewPointer )
+ {
+ iMmSmsStorageTsy = aNewPointer;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::ResetVariables
+// Reset used variables
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::ResetVariables()
+ {
+ // Resets routing activity variable. If routing is active in DOS
+ // this parameter is true.
+ iServerRoutingActivity = ERoutingNotActivated;
+
+ // Resets mobile sms receive mode to EReceiveUnstoredClientAck. Mobile
+ // sms receive mode includes the receive mode type.
+ iMobileSmsReceiveMode = RMobileSmsMessaging::EReceiveUnstoredClientAck;
+
+ // Resets receive mode change notify variables.
+ iNotifyReceiveModeChangePtr = NULL;
+
+ // Resets receive message variables.
+ iReceiveMessagePduPtr = NULL;
+ iReceiveMessageParamsPtr = NULL;
+
+ // Resets sms bearer notify variables.
+ iNotifySmsBearerPtr = NULL;
+
+ // Resets send message variables.
+ iSendMessageMsgAttrPckgPtr = NULL;
+
+ // Resets get message store variables.
+ iGetMessageStoreInfoPtr = NULL;
+
+ // Resets smsp (sms parameters) variables.
+ iRetSMSPSize = NULL;
+ iSMSPClientId = NULL;
+ iSMSPList = NULL;
+
+ // Resets sms storage parameter variables.
+ iStoreSmspBufferPtr = NULL;
+ iStoreSmspIndex = NULL;
+
+ // Resets sms storage tsy variable.
+ iMmSmsStorageTsy = NULL;
+
+ // Resets SMS stack storage status variables
+ iClientStorageFull = EFalse;
+
+
+ //Set number of SMS locations on SIM card to 0
+ iSmsNumOfLoc = 0;
+ }
+
+#ifdef REQHANDLE_TIMER
+//----------------------------------------------------------------------------
+// CMmSmsTsy::SetTypeOfResponse
+// Sets the type of response for a given Handle. Automatic
+// mode includes an automatic response in case of non response
+// from the DOS in a specified time
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::SetTypeOfResponse(
+ const TInt aReqHandleType,
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ TInt timeOut( 0 );
+
+ switch ( aReqHandleType )
+ {
+ // SMS specific requests
+ case EMultimodeSmsSetReceiveMode:
+ timeOut = KMmSmsSetReceiveMode;
+ break;
+ case EMultimodeSmsAckStored:
+ case EMultimodeSmsNackStored:
+ timeOut = KMmSmsAckNackMessage;
+ break;
+ case EMultimodeSmsSendMessage:
+ timeOut = KMmSmsSendMessage;
+ break;
+ case EMultimodeSmsSendMessageNoFdnCheck:
+ timeOut = KMmSmsSendMessageNoFdnCheckTimeOut;
+ break;
+ case EMultimodeSmsSendSatMessage:
+ timeOut = KMmSmsSendSatMessage;
+ break;
+ case EMultimodeSmsResumeReception:
+ timeOut = KMmSmsResumeSmsReception;
+ break;
+ case EMultimodeSmsGetMessageStoreInfo:
+ timeOut = KMmSmsGetMessageStoreInfo;
+ break;
+ case EMultimodeSmsReadSmspListPhase1:
+ case EMultimodeSmsStoreSmspList:
+ timeOut = KMmSmsReadAndStoreSmspList;
+ break;
+ // SMS storage specific requests
+ case EMultimodeSmsGetInfo:
+ timeOut = KMmSimSmsGetInfo;
+ break;
+ case EMultimodeSimStSmsWriteSms:
+ timeOut = KMmSimSmsWriteSms;
+ break;
+ case EMultimodeSimStSmsReadSms:
+ case EMultimodeSimStSmsEraseSms:
+ timeOut = KMmSimSmsReadDeleteSms;
+ break;
+ case EMultimodeSimStSmsEraseAllSms:
+ timeOut = KMmSimSmsDeleteAllSms;
+ break;
+ case EMultimodeSimStSmsReadAllSms:
+ timeOut = KMmSimSmsReadAllSms;
+ break;
+ // Must not use timer:
+ // case EMultimodeSmsReceiveMessage:
+ // case EMultimodeSmsNotifyReceiveModeChange:
+ // case EMultimodeSmsNotifyMoSmsBearerChange:
+ // case EMultimodeSmsNotifySmspListChange:
+ // case EMultimodeSmsMemoryNotifyStoreEvent:
+ default:
+ // does not use timer
+ iTsyReqHandleStore->SetTsyReqHandle(
+ aReqHandleType, aTsyReqHandle );
+ break;
+ }
+
+ if ( timeOut > 0 )
+ {
+ // the timeout parameter is given in seconds.
+ iTsyReqHandleStore->SetTsyReqHandle( aReqHandleType, aTsyReqHandle,
+ timeOut );
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::Complete
+// Completes the request due timer expiration
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::Complete(
+ TInt aReqHandleType,
+ TInt aError )
+ {
+ // All possible TSY req handle types are listed in the
+ // switch case below.
+ switch( aReqHandleType )
+ {
+ // Cases handled with automatic completion
+ // SMS specific requests
+ case EMultimodeSmsAckStored:
+ CompleteAckSmsStored( aError );
+ break;
+ case EMultimodeSmsNackStored:
+ CompleteNackSmsStored( aError );
+ break;
+ case EMultimodeSmsSendMessage:
+ CompleteSendMessage( KErrTimedOut, NULL );
+ break;
+ case EMultimodeSmsSendMessageNoFdnCheck:
+ CompleteSendMessageNoFdnCheck( KErrTimedOut, NULL );
+ break;
+ case EMultimodeSmsSendSatMessage:
+ CompleteSendSatMessage( KErrTimedOut );
+ break;
+ case EMultimodeSmsResumeReception:
+ CompleteResumeSmsReception( aError );
+ break;
+ case EMultimodeSmsGetMessageStoreInfo:
+ CompleteGetMessageStoreInfo( aError, NULL );
+ break;
+ case EMultimodeSmsReadSmspListPhase1:
+ CompleteReadAllSmspPhase1( aError, NULL );
+ break;
+ case EMultimodeSmsStoreSmspList:
+ CompleteStoreSmspList( aError );
+ break;
+ // SMS storage specific requests
+ case EMultimodeSmsGetInfo:
+ if ( iMmSmsStorageTsy )
+ {
+ iMmSmsStorageTsy->CompleteGetInfo( aError, NULL );
+ }
+ break;
+ case EMultimodeSimStSmsReadSms:
+ if ( iMmSmsStorageTsy )
+ {
+ iMmSmsStorageTsy->CompleteReadSms( aError, NULL );
+ }
+ break;
+ case EMultimodeSimStSmsWriteSms:
+ if ( iMmSmsStorageTsy )
+ {
+ iMmSmsStorageTsy->CompleteWriteSms( aError, NULL );
+ }
+ break;
+ case EMultimodeSimStSmsEraseSms:
+ if ( iMmSmsStorageTsy )
+ {
+ iMmSmsStorageTsy->CompleteDeleteSms( aError );
+ }
+ break;
+ case EMultimodeSimStSmsEraseAllSms:
+ if ( iMmSmsStorageTsy )
+ {
+ iMmSmsStorageTsy->CompleteDeleteAllSms( aError );
+ }
+ break;
+ case EMultimodeSimStSmsReadAllSms:
+ if ( iMmSmsStorageTsy )
+ {
+ iMmSmsStorageTsy->CompleteReadAllSmsPhase1( aError, EFalse );
+ }
+ break;
+ // Can't use timer:
+ // case EMultimodeSmsReceiveMessage:
+ // case EMultimodeSmsNotifyReceiveModeChange:
+ // case EMultimodeSmsNotifyMoSmsBearerChange:
+ // case EMultimodeSmsNotifySmspListChange:
+ // case EMultimodeSmsMemoryNotifyStoreEvent:
+ default:
+ ReqCompleted( iTsyReqHandleStore->ResetTsyReqHandle(
+ aReqHandleType ), aError );
+ break;
+ }
+ }
+
+#endif // REQHANDLE_TIMER
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::SendSatMessageL
+// SimAtkTsy can send SMS messages to the network by calling this method.
+// This method can leave.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::SendSatMessageL(
+ CMmPhoneTsy* aMmPhone,
+ TDes8* aSmsTpdu,
+ TDes16* aScAddress,
+ RMobilePhone::TMobileTON* aMobileTON,
+ RMobilePhone::TMobileNPI* aMobileNPI,
+ TBool aMoreToSend )
+ {
+ TInt ret( KErrNone );
+ // Deliver attributes to message handler by using
+ // TMobileSmsSendAttributesV1 class.
+ RMobileSmsMessaging::TMobileSmsSendAttributesV1 msgAttrib;
+
+ msgAttrib.iFlags = ( RMobileSmsMessaging::KSmsDataFormat |
+ RMobileSmsMessaging::KGsmServiceCentre |
+ RMobileSmsMessaging::KMoreToSend );
+
+ msgAttrib.iDataFormat = RMobileSmsMessaging::EFormatGsmTpdu;
+
+ // if service center address length > 20 digits plus "+" sign
+ if ( aScAddress->Length() > ( KMaxAmountOfDigits + 1 ) )
+ {
+ ret = KErrArgument;
+ }
+ else
+ {
+ msgAttrib.iGsmServiceCentre.iTelNumber.Copy( *aScAddress );
+ msgAttrib.iGsmServiceCentre.iTypeOfNumber = *aMobileTON;
+ msgAttrib.iGsmServiceCentre.iNumberPlan = *aMobileNPI;
+
+ msgAttrib.iMore = aMoreToSend;
+
+ // create package
+ CMmDataPackage package;
+
+ // structure for all sms parameters and data
+ TSendSmsDataAndAttributes sendData;
+
+ sendData.iAttributes = &msgAttrib;
+ sendData.iMsgData = aSmsTpdu;
+ sendData.iIpc = EMmTsySmsSendSatMessage;
+
+ // Pack parameters
+ package.PackData( &sendData );
+
+ // send request to DOS
+ ret = aMmPhone->MessageManager()->HandleRequestL(
+ EMmTsySmsSendSatMessage, &package );
+
+ if ( KErrNone == ret )
+ {
+ iReqHandleType = EMultimodeSmsSendSatMessage;
+ }
+ }
+
+ return ret;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::ResendSms
+// Resends unsent message which is stored in iSmsSendReq
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::ResendSms()
+ {
+ if ( NULL != iSmsSendReq )
+ {
+ // Create package
+ CMmDataPackage package;
+
+ // structure for all sms parameters and data
+ TSendSmsDataAndAttributes sendData =
+ iSmsSendReq->GetSmsDataAndAttributes();
+
+ // Pack parameters
+ package.PackData( &sendData );
+
+ // send request to DOS
+ TInt ret = KErrNone;
+ TRAPD( trapError, ret = iMmPhone->MessageManager()->HandleRequestL(
+ sendData.iIpc, &package ); );
+
+ if ( ( KErrNone != ret ) || ( KErrNone != trapError ) )
+ {
+ delete iSmsSendReq; // Delete object
+ iSmsSendReq = NULL; // Reset pointer
+
+ // Response for send SMS request
+ if ( EMobileSmsMessagingSendMessage == sendData.iIpc )
+ {
+ iSmsNoFdnCheckFlag = ESmsNoFdnCheckNotUsed;
+ CompleteSendMessage( KErrGeneral, NULL );
+ }
+ // Response for send SAT SMS request
+ else if ( EMmTsySmsSendSatMessage == sendData.iIpc )
+ {
+ CompleteSendSatMessage( KErrGeneral );
+ }
+ // Response for send SMS NoFdnCheck request
+ else if ( EMobileSmsMessagingSendMessageNoFdnCheck ==
+ sendData.iIpc )
+ {
+ iSmsNoFdnCheckFlag = ESmsNoFdnCheckUsed;
+TFLOGSTRING2("TSY: CMmSmsTsy::ResendSms. EMobileSmsMessagingSendMessageNoFdnCheck: %d", sendData.iIpc);
+ CompleteSendMessageNoFdnCheck( KErrGeneral, NULL );
+ }
+ }
+ else
+ {
+ iSmsSendReq->IncreaseSendCounter();
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMmSmsTsy::IsRequestPossibleInOffLine
+// Checks wether a ETel request can be performed or not while offline mode is
+// enabled
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TBool CMmSmsTsy::IsRequestPossibleInOffline( TInt aIpc ) const
+ {
+ TBool isRequestPossible ( ETrue );
+ switch ( aIpc )
+ {
+ case EMobileSmsMessagingSendMessage: //NO
+ case EMobileSmsMessagingSendMessageNoFdnCheck: //NO
+ isRequestPossible = EFalse;
+ break;
+ // case EMobileSmsMessagingSetReceiveMode:
+ // case EMobileSmsMessagingNotifyReceiveModeChange:
+ // case EMobileSmsMessagingReceiveMessage:
+ // case EMobileSmsMessagingAckSmsStored:
+ // case EMobileSmsMessagingNackSmsStored:
+ // case EMobileSmsMessagingResumeSmsReception: //request is possible
+ //(will be delayed
+ // and sent later, see
+ // ResumeSmsReception)
+ // case EMobileSmsMessagingNotifyMoSmsBearerChange:
+ // case EMobileSmsMessagingGetMessageStoreInfo:
+ // case EMobileSmsMessagingGetSmspListPhase1:
+ // case EMobileSmsMessagingNotifySmspListChange:
+ // case EMobileSmsMessagingStoreSmspList:
+ default:
+ break;
+ }
+
+ return isRequestPossible;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmSmsTsy::SendMessageNoFdnCheckCancel
+// Cancels SendMessageNoFdnCheck request.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmSmsTsy::SendMessageNoFdnCheckCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+TFLOGSTRING("TSY: CMmSmsTsy::SendMessageNoFdnCheckCancel" );
+ // Reset req handle. Returns the deleted req handle
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeSmsSendMessageNoFdnCheck );
+
+ if ( EMultimodeSmsReqHandleUnknown < reqHandle )
+ {
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+
+ iSmsNoFdnCheckFlag = ESmsNoFdnCheckUnknown;
+ }
+
+ return KErrNone;
+ }
+
+//----------------------------------------------------------------------------
+// CMmSmsTsy::CompleteSendMessageNoFdnCheck
+// Complete SendMessage request
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmSmsTsy::CompleteSendMessageNoFdnCheck(
+ TInt aError,
+ CMmDataPackage* aDataPackage )
+ {
+ if ( ( KErrNone != aError ) && ( KErrTimedOut != aError )
+ && ( KErrGsmSMSOperationNotAllowed !=
+ CMmCommonStaticUtility::ExtendedErrorCode ( aError ) )
+ // FDB check failed
+ && ( KErrGsmSMSUnspecifiedProtocolError !=
+ CMmCommonStaticUtility::ExtendedErrorCode ( aError ) )
+ && ( KErrSatControl !=
+ CMmCommonStaticUtility::ExtendedErrorCode ( aError ) )
+ && ( !( iMmPhone->GetSatMessaging() &&
+ iMmPhone->GetSatMessaging()->IsMoSmControlBySimActivated() ) )
+ && ( NULL != iSmsSendReq ) && ( 2 >=
+ iSmsSendReq->GetSendCounter() ) )
+ {
+ // DOS returned error to send request. Message might be tried to be
+ // resent (see method ResendSms).
+ // Timeout mechanism cannot access this part of code, ever.
+TFLOGSTRING2("TSY: CMmSmsTsy::CompleteSendMessageNoFdnCheck. Resend counter: %d", iSmsSendReq->GetSendCounter());
+ }
+ else
+ {
+ // This is executed
+ // - if sending was successful
+ // - if there are no more resending attempts
+ // - if timer expires (called from the Complete of CMmSmsTsy class)
+
+ // Delete send message entry from send array
+ if ( iSmsSendReq )
+ {
+ delete iSmsSendReq; // Delete object
+ iSmsSendReq = NULL; // Reset pointer
+ }
+
+ // reset req handle and complete request
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->
+ ResetTsyReqHandle( EMultimodeSmsSendMessageNoFdnCheck );
+
+ if ( EMultimodeSmsReqHandleUnknown < reqHandle )
+ {
+ // get values only if there was no error, and if return pointer to
+ // client is available
+ if ( KErrNone == aError && iSendMessageMsgAttrPckgPtr )
+ {
+ TInt16 msgRef( 0 );
+ TBuf8<RMobileSmsMessaging::KGsmTpduSize> smsMsg;
+
+ aDataPackage->UnPackData( msgRef, smsMsg );
+
+ RMobileSmsMessaging::TMobileSmsSendAttributesV1Pckg* attsPckg =
+ reinterpret_cast<
+ RMobileSmsMessaging::TMobileSmsSendAttributesV1Pckg* >(
+ iSendMessageMsgAttrPckgPtr );
+ RMobileSmsMessaging::TMobileSmsSendAttributesV1& msgAttr =
+ ( *attsPckg )();
+
+ msgAttr.iFlags = RMobileSmsMessaging::KMessageReference;
+ msgAttr.iMsgRef = static_cast< TUint16 >( msgRef );
+
+ if ( NULL != smsMsg.Length() )
+ {
+ msgAttr.iSubmitReport.Copy(smsMsg);
+ msgAttr.iFlags |= RMobileSmsMessaging::KGsmSubmitReport;
+ }
+ }
+
+ ReqCompleted( reqHandle, aError );
+ // reset pointer to client memory
+ iSendMessageMsgAttrPckgPtr = NULL;
+
+ iSmsNoFdnCheckFlag = ESmsNoFdnCheckUnknown;
+ }
+ }
+
+ // Resend unsent message
+ ResendSms();
+ }
+
+
+// End of File