diff -r 000000000000 -r 3553901f7fa8 telephonyserverplugins/common_tsy/commontsy/src/mmsms/cmmbroadcasttsy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/telephonyserverplugins/common_tsy/commontsy/src/mmsms/cmmbroadcasttsy.cpp Tue Feb 02 01:41:59 2010 +0200 @@ -0,0 +1,1290 @@ +// 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 +#include +#include "cmmbroadcasttsy.h" +#include "cmmphonetsy.h" +#include "CMmPrivateUtility.h" // Read all list class +#include +#include "MmTsy_numberOfSlots.h" +#include "cmmtsyreqhandlestore.h" +#include +#include +#include "cmmnettsy.h" + +// ======== MEMBER FUNCTIONS ======== + +CMmBroadcastTsy::CMmBroadcastTsy() + { + // Set number of WCDMA CBS Pages to 0 + iWcdmaPageNumber = 0; + + // Defaut value for iWcdmaCbsPageLeft.it means that there are + // no page left to send to upper layer + iWcdmaCbsPageLeft = EFalse; + + // First page is always at index 0 + iWcdmaCbsMsgPageIndex = 0; + } + +void CMmBroadcastTsy::ConstructL() + { +TFLOGSTRING("TSY: CMmBroadcastTsy::ConstructL"); +#ifdef REQHANDLE_TIMER + // create req handle store + iTsyReqHandleStore = CMmTsyReqHandleStore::NewL( this, iMmPhone, + EMultimodeBroadcastMaxNumOfRequests, iBroadcastReqHandles ); +#else + // create req handle store + iTsyReqHandleStore = CMmTsyReqHandleStore::NewL( + EMultimodeBroadcastMaxNumOfRequests, iBroadcastReqHandles ); +#endif // REQHANDLE_TIMER + + // Reset all CMmBroadcastTsy variables + ResetVariables(); + + // Maximun of subBlocks is 15 so let's put the granularity to 10 + iCbsMsg = new( ELeave ) CArrayPtrFlat< TWcdmaCbsMsg >( 10 ); + + // register broadcast tsy in the message manager + iMmPhone->MessageManager()->RegisterTsyObject( + CMmMessageManagerBase::EBroadcastMessagingTsy, this ); + } + +CMmBroadcastTsy* CMmBroadcastTsy::NewL( + CMmPhoneTsy* aMmPhone ) + { + CMmBroadcastTsy* aMmBroadcastTsy = new ( ELeave ) CMmBroadcastTsy(); + CleanupClosePushL( *aMmBroadcastTsy ); + aMmBroadcastTsy->iMmPhone = aMmPhone; + aMmBroadcastTsy->ConstructL(); + CleanupStack::Pop(); + + return aMmBroadcastTsy; + } + +CMmBroadcastTsy::~CMmBroadcastTsy() + { +TFLOGSTRING("TSY: CMmBroadcastTsy::~CMmBroadcastTsy"); + if ( iMmPhone ) + { + // deregister tsy object from message manager + iMmPhone->MessageManager()->DeregisterTsyObject(this); + } + + delete iTsyReqHandleStore; + iTsyReqHandleStore = NULL; + + // Delete iCbsMsg + delete iCbsMsg; + iCbsMsg = NULL; + + // Set pointers to NULL + iMmPhone = NULL; + iMessageManager = NULL; + iReceiveCbMessagePtr = NULL; + iReceiveCbMessageAttributesPtr = NULL; + iNotifyFilterSettingChangePtr = NULL; + + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::Init +// Initialisation method +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CMmBroadcastTsy::Init() + { + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::ExtFunc +// Handling of extended requests +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TInt CMmBroadcastTsy::ExtFunc( + const TTsyReqHandle aTsyReqHandle, + const TInt aIpc, + const TDataPackage& aPackage ) + { + TInt ret( KErrNone ); + TAny* dataPtr = aPackage.Ptr1(); + TAny* dataPtr2 = aPackage.Ptr2(); + + switch ( aIpc ) + { + // Cell broadcast requests that doesn't need trapping + case EMobileBroadcastMessagingGetCaps: + ret = GetCaps( aTsyReqHandle, aPackage.Des1n() ); + break; + case EMobileBroadcastMessagingGetFilterSetting: + ret = GetFilterSetting( aTsyReqHandle, reinterpret_cast< + RMobileBroadcastMessaging::TMobilePhoneBroadcastFilter*> + ( dataPtr ) ); + break; + case EMobileBroadcastMessagingGetIdListPhase1: + TRAP_IGNORE( ret = GetBroadcastIdListPhase1L( aTsyReqHandle, + reinterpret_cast< CRetrieveMobilePhoneBroadcastIdList:: + TGetBroadcastIdRequest* > ( dataPtr ), + reinterpret_cast< TInt* > ( dataPtr2 ) ); ); + break; + case EMobileBroadcastMessagingGetIdListPhase2: + ret = GetBroadcastIdListPhase2( aTsyReqHandle, + reinterpret_cast< RMobilePhone::TClientId* > ( dataPtr ), + aPackage.Des2n() ); + break; + // Cell broadcast requests that may need trapping + default: + // reset last tsy request type + iReqHandleType = EMultimodeBroadcastReqHandleUnknown; + + TInt leaveCode( KErrNone ); + TRAP( leaveCode, ret = DoExtFuncL( aTsyReqHandle, aIpc, + aPackage ); ); + + if ( KErrNone != leaveCode ) + { + ReqCompleted( aTsyReqHandle, leaveCode ); + } + + // save request handle + if ( EMultimodeBroadcastReqHandleUnknown != iReqHandleType ) + { +#ifdef REQHANDLE_TIMER + SetTypeOfResponse( iReqHandleType, aTsyReqHandle ); +#else + //Never comes here ? See SetTypeOfResponse. + iTsyReqHandleStore->SetTsyReqHandle( iReqHandleType, + aTsyReqHandle ); +#endif // REQHANDLE_TIMER + } + break; + } + + return ret; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::DoExtFuncL +// Handling of broadcast related requests that needs trapping +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TInt CMmBroadcastTsy::DoExtFuncL( + const TTsyReqHandle aTsyReqHandle, + const TInt aIpc, + const TDataPackage& aPackage ) + { + TInt ret( KErrNone ); + TAny* dataPtr = aPackage.Ptr1(); + + switch ( aIpc ) + { + // Cell broadcast requests that may need trapping + case EMobileBroadcastMessagingReceiveMessage: + ret = ReceiveMessageL( + aTsyReqHandle, aPackage.Des1n(), aPackage.Des2n() ); + break; + case EMobileBroadcastMessagingSetFilterSetting: + ret = SetFilterSettingL( aTsyReqHandle, + reinterpret_cast< + RMobileBroadcastMessaging::TMobilePhoneBroadcastFilter* > + ( dataPtr ) ); + break; + case EMobileBroadcastMessagingNotifyFilterSettingChange: + ret = NotifyFilterSettingChange( reinterpret_cast< + RMobileBroadcastMessaging::TMobilePhoneBroadcastFilter* > + ( dataPtr ) ); + break; + case EMobileBroadcastMessagingStoreIdList: + ret = StoreBroadcastIdListL( aTsyReqHandle, aPackage.Des1n() ); + break; + default: + ret = KErrNotSupported; + break; + } + + return ret; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::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 CMmBroadcastTsy::CancelService( + const TInt aIpc, + const TTsyReqHandle aTsyReqHandle ) + { + TInt ret( KErrNone ); + switch ( aIpc ) + { + case EMobileBroadcastMessagingNotifyFilterSettingChange: + ret = NotifyFilterSettingChangeCancel ( aTsyReqHandle ); + break; + case EMobileBroadcastMessagingSetFilterSetting: + case EMobileBroadcastMessagingStoreIdList: + case EMobileBroadcastMessagingGetIdListPhase1: + case EMobileBroadcastMessagingGetIdListPhase2: + ret = KErrNone; + break; + // This cancel request may need message construction, + // so trapping is needed + case EMobileBroadcastMessagingReceiveMessage: + // call cancel handling + TRAPD( leaveCode, ( ret = ReceiveMessageCancelL( aTsyReqHandle ) ) ); + if ( KErrNone != leaveCode ) + { + ReqCompleted( aTsyReqHandle, leaveCode ); + } + break; + default: + ret = KErrGeneral; + break; + } + + return ret; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::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 CMmBroadcastTsy::ReqModeL( + const TInt aIpc ) + { + CTelObject::TReqMode ret = 0; + + switch ( aIpc ) + { + // Non-Flow Controlled Services + case EMobileBroadcastMessagingGetCaps: + case EMobileBroadcastMessagingGetFilterSetting: + case EMobileBroadcastMessagingGetIdListPhase1: + case EMobileBroadcastMessagingGetIdListPhase2: + case EMobileBroadcastMessagingStoreIdList: + break; + // Flow Controlled Services + case EMobileBroadcastMessagingSetFilterSetting: + ret = KReqModeFlowControlObeyed; + break; + // Multiple Completion Services with Immediate Server Repost + // (Usually Notifications) + case EMobileBroadcastMessagingReceiveMessage: + case EMobileBroadcastMessagingNotifyFilterSettingChange: + ret = KReqModeMultipleCompletionEnabled | + KReqModeRePostImmediately; + break; + default: + User::Leave ( KErrNotSupported ); + break; + } + + return ret; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::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 CMmBroadcastTsy::NumberOfSlotsL( + const TInt aIpc ) + { + TInt numberOfSlots = 1; + switch ( aIpc ) + { + // Number of slots for the receive message + case EMobileBroadcastMessagingReceiveMessage: + numberOfSlots = KMmBroadcastMessagingReceiveMessageSlots; + break; + // Number of the slots for the notify changes + case EMobileBroadcastMessagingNotifyFilterSettingChange: + numberOfSlots = + KMmBroadcastMessagingNotifyFilterSettingChangeSlots; + break; + default: + // Unknown or invalid Broadcast IPC + User::Leave ( KErrNotSupported ); + break; + } + + return numberOfSlots; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::OpenNewObjectByNameL +// Creates new object and returns a pointer to it +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +CTelObject* CMmBroadcastTsy::OpenNewObjectByNameL( + const TDesC& /*aName*/ ) + { + User::Leave( KErrNotSupported ); + //lint -e{527} "unreachable code" + + return NULL; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::OpenNewObjectL +// Creates new object and returns a pointer to it +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +CTelObject* CMmBroadcastTsy::OpenNewObjectL( + TDes& /*aName*/ ) + { + User::Leave( KErrNotSupported ); + //lint -e{527} "unreachable code" + + return NULL; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::RegisterNotification +// RegisterNotification is 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 CMmBroadcastTsy::RegisterNotification( + const TInt aIpc ) + { + switch ( aIpc ) + { + case EMobileBroadcastMessagingReceiveMessage: + case EMobileBroadcastMessagingNotifyFilterSettingChange: + return KErrNone; + default: + // Unknown or invalid Broadcast IPC + return KErrNotSupported; + } + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::DeregisterNotification +// DeregisterNotification is 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 DOS +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TInt CMmBroadcastTsy::DeregisterNotification( + const TInt aIpc ) + { + switch ( aIpc ) + { + case EMobileBroadcastMessagingReceiveMessage: + case EMobileBroadcastMessagingNotifyFilterSettingChange: + return KErrNone; + default: + // Unknown or invalid Broadcast IPC + return KErrNotSupported; + } + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::GetCaps +// This method returns a class that reflects the broadcast +// messaging capabilities of the phone. +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TInt CMmBroadcastTsy::GetCaps( + const TTsyReqHandle aTsyReqHandle, + TDes8* aCaps ) + { + + TInt ret( KErrArgument ); + + if ( aCaps ) + { + TInt paramLength = aCaps->MaxLength(); + TInt expectedLength = sizeof( RMobileBroadcastMessaging::TMobileBroadcastCapsV1Pckg ); + + if (paramLength == expectedLength) + { + RMobileBroadcastMessaging::TMobileBroadcastCapsV1Pckg* cbsCapsPckg = + reinterpret_cast< RMobileBroadcastMessaging::TMobileBroadcastCapsV1Pckg* > + ( aCaps ); + RMobileBroadcastMessaging::TMobileBroadcastCapsV1& cbsCaps = + ( *cbsCapsPckg )(); + + cbsCaps.iModeCaps = RMobileBroadcastMessaging::KCapsGsmTpduFormat; + +#ifdef __WINS__ + + // force GSM+WCDMA capabilities for emulator testing + cbsCaps.iModeCaps = RMobileBroadcastMessaging::KCapsWcdmaTpduFormat + | RMobileBroadcastMessaging::KCapsGsmTpduFormat; + +#endif // __WINS__ + + // TSY supports only "accept all" and "reject all" filtering. + cbsCaps.iFilterCaps = RMobileBroadcastMessaging::KCapsSimpleFilter; + + TFLOGSTRING3("TSY:CMmBroadcastTsy::GetCaps:Mode caps=0x%x, Filter caps=0x%x",cbsCaps.iModeCaps,cbsCaps.iFilterCaps); + + ret = KErrNone; + ReqCompleted( aTsyReqHandle, ret ); + } + } + + return ret; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::ReceiveMessageL +// Activates routing of CB messages, and then waits for incoming CB messages +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TInt CMmBroadcastTsy::ReceiveMessageL( + const TTsyReqHandle aTsyReqHandle, + TDes8* aMsgData, + TDes8* aMsgAttributes ) + { + TInt ret = KErrArgument; + + if (aMsgData && aMsgAttributes) + { + + RMobileBroadcastMessaging::TBroadcastPageData tempData; + + if (aMsgData->MaxLength() == tempData.MaxLength()) + { + RMobileBroadcastMessaging::TMobileBroadcastAttributesV1 tempV1; + RMobileBroadcastMessaging::TMobileBroadcastAttributesV1Pckg tempV1Pckg(tempV1); + + RMobileBroadcastMessaging::TMobileBroadcastAttributesV2 tempV2; + RMobileBroadcastMessaging::TMobileBroadcastAttributesV2Pckg tempV2Pckg(tempV2); + + if ( (aMsgAttributes->MaxLength() == tempV1Pckg.MaxLength()) || (aMsgAttributes->MaxLength() == tempV2Pckg.MaxLength()) ) + { + ret = KErrNone; + } + + if (ret == KErrNone) + { + iReceiveCbMessagePtr = aMsgData; + iReceiveCbMessageAttributesPtr = aMsgAttributes; + + + if ( iWcdmaCbsPageLeft ) + { + // currentpage increased, because pages left to deliver + iWcdmaCurrentPage++; + + // there are previously received pages left + CompleteReceivedWcdmaCbsMessagePageLeft(); + ReqCompleted( aTsyReqHandle, KErrNone ); + } + else if ( !iCbRoutingActivated ) + { + // DOS's CB routing is not activated + TFLOGSTRING("TSY:CMmBroadcastTsy::ReceiveMessageL:DOS's CB routing is not activated, sending activation request."); + + //Create package + CMmDataPackage package; + + TCbsCbmiAndLangAndFilter data; + data.iSetting = RMobileBroadcastMessaging::EBroadcastAcceptAll; + data.iCbmiStorage = KNullDesC; // deprecated + data.iLanguageStorage = KNullDesC; // deprecated + + // Pack parameters + package.PackData( &data ); + + // Send request to the Domestic OS layer. + TInt error = iMmPhone->MessageManager()->HandleRequestL( + EMobileBroadcastMessagingReceiveMessage, &package ); + + if ( KErrNone == error ) + { + iReqHandleType = EMultimodeBroadcastReceiveMessage; + } + else + { + // Message construction failed or phonet sender returned error + ReqCompleted( aTsyReqHandle, error ); + } + } + else + { + TFLOGSTRING("TSY:CMmBroadcastTsy::ReceiveMessageL:DOS's CB routing is activated, waiting for messages."); + // routing is active, wait for messages from DOS + iReqHandleType = EMultimodeBroadcastReceiveMessage; + + // currentpage set to zero - no pages to deliver + iWcdmaCurrentPage = 0; + } + } + } + } + + return ret; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::InternalCompleteCbRoutingRequest +// Completes routing of CB messages request (does not include CB message) +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CMmBroadcastTsy::InternalCompleteCbRoutingRequest( + TInt aError ) + { +TFLOGSTRING2("TSY:CMmBroadcastTsy::InternalCompleteCbRoutingRequest:error=%d.", aError); + if ( KErrNone == aError ) + { + iCbRoutingActivated = ETrue; + } + else + { + TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle( + EMultimodeBroadcastReceiveMessage ); + + if ( reqHandle ) + { + ReqCompleted( reqHandle, aError ); + } + } + // Check if there are some WCDMA CBS Pages left to send to upper layer + if ( ( iWcdmaCbsPageLeft ) && ( KErrNone == aError ) ) + { + TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle( + EMultimodeBroadcastReceiveMessage ); + + if ( reqHandle ) + { + CompleteReceivedWcdmaCbsMessagePageLeft(); + ReqCompleted( reqHandle, aError ); + } + } + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::CompleteReceivedWcdmaCbsMessagePageLeft +// This method sends the pages left for WCDMA CBS message +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CMmBroadcastTsy::CompleteReceivedWcdmaCbsMessagePageLeft() + { +TFLOGSTRING2("TSY:CMmBroadcastTsy::CompleteReceivedWcdmaCbsMessagePageLeft:Delivering page %d to client.", iWcdmaCbsMsgPageIndex); + RMobileBroadcastMessaging::TMobileBroadcastAttributesV2Pckg* + attrPckg = reinterpret_cast + < RMobileBroadcastMessaging::TMobileBroadcastAttributesV2Pckg* > + ( iReceiveCbMessageAttributesPtr ); + + RMobileBroadcastMessaging::TMobileBroadcastAttributesV2& cbAttrib = + ( *attrPckg )(); + + // The bit-mask flags indicating which attributes are present in this + // instance + cbAttrib.iFlags = + ( RMobileBroadcastMessaging::KBroadcastDataFormat ); + + // WCDMA + cbAttrib.iFormat = RMobileBroadcastMessaging::EFormatWcdmaTpdu; + + // Number of pages + cbAttrib.iNumberOfPages = ( *iCbsMsg )[iWcdmaCbsMsgPageIndex] + ->iNumberOfPages; + + TFLOGSTRING2("TSY:CMmBroadcastTsy::CompleteReceiveMessageWcdmaCbs: cbAttrib.iNumberOfPages %x .", cbAttrib.iNumberOfPages); + + // Message Type + cbAttrib.iMessageType = ( *iCbsMsg )[iWcdmaCbsMsgPageIndex] + ->iMessageType; + + // Message ID + cbAttrib.iMessageId = ( *iCbsMsg )[iWcdmaCbsMsgPageIndex]->iMessageId; + + // Serial Number + cbAttrib.iSerialNum = ( *iCbsMsg )[iWcdmaCbsMsgPageIndex]->iSerialNum; + + // data coding scheme + cbAttrib.iDCS = ( *iCbsMsg )[iWcdmaCbsMsgPageIndex]->iDCS; + + iReceiveCbMessagePtr->Copy( ( *iCbsMsg )[iWcdmaCbsMsgPageIndex]->iWcdmaCbsData.Ptr(), + ( *iCbsMsg )[iWcdmaCbsMsgPageIndex]->iInfoLength ); + + TFLOGSTRING2("TSY:CMmBroadcastTsy::CompleteReceivedWcdmaCbsMessagePageLeft: AppendFormat in use iWcdmaCurrentPage: %d.", iWcdmaCurrentPage ); + _LIT8(KFormat, "%c"); + + // Append pagenumber to end of CBS message + iReceiveCbMessagePtr->AppendFormat(KFormat, iWcdmaCurrentPage); + + // Increase by 1 the page index + iWcdmaCbsMsgPageIndex++; + + // if all the pages have been sent to upper layer + if ( iWcdmaCbsMsgPageIndex == iWcdmaPageNumber ) + { + // all the pages have been read so set variable to its default + // value which means that there are no WCDMA CBS page to pass + // to upper layer anymore + iWcdmaCbsPageLeft = EFalse; + iWcdmaCbsMsgPageIndex = 0; + + // Reset the array + iCbsMsg->Reset(); + } + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::CompleteReceiveMessage +// This method completes routing of CB messages request +// (includes message) +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CMmBroadcastTsy::CompleteReceiveMessageGsmCbs( + TInt aError, + CMmDataPackage* aDataPackage ) + { +TFLOGSTRING2("TSY:CMmBroadcastTsy::CompleteReceiveMessageGsmCbs:error=%d.",aError); + TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle( + EMultimodeBroadcastReceiveMessage ); + + if ( reqHandle ) + { + if ( KErrNone == aError ) + { + TGsmCbsMsg cbsMsg; + + //Unpack data + aDataPackage->UnPackData( cbsMsg ); + + RMobileBroadcastMessaging::TMobileBroadcastAttributesV1Pckg* + attrPckg = reinterpret_cast + < RMobileBroadcastMessaging:: + TMobileBroadcastAttributesV1Pckg* > + ( iReceiveCbMessageAttributesPtr ); + + RMobileBroadcastMessaging::TMobileBroadcastAttributesV1& + cbAttrib = ( *attrPckg )(); + + cbAttrib.iFlags = + ( RMobileBroadcastMessaging::KBroadcastDataFormat ); + + // GSM Mode + cbAttrib.iFormat = RMobileBroadcastMessaging::EFormatGsmTpdu; + + iReceiveCbMessagePtr->Copy( cbsMsg.iCbsMsg ); + } + ReqCompleted( reqHandle, aError ); + } + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::CompleteReceiveMessageWcdmaCbs +// This method complete routing of Wcdma CB messages request +// (include message) +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CMmBroadcastTsy::CompleteReceiveMessageWcdmaCbs( + TInt aError, + CMmDataPackage* aDataPackage ) + { +TFLOGSTRING2("TSY:CMmBroadcastTsy::CompleteReceiveMessageWcdmaCbs:error=%d.", aError); + TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle( + EMultimodeBroadcastReceiveMessage ); + + // Reset array + iCbsMsg->Reset(); + + // Set to EFalse + iWcdmaCbsPageLeft = EFalse; + + if ( reqHandle ) + { + if ( KErrNone == aError ) + { + CArrayPtrFlat< TWcdmaCbsMsg >* cbsMsgTemp = NULL; + + // Unpack data + aDataPackage->UnPackData( cbsMsgTemp, iWcdmaPageNumber ); + + if (iWcdmaPageNumber <= cbsMsgTemp->Count()) + { + // Copy the pages + TRAPD( trapError, + for ( TUint8 i = 0; i < iWcdmaPageNumber; i++ ) + { + iCbsMsg->AppendL( cbsMsgTemp->At( i ) ); + } + ); + + if ( KErrNone == trapError ) + { + TFLOGSTRING2("TSY:CMmBroadcastTsy::CompleteReceiveMessageWcdmaCbs: %d pages received.",iWcdmaPageNumber); + // first page. index is 0 + iWcdmaCbsMsgPageIndex = 0; + + // currentpage is 1 at this state even if multipage cbs + iWcdmaCurrentPage = 1; + + RMobileBroadcastMessaging::TMobileBroadcastAttributesV2Pckg* + attrPckg = reinterpret_cast + < RMobileBroadcastMessaging:: + TMobileBroadcastAttributesV2Pckg* > + ( iReceiveCbMessageAttributesPtr ); + + RMobileBroadcastMessaging::TMobileBroadcastAttributesV2& + cbAttrib = ( *attrPckg )(); + + // The bit-mask flags indicating which attributes are present + // in this instance + cbAttrib.iFlags = + ( RMobileBroadcastMessaging::KBroadcastDataFormat ); + + // WCDMA + cbAttrib.iFormat = RMobileBroadcastMessaging::EFormatWcdmaTpdu; + + // Number of pages + cbAttrib.iNumberOfPages = ( *iCbsMsg )[iWcdmaCbsMsgPageIndex] + ->iNumberOfPages; + + TFLOGSTRING2("TSY:CMmBroadcastTsy::CompleteReceiveMessageWcdmaCbs: cbAttrib.iNumberOfPages %x .", cbAttrib.iNumberOfPages); + + // Message Type + cbAttrib.iMessageType = ( *iCbsMsg ) + [iWcdmaCbsMsgPageIndex]->iMessageType; + + // Message ID + cbAttrib.iMessageId = ( *iCbsMsg ) + [iWcdmaCbsMsgPageIndex]->iMessageId; + + // Serial Number + cbAttrib.iSerialNum = ( *iCbsMsg ) + [iWcdmaCbsMsgPageIndex]->iSerialNum; + + // data coding scheme + cbAttrib.iDCS = ( *iCbsMsg )[iWcdmaCbsMsgPageIndex]->iDCS; + + iReceiveCbMessagePtr->Copy( ( *iCbsMsg ) + [iWcdmaCbsMsgPageIndex]->iWcdmaCbsData ); + + + _LIT8(KFormat, "%c"); + + TFLOGSTRING2("TSY:CMmBroadcastTsy::CompleteReceiveMessageWcdmaCbs: 1st Page - AppendFormat in use iWcdmaCurrentPage: %d.", iWcdmaCurrentPage ); + // insert current pagenumber end of CBS message + iReceiveCbMessagePtr->AppendFormat(KFormat, iWcdmaCurrentPage); + + // index of the pages begins at 0 + if ( iWcdmaCbsMsgPageIndex == ( iWcdmaPageNumber -1 ) ) + { + // No page left to send to upper layer + iWcdmaCbsPageLeft = EFalse; + iWcdmaCbsMsgPageIndex = 0; + + // no pages left update current page + iWcdmaCurrentPage = 0; + + // Reset the array + iCbsMsg->Reset(); + } + else + { + // some pages are waiting to be send to upper layer + iWcdmaCbsPageLeft = ETrue; + // Increase by 1 the index of the pages + iWcdmaCbsMsgPageIndex++; + } + } + else + { + aError = trapError; + } + } + else + { + aError = KErrCorrupt; + } + } +TFLOGSTRING2("TSY:CMmBroadcastTsy::CompleteReceiveMessageWcdmaCbs:Completing with error=%d.", aError); + + ReqCompleted( reqHandle, aError ); + } + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::ReceiveMessageCancelL +// This method releases routing of CB messages, and +// cancels receiving of next incoming Broadcast Message +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TInt CMmBroadcastTsy::ReceiveMessageCancelL( + const TTsyReqHandle aTsyReqHandle ) + { + // Lets set this setting to null. Now TSY doesn't anymore try to send + // incoming CB message to the client. + iTsyReqHandleStore->ResetTsyReqHandle( + EMultimodeBroadcastReceiveMessage ); + + if ( iCbRoutingActivated ) + { +TFLOGSTRING("TSY:CMmBroadcastTsy::ReceiveMessageCancelL:Routing was active, sending de-activation request."); + // Create package + CMmDataPackage package; + + TCbsCbmiAndLangAndFilter data; + data.iSetting = RMobileBroadcastMessaging::EBroadcastAcceptNone; + data.iCbmiStorage = KNullDesC; // deprecated + data.iLanguageStorage = KNullDesC; // deprecated + + // Pack parameters + package.PackData( &data ); + + // Send request to the Domestic OS layer. + TInt ret = iMmPhone->MessageManager()->HandleRequestL( + EMobileBroadcastMessagingReceiveMessageCancel, &package ); + + if ( KErrNone == ret ) + { +#ifdef REQHANDLE_TIMER + SetTypeOfResponse( + EMultimodeBroadcastReceiveMessageCancel, aTsyReqHandle ); +#else + iTsyReqHandleStore->SetTsyReqHandle( + EMultimodeBroadcastReceiveMessageCancel, aTsyReqHandle ); +#endif // REQHANDLE_TIMER + } + else // DOS call returned error + { + // This setting must be set to false + iCbRoutingActivated = EFalse; + + // We have to complete this now, because Etel assumes that + // cancel-requests never fail and doesn't call again + // ReceiveMessage method (after canceling Etel crash if TSY try to + // deliver next incoming CB message to Etel). Failing of CB + // routing release request shouldn't be possible. + ReqCompleted( aTsyReqHandle, ret ); + } + } + else + { +TFLOGSTRING("TSY:CMmBroadcastTsy::ReceiveMessageCancelL:Routing was not active."); + ReqCompleted( aTsyReqHandle, KErrCancel ); + } + + return KErrNone; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::CompleteReceiveMessageCancel +// This method complete canceling of CB messages routing +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CMmBroadcastTsy::CompleteReceiveMessageCancel( + TInt aError ) + { +TFLOGSTRING2("TSY:CMmBroadcastTsy::CompleteReceiveMessageCancel:error=%d.",aError); + TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle( + EMultimodeBroadcastReceiveMessageCancel ); + + if ( reqHandle ) + { + // This setting must be set to false even if DOS returned error. + iCbRoutingActivated = EFalse; + + if ( KErrNone == aError ) + { + ReqCompleted( reqHandle, KErrCancel ); + } + else + { + ReqCompleted( reqHandle, aError ); + } + } + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::GetFilterSetting +// This method returns the current setting for the receipt of +// broadcast messages. And completes the request to the client +// using ReqCompleted +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TInt CMmBroadcastTsy::GetFilterSetting( + const TTsyReqHandle aTsyReqHandle, + RMobileBroadcastMessaging::TMobilePhoneBroadcastFilter* aSetting ) + { + *aSetting = iCbFilterSetting; +TFLOGSTRING2("TSY:CMmBroadcastTsy::GetFilterSetting:Filter setting=0x%x.",iCbFilterSetting); + + ReqCompleted( aTsyReqHandle, KErrNone ); + + return KErrNone; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::SetFilterSettingL +// This method returns the current setting for the receipt +// of broadcast messages +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TInt CMmBroadcastTsy::SetFilterSettingL( + const TTsyReqHandle aTsyReqHandle, + RMobileBroadcastMessaging::TMobilePhoneBroadcastFilter const* aSetting ) + { +TFLOGSTRING3("TSY:CMmBroadcastTsy::SetFilterSettingL:Old filter setting=0x%x, setting to 0x%x.",iCbFilterSetting,*aSetting); + if ( ( RMobileBroadcastMessaging::EBroadcastAcceptAll == *aSetting ) || + ( RMobileBroadcastMessaging::EBroadcastAcceptNone == *aSetting ) ) + { + // We can complete this after response from DOS + TTsyReqHandle reqHandle = iTsyReqHandleStore->GetTsyReqHandle( + EMultimodeBroadcastReceiveMessage ); + + if ( iCbRoutingActivated || + ( RMobileBroadcastMessaging::EBroadcastAcceptNone == + iCbFilterSetting && + reqHandle ) ) + { + iCbFilterTempSetting = *aSetting; + + // Create package + CMmDataPackage package; + + TCbsCbmiAndLangAndFilter data; + data.iSetting = iCbFilterTempSetting; + data.iCbmiStorage = KNullDesC; // deprecated + data.iLanguageStorage = KNullDesC; // deprecated + + // Pack parameters + package.PackData( &data ); + + // Lets make new routing request so new filter settings can be + // delivered to DOS + TInt ret = iMmPhone->MessageManager()->HandleRequestL( + EMobileBroadcastMessagingSetFilterSetting, &package ); + + if ( KErrNone == ret ) + { + iReqHandleType = EMultimodeBroadcastSetFilterSetting; + } + else + { + // DOS call failed + ReqCompleted( aTsyReqHandle, ret ); + } + } + else + { + iCbFilterSetting = *aSetting; + + // CB routing is not activated. We can complete this now. + CompleteNotifyFilterSettingChange(); + + // Using CompleteNotifyFilterSettingChange() causes iReqHandleType to be modified so that + // the object thinks it has been asked to perform a notification request, rather than a set request. + iReqHandleType = EMultimodeBroadcastReqHandleUnknown; + + ReqCompleted( aTsyReqHandle, KErrNone ); + } + } + else + { + ReqCompleted( aTsyReqHandle, KErrNotSupported ); + } + + return KErrNone; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::CompleteSetFilterSetting +// This method complete new filter setting sending +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CMmBroadcastTsy::CompleteSetFilterSetting( + TInt aError ) + { +TFLOGSTRING2("TSY:CMmBroadcastTsy::CompleteSetFilterSetting:error=%d.",aError); + TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle( + EMultimodeBroadcastSetFilterSetting ); + + if( reqHandle ) + { + if ( KErrNone == aError ) + { + iCbFilterSetting = iCbFilterTempSetting; + + if ( RMobileBroadcastMessaging::EBroadcastAcceptNone == + iCbFilterSetting ) + { + iCbRoutingActivated = EFalse; + } + else + { + iCbRoutingActivated = ETrue; + } + + CompleteNotifyFilterSettingChange(); + } + + if ( reqHandle ) + { + ReqCompleted( reqHandle, aError ); + } + + //complete the cancel request as well + CompleteReceiveMessageCancel( aError ); + } + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::NotifyFilterSettingChange +// This method allows a client to be notified if there is a +// change in the setting for the receipt of broadcast messages +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TInt CMmBroadcastTsy::NotifyFilterSettingChange( + RMobileBroadcastMessaging::TMobilePhoneBroadcastFilter* aSetting ) + { +TFLOGSTRING("TSY:CMmBroadcastTsy::NotifyFilterSettingChange."); + iReqHandleType = EMultimodeBroadcastNotifyFilterSetting; + iNotifyFilterSettingChangePtr = aSetting; + + return KErrNone; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::NotifyFilterSettingChangeCancel +// This method cancels an outstanding asynchronous +// NotifyFilterSettingChange request +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TInt CMmBroadcastTsy::NotifyFilterSettingChangeCancel( + const TTsyReqHandle aTsyReqHandle ) + { +TFLOGSTRING("TSY:CMmBroadcastTsy::NotifyFilterSettingChangeCancel."); + iTsyReqHandleStore->ResetTsyReqHandle( + EMultimodeBroadcastNotifyFilterSetting ); + ReqCompleted( aTsyReqHandle, KErrCancel ); + iNotifyFilterSettingChangePtr = NULL; // reset pointer to client memory + + return KErrNone; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::CompleteNotifyFilterSettingChange +// This method is called when some client change CB Filter Settings +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CMmBroadcastTsy::CompleteNotifyFilterSettingChange() + { +TFLOGSTRING("TSY:CMmBroadcastTsy::CompleteNotifyFilterSettingChange."); + TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle( + EMultimodeBroadcastNotifyFilterSetting ); + + if ( reqHandle ) + { + if ( iNotifyFilterSettingChangePtr ) + { + *iNotifyFilterSettingChangePtr = iCbFilterSetting; +TFLOGSTRING2("TSY:CMmBroadcastTsy::CompleteNotifyFilterSettingChange.New filter setting is 0x%x.",iCbFilterSetting); + } + + ReqCompleted( reqHandle, KErrNone ); + } + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::GetBroadcastIdListPhase1L +// CBMI list is returned to the client in two phases. First phase +// returns how many bytes the streamed list is +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TInt CMmBroadcastTsy::GetBroadcastIdListPhase1L( + const TTsyReqHandle , + CRetrieveMobilePhoneBroadcastIdList::TGetBroadcastIdRequest const* , + TInt* ) + { + // not supported. +TFLOGSTRING("TSY: CMmBroadcastTsy::GetBroadcastIdListPhase1L"); + return KErrNotSupported; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::GetBroadcastIdListPhase2 +// CBMI list is returned to the client in two phases. In second +// phase TSY writes the entries into CMobilePhoneCbmiList using +// the AddEntryL method +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TInt CMmBroadcastTsy::GetBroadcastIdListPhase2( + const TTsyReqHandle , + RMobilePhone::TClientId const* , + TDes8* ) + { + TFLOGSTRING("TSY:CMmBroadcastTsy::GetBroadcastIdListPhase2.List returned to client."); + return KErrNotSupported; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::StoreBroadcastIdListL +// This method may be used to store a new version of the entire +// list of CBMI entries +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TInt CMmBroadcastTsy::StoreBroadcastIdListL( + const TTsyReqHandle aTsyReqHandle, + TDes8 const* /*aBuffer*/ ) + { +TFLOGSTRING("TSY:CMmBroadcastTsy::StoreBroadcastIdListL."); + ReqCompleted( aTsyReqHandle, KErrNotSupported ); + + return KErrNone; + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::ResetVariables +// Reset used variables +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CMmBroadcastTsy::ResetVariables() + { + // Set accept all to the CB messages fiter setting + iCbFilterSetting = RMobileBroadcastMessaging::EBroadcastAcceptAll; + + // Set CB routing to unactivated + iCbRoutingActivated = EFalse; + + // Resets receive message variables + iReceiveCbMessagePtr = NULL; + iReceiveCbMessageAttributesPtr = NULL; + + // Reset CB notify variables + iNotifyFilterSettingChangePtr = NULL; + } + +#ifdef REQHANDLE_TIMER +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::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 CMmBroadcastTsy::SetTypeOfResponse( + const TInt aReqHandleType, + const TTsyReqHandle aTsyReqHandle ) + { + TInt timeOut( 0 ); + + // example switch + switch ( aReqHandleType ) + { + case EMultimodeBroadcastReceiveMessageCancel: + timeOut = KMmBroadcastReceiveMessageCancel; + break; + case EMultimodeBroadcastSetFilterSetting: + timeOut = KMmBroadcastSetFilter; + break; + // Must not use timer: + // case EMultimodeBroadcastReceiveMessage: + // case EMultimodeBroadcastNotifyFilterSetting: + 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 ); + } + } + +//---------------------------------------------------------------------------- +// CMmBroadcastTsy::Complete +// Completes the request due timer expiration +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CMmBroadcastTsy::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 + case EMultimodeBroadcastReceiveMessageCancel: + CompleteReceiveMessageCancel( aError ); + break; + case EMultimodeBroadcastSetFilterSetting: + CompleteSetFilterSetting( aError ); + break; + // Can't use timer: + // case EMultimodeBroadcastReceiveMessage: + // case EMultimodeBroadcastNotifyFilterSetting: + default: + ReqCompleted( iTsyReqHandleStore->ResetTsyReqHandle( + aReqHandleType ), aError ); + break; + } + } +#endif // REQHANDLE_TIMER + +// End of the file +