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