--- /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 <mmlist.h>
+#include <etelmm.h>
+#include "cmmbroadcasttsy.h"
+#include "cmmphonetsy.h"
+#include "CMmPrivateUtility.h" // Read all list class
+#include <ctsy/serviceapi/cmmsmsutility.h>
+#include "MmTsy_numberOfSlots.h"
+#include "cmmtsyreqhandlestore.h"
+#include <ctsy/pluginapi/cmmdatapackage.h>
+#include <ctsy/tflogger.h>
+#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
+