diff -r 000000000000 -r 3553901f7fa8 telephonyserverplugins/common_tsy/commontsy/src/mmsms/cmmsmstsy.cpp --- /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 +#include "MmTsy_numberOfSlots.h" +#include +#include "cmmsmssendrequest.h" +#include +#include "CMmCommonStaticUtility.h" +#include +#include +#include // 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( 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( 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( 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 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& 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. +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CMmSmsTsy::CompleteReadAllSmspPhase1( + TInt aError, + CMmDataPackage* aDataPackage ) + { + CArrayPtrFlat* 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 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