--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bearermanagement/S60MCPR/src/s60mpmrequests.cpp Thu Dec 17 08:55:21 2009 +0200
@@ -0,0 +1,889 @@
+/*
+* Copyright (c) 2008-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: Handling of the MPM interface.
+ *
+*/
+
+
+/**
+ @file s60mpmrequests.cpp
+ Handling of the MPM interface.
+ */
+
+// Project includes
+#include "s60mpmrequests.h"
+#include "s60mcpr.h"
+#include "s60mpmnotifications.h"
+
+// Namespace
+using namespace S60MCPRMPMOperations;
+
+// ============================ MEMBER FUNCTIONS ===============================
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::NewL
+// -----------------------------------------------------------------------------
+//
+CMPMPolicyRequests* CMPMPolicyRequests::NewL( MMPMPolicyNotificationUser& aUser )
+ {
+ CMPMPolicyRequests* self = new ( ELeave ) CMPMPolicyRequests();
+ CleanupStack::PushL( self );
+ self->ConstructL( aUser );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::PolicyNotification
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::PolicyNotification( TMpmNotification& aNotification )
+ {
+ if ( !iCommitedToDeleteItself )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::PolicyNotification() forwarding call tocalling MCPR", this )
+ iPolicyNotificationsUser->PolicyNotification( aNotification );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::RequestDelete
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::RequestDelete()
+ {
+ iCommitedToDeleteItself = ETrue;
+ // Either we have pending requests
+ // (we always have at least notifications if we're connected.)
+ //
+ if ( iPolicyRequests.Count() > 0 )
+ {
+ S60MCPRLOGSTRING2( "S60MCPR::CMPMPolicyRequests<%x>::RequestDelete() %d pending requests, IssueRequest", this, iPolicyRequests.Count() )
+ IssueRequest();
+ }
+ // Or we are free to delete this.
+ //
+ else
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::RequestDelete() IssueDeleteRequest", this )
+ IssueDeleteRequest();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::CMPMPolicyRequests
+// -----------------------------------------------------------------------------
+//
+CMPMPolicyRequests::CMPMPolicyRequests() :
+ CActive( EPriorityStandard ),
+ iCommitedToDeleteItself( EFalse )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::CMPMPolicyRequests()", this )
+ CActiveScheduler::Add( this );
+ iConnId = (TConnectionId)this;
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::~CMPMPolicyRequests
+// -----------------------------------------------------------------------------
+//
+CMPMPolicyRequests::~CMPMPolicyRequests()
+ {
+ //LOG( ESockLog::Printf(KESockMetaConnectionTag, _L8("CMPMPolicyRequests<%x>::~CMPMPolicyRequests"), this ); )
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::~CMPMPolicyRequests()", this )
+
+ __ASSERT_ALWAYS(!IsActive(), User::Panic(KS60MCprPanic, KPanicInvalidCActiveUsage));
+ __ASSERT_DEBUG(iPolicyRequests.Count() == 0, User::Panic(KS60MCprPanic, KPanicInvalidCActiveUsage));
+
+ // Clean up all objects in the list
+ // Normally there shouldn't be any.
+ TInt count = iPolicyRequests.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ S60MCPRLOGSTRING2( "S60MCPR::CMPMPolicyRequests<%x>::~CMPMPolicyRequests() deleting request %d",
+ this, (TInt)iPolicyRequests[i].iRequestType )
+ // Delete prefs
+ delete iPolicyRequests[i].iConnPref;
+ delete iPolicyRequests[i].iPolicyPref;
+ // PolicyRequest owns this class and can delete it.
+ // MCPR must have cancelled its activity when this happens.
+ delete iPolicyRequests[i].iUser;
+ }
+
+ // Reset the array.
+ iPolicyRequests.Close();
+
+ // Close the MPM handle
+ if ( iMpm.Connected() )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::~CMPMPolicyRequests() closing MPM session", this )
+ iMpm.Close();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::ConstructL( MMPMPolicyNotificationUser& aUser )
+ {
+ // Force MPMNotifications to go through CMPMPolicyRequests
+ iPolicyNotificationsUser = &aUser;
+ iPolicyNotifications = CMPMPolicyNotifications::NewL( *(MMPMPolicyNotificationUser*)this,
+ iMpm );
+ S60MCPRLOGSTRING2( "S60MCPR::CMPMPolicyRequests<%x>::ConstructL() using iPolicyNotifications<%x>",
+ this, iPolicyNotifications )
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::IAPConnectionStartedL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::IAPConnectionStartedL( const TUint32 aIapId )
+ {
+ S60MCPRLOGSTRING2( "S60MCPR::CMPMPolicyRequests<%x>::IAPConnectionStartedL() IAP %d", this, aIapId )
+ CreatePolicyRequestL( EPolicyRequestIAPConnectionStarted, aIapId );
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::IAPConnectionStoppedL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::IAPConnectionStoppedL( const TUint32 aIapId )
+ {
+ S60MCPRLOGSTRING2( "S60MCPR::CMPMPolicyRequests<%x>::IAPConnectionStoppedL() IAP %d", this, aIapId )
+ CreatePolicyRequestL( EPolicyRequestIAPConnectionStopped, aIapId );
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::ApplicationJoinsConnectionL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::ApplicationJoinsConnectionL( const TUint32 aIapId )
+ {
+ // Can't use CreatePolicyRequest() here because this could
+ // be the first call to MPM.
+
+ PolicyRequest policydata = PolicyRequest();
+ policydata.iRequestType = EPolicyRequestApplicationJoinsConnection;
+ policydata.iConnId = iConnId;
+ policydata.iIapId = aIapId;
+
+ // Add request to array of uncompleted requests
+ iPolicyRequests.AppendL( policydata );
+
+ S60MCPRLOGSTRING2( "S60MCPR::CMPMPolicyRequests<%x>::ApplicationJoinsConnectionL() IAP %d", this, aIapId )
+
+ // Submit it.
+ IssueRequest();
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::ApplicationLeavesConnectionL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::ApplicationLeavesConnectionL( const TUint32 aIapId )
+ {
+ S60MCPRLOGSTRING2( "S60MCPR::CMPMPolicyRequests<%x>::ApplicationLeavesConnectionL() IAP %d", this, aIapId )
+ CreatePolicyRequestL( EPolicyRequestApplicationLeavesConnection, aIapId );
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::ApplicationLeavesConnectionL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::ApplicationConnectionEndsL()
+ {
+ // This is only a notification. Thus, if the session doesn't exist, don't create one
+ if ( !iMpm.Connected() )
+ {
+ return;
+ }
+
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::ApplicationConnectionEndsL() IAP %d", this )
+
+ PolicyRequest policydata = PolicyRequest();
+ policydata.iRequestType = EPolicyRequestApplicationConnectionEnds;
+ policydata.iConnId = iConnId;
+// policydata.iIapId = aIapId;
+ // Nothing to cleanup so it's ok to Leave in AppendL
+
+ // Add request to array of uncompleted requests
+ iPolicyRequests.AppendL( policydata );
+
+ // Submit it.
+ IssueRequest();
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::RegisterPreferredIAPNotificationL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::RegisterPreferredIAPNotificationL()
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::RegisterPreferredIAPNotificationL()", this )
+
+ PolicyRequest policydata = PolicyRequest();
+
+ policydata.iRequestType = EPolicyRequestRegisterPrefIAPNotif;
+ policydata.iConnId = iConnId;
+
+ // Add request to array of uncompleted requests
+ iPolicyRequests.AppendL( policydata );
+
+ // Submit it.
+ IssueRequest();
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::UnregisterPreferredIAPNotificationL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::UnregisterPreferredIAPNotificationL()
+ {
+ // Sanity check that we're still in business.
+ if ( !iMpm.Connected() )
+ {
+ return;
+ }
+
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::UnregisterPreferredIAPNotificationL()", this )
+
+ PolicyRequest policydata = PolicyRequest();
+
+ policydata.iRequestType = EPolicyRequestUnregisterPrefIAPNotif;
+ policydata.iConnId = iConnId;
+
+ // Add request to array of uncompleted requests
+ iPolicyRequests.AppendL( policydata );
+
+ // Submit it.
+ IssueRequest();
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::ApplicationIgnoredTheCarrierL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::ApplicationIgnoredTheCarrierL( const TUint32 aIapId )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::ApplicationIgnoredTheCarrierL()", this )
+ CreatePolicyRequestL( EPolicyRequestApplicationIgnoredTheCarrier, aIapId );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::ApplicationMigratesToCarrierL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::ApplicationMigratesToCarrierL( const TUint32 aIapId )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::ApplicationMigratesToCarrierL()", this )
+ CreatePolicyRequestL( EPolicyRequestApplicationMigratesToCarrier, aIapId );
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::ApplicationRejectedTheCarrierL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::ApplicationRejectedTheCarrierL( const TUint32 aIapId )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::ApplicationRejectedTheCarrierL()", this )
+ CreatePolicyRequestL( EPolicyRequestApplicationRejectedTheCarrier, aIapId );
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::ApplicationAcceptedTheCarrierL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::ApplicationAcceptedTheCarrierL( const TUint32 aIapId)
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::ApplicationAcceptedTheCarrierL()", this )
+ CreatePolicyRequestL( EPolicyRequestApplicationAcceptedTheCarrier, aIapId );
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::ChooseBestIAP
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::ChooseBestIAPL( TConnPref* aConnPref,
+ const TUid& aAppUid,
+ TConnPref* aPolicyPref,
+ MMPMPolicyRequestsUser* aUser )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::ChooseBestIAPL()", this )
+
+ // Define policydata
+ PolicyRequest policydata = PolicyRequest();
+ policydata.iRequestType = EPolicyRequestChooseBestIAP;
+ policydata.iConnId = iConnId;
+ policydata.iAppUid = aAppUid;
+
+ // Heap allocated objects
+ policydata.iConnPref = aConnPref;
+ policydata.iPolicyPref = aPolicyPref;
+ policydata.iUser = aUser;
+
+ // Nothing to cleanup so it's ok to Leave in AppendL
+ // Heap allocated objects are on callers responsibility if we Leave.
+
+ // Add it to the array of uncompleted requests
+ iPolicyRequests.AppendL( policydata );
+
+ IssueRequest();
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::CancelReselectBestIAP()
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::CancelReselectBestIAP()
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::CancelReselectBestIAPL()", this )
+ ASSERT( iPolicyRequests.Count() > 0 );
+ CancelRequest( EMPMReselectBestIAP );
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::CancelChooseBestIAPL()
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::CancelChooseBestIAPL()
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::CancelChooseBestIAPL()", this )
+ ASSERT( iPolicyRequests.Count() > 0 );
+ CancelRequest( EMPMChooseBestIAP );
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::CancelProcessError()
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::CancelProcessError()
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::CancelProcessErrorL()", this )
+ ASSERT( iPolicyRequests.Count() > 0 );
+ CancelRequest( EMPMProcessError );
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::ReselectIAPL()
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::ReselectIAPL( TConnPref* aPolicyPref,
+ MMPMPolicyRequestsUser* aUser )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::ReselectIAPL()", this )
+ //Call MPM to get the list of potential IAPs for the connection
+ //
+ PolicyRequest policydata = PolicyRequest();
+
+ policydata.iRequestType = EPolicyRequestReselectBestIAP;
+ policydata.iConnId = iConnId;
+ policydata.iPolicyPref = aPolicyPref;
+ policydata.iUser = aUser;
+
+ // Add it to the array of uncompleted requests
+ iPolicyRequests.AppendL( policydata );
+
+ IssueRequest();
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::ProcessErrorL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::ProcessErrorL( TInt& anError,
+ MMPMPolicyRequestsUser* aUser )
+ {
+ S60MCPRLOGSTRING2( "S60MCPR::CMPMPolicyRequests<%x>::ProcessErrorL() %d", this, anError )
+
+ // insert into array of pending policy request
+ PolicyRequest policydata = PolicyRequest();
+
+ policydata.iRequestType = EPolicyRequestProcessError;
+ policydata.iError = anError;
+ policydata.iConnId = iConnId;
+ policydata.iUser = aUser;
+
+ // Add it to the array of uncompleted requests
+ iPolicyRequests.AppendL( policydata );
+
+ IssueRequest();
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::IssueDeleteRequest
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::IssueDeleteRequest()
+ {
+ ASSERT( !IsActive() );
+ // Always cancel & delete policynotifications.
+ if ( iMpm.Connected() && iPolicyNotifications->IsActive() )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::IssueDeleteRequest() Asynch", this )
+ iPolicyNotifications->CancelRequestAndDestroyD( &iStatus );
+ iPolicyNotifications = NULL;
+ SetActive();
+ }
+ else if ( iPolicyNotifications )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::IssueDeleteRequest() Immediate", this )
+ iPolicyNotifications->CancelRequestAndDestroyD();
+ iPolicyNotifications = NULL;
+ delete this;
+ }
+ else
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::IssueDeleteRequest() Invalid state", this )
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::IssueRequest
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::IssueRequest()
+ {
+ //__ASSERT_ALWAYS(IsActive() || iPolicyRequests.Count() > 0,User::Panic(KNetMCprPanic, KPanicInvalidCActiveUsage));
+
+ // If we have a pending request, back off.
+ //
+ if ( IsActive() || iPolicyRequests.Count() == 0 )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::IssueRequest() Unnecessary call, back off", this )
+ return;
+ }
+
+ if ( !iMpm.Connected() )
+ {
+ PolicyRequest policydata = PolicyRequest();
+ policydata.iRequestType = EPolicyRequestConnect;
+ // OK because default granularity is 8 and this is done when first request arrives.
+ iPolicyRequests.Insert(policydata, 0);
+ }
+
+ S60MCPRLOGSTRING2( "S60MCPR::CMPMPolicyRequests<%x>::IssueRequest() iRequestType %d", this, (TInt)iPolicyRequests[0].iRequestType )
+ //
+ // else we submit a new one.
+ switch ( iPolicyRequests[0].iRequestType )
+ {
+ case EPolicyRequestConnect:
+ {
+ iMpm.Connect( iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestChooseBestIAP:
+ {
+ //LOG(ESockLog::Printf(KESockMetaConnectionTag, _L8("\tcall MPM ChooseBestIAP")));
+ iMpm.ChooseBestIAP( ( *iPolicyRequests[0].iConnPref ),
+ iPolicyRequests[0].iConnId,
+ iPolicyRequests[0].iAppUid,
+ ( *iPolicyRequests[0].iPolicyPref ),
+ iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestReselectBestIAP:
+ {
+ iMpm.ReselectBestIAP( iPolicyRequests[0].iConnId,
+ ( *iPolicyRequests[0].iPolicyPref ),
+ iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestIAPConnectionStarted:
+ {
+ iMpm.IAPConnectionStarted( iPolicyRequests[0].iIapId,
+ iPolicyRequests[0].iConnId,
+ iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestIAPConnectionStopped:
+ {
+ iMpm.IAPConnectionStopped( iPolicyRequests[0].iIapId,
+ iPolicyRequests[0].iConnId,
+ iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestApplicationJoinsConnection:
+ {
+ iMpm.ApplicationJoinsConnection( iPolicyRequests[0].iIapId,
+ iPolicyRequests[0].iConnId,
+ iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestApplicationLeavesConnection:
+ {
+ iMpm.ApplicationLeavesConnection( iPolicyRequests[0].iIapId,
+ iPolicyRequests[0].iConnId,
+ iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestApplicationConnectionEnds:
+ {
+ iMpm.ApplicationConnectionEnds( iPolicyRequests[0].iConnId,
+ iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestRegisterPrefIAPNotif:
+ {
+ iMpm.RegisterPrefIAPNotif( iPolicyRequests[0].iConnId,
+ iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestUnregisterPrefIAPNotif:
+ {
+ iMpm.UnregisterPrefIAPNotif( iPolicyRequests[0].iConnId,
+ iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestApplicationIgnoredTheCarrier:
+ {
+ iMpm.ApplicationIgnoredTheCarrier( iPolicyRequests[0].iIapId,
+ iPolicyRequests[0].iConnId,
+ iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestApplicationMigratesToCarrier:
+ {
+ iMpm.ApplicationMigratesToCarrier( iPolicyRequests[0].iIapId,
+ iPolicyRequests[0].iConnId,
+ iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestApplicationRejectedTheCarrier:
+ {
+ iMpm.ApplicationRejectedTheCarrier( iPolicyRequests[0].iIapId,
+ iPolicyRequests[0].iConnId,
+ iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestApplicationAcceptedTheCarrier:
+ {
+ iMpm.ApplicationAcceptedTheCarrier( iPolicyRequests[0].iIapId,
+ iPolicyRequests[0].iConnId,
+ iStatus );
+ SetActive();
+ break;
+ }
+ case EPolicyRequestProcessError:
+ {
+ //LOG(ESockLog::Printf(KESockMetaConnectionTag, _L8("\tcall MPM ProcessError")));
+ iMpm.ProcessError( iPolicyRequests[0].iError,
+ iPolicyRequests[0].iConnId,
+ iPolicyRequests[0].iNeededAction,
+ iStatus );
+ SetActive();
+ break;
+ }
+ default:
+ {
+#ifdef _DEBUG
+ // In debug builds, panic
+ _LIT( KPanicMsg, "CMPMPolicyRequests::IssueRequestL: Invalid case" );
+ User::Panic( KPanicMsg, KErrNotSupported );
+#endif
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::RunL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::RunL()
+ {
+ S60MCPRLOGSTRING2( "S60MCPR::CMPMPolicyRequests<%x>::RunL() iStatus %d", this, iStatus.Int() )
+
+ // If there's a request waiting and is now completed
+ //
+ if ( iPolicyRequests.Count() > 0 && !iCommitedToDeleteItself)
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::RunL() Standard processing", this )
+ PolicyRequest& policydata = iPolicyRequests[0];
+ // Process the response
+ //
+ switch ( policydata.iRequestType )
+ {
+ case EPolicyRequestConnect:
+ {
+ if ( iStatus.Int() != KErrNone )
+ {
+ //-jl- MPM connection failed, set MPM connection required again.
+ iMpm.Close();
+ //-jl- Go to RunError
+ User::Leave( iStatus.Int() );
+ }
+ else
+ {
+ // Otherwise MPM ok and start listening for notifications
+ iPolicyNotifications->Activate();
+ }
+ break;
+ }
+ case EPolicyRequestProcessError:
+ case EPolicyRequestChooseBestIAP:
+ case EPolicyRequestReselectBestIAP:
+ {
+ if ( policydata.iUser )
+ {
+ // ChooseBest IAP is completed by iUser.
+ //
+ policydata.iStatus = iStatus.Int();
+ policydata.iUser->PolicyResponse( policydata );
+ }
+ break;
+ }
+ // With these messages we ignore the result.
+ case EPolicyRequestRegisterPrefIAPNotif:
+ case EPolicyRequestUnregisterPrefIAPNotif:
+ case EPolicyRequestApplicationIgnoredTheCarrier:
+ case EPolicyRequestApplicationMigratesToCarrier:
+ case EPolicyRequestApplicationRejectedTheCarrier:
+ case EPolicyRequestApplicationAcceptedTheCarrier:
+ case EPolicyRequestIAPConnectionStarted:
+ case EPolicyRequestIAPConnectionStopped:
+ case EPolicyRequestApplicationJoinsConnection:
+ case EPolicyRequestApplicationLeavesConnection:
+ case EPolicyRequestApplicationConnectionEnds:
+ {
+#ifdef _DEBUG
+ if ( iStatus.Int() != KErrNone )
+ {
+ S60MCPRLOGSTRING3( "S60MCPR::CMPMPolicyRequests<%x>::RunL() Request %d failed %d",
+ this, (TInt) policydata.iRequestType, iStatus.Int() )
+ }
+#endif // _DEBUG
+ break;
+ }
+ default:
+ {
+#ifdef _DEBUG
+ // In debug builds, panic
+ _LIT( KPanicMsg, "CMPMPolicyRequests::RunL: Invalid case" );
+ User::Panic( KPanicMsg, KErrNotSupported );
+#endif
+ break;
+ }
+ }
+ // Then cleanup
+ //
+ policydata.Cleanup();
+ iPolicyRequests.Remove( 0 ); // remove request from the array
+ // And if there are still pending request, cotinue with the next one
+ //
+ if ( iPolicyRequests.Count() > 0 )
+ {
+ IssueRequest();
+ }
+ }
+ // We have pending requests but we have commited to delete itself
+ //
+ else if ( iPolicyRequests.Count() > 0 && iCommitedToDeleteItself )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::RunL() Processing pending requests before delete", this )
+ // Submit pending requests to keep MPM in consistent state.
+ // First cleanup the old one
+ //
+ iPolicyRequests[0].Cleanup();
+ iPolicyRequests.Remove( 0 ); // remove request from the array
+ // And if there are still pending request, cotinue with the next one
+ //
+ if ( iPolicyRequests.Count() > 0 )
+ {
+ IssueRequest();
+ }
+ // In this case we've processed everything and can close.
+ //
+ else
+ {
+ IssueDeleteRequest();
+ }
+ }
+ else if ( iPolicyRequests.Count() == 0 && iCommitedToDeleteItself )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::RunL() About to delete itself", this )
+ ASSERT( !iPolicyNotifications );
+ delete this;
+ }
+ else
+ {
+ // INVALID STATE
+#ifdef _DEBUG
+ // In debug builds, panic
+ _LIT( KPanicMsg, "CMPMPolicyRequests::RunL: Invalid state" );
+ User::Panic( KPanicMsg, KErrNotSupported );
+#endif
+ // Even still, make sure we don't leak memory
+ //
+ iPolicyNotifications->CancelRequestAndDestroyD();
+ iPolicyNotifications = NULL;
+ delete this;
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::DoCancel
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::DoCancel()
+ {
+ // Not allowed! Cancel() may cause deadlock!
+ _LIT( KPanicMsg, "CMPMPolicyRequests::DoCancel" );
+ User::Panic( KPanicMsg, KErrNotSupported );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::RunError
+// -----------------------------------------------------------------------------
+//
+TInt CMPMPolicyRequests::RunError( TInt aError )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::RunError()", this )
+ // Connect has failed, cleanup and deliver errors
+ TInt count = iPolicyRequests.Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( iPolicyRequests[i].iUser )
+ {
+ S60MCPRLOGSTRING2( "S60MCPR::CMPMPolicyRequests<%x>::RunError() Sending error %d in PolicyResponse", this, aError )
+ iPolicyRequests[i].iStatus = aError;
+ iPolicyRequests[i].iUser->PolicyResponse( iPolicyRequests[i] );
+ }
+
+ // Delete prefs
+ iPolicyRequests[i].Cleanup();
+ }
+ iPolicyRequests.Reset();
+
+ return KErrNone;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::CancelRequest
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::CancelRequest( TMpmAsynchCodes aRequestCode )
+ {
+ // Semantics of asynchronous cancellations:
+ //
+ // The biggest difference is that asynchronous cancellation will
+ // cause RunL() -call for original request. Because of this the
+ // PolicyResponse() calls must be prevented.
+ //
+ // Asynch Cancellation cannot be queued along with the other requests.
+ // Precondition for cancellation call to MPM is that there's an active request
+ // and that request code matches to the given parameter.
+ //
+ // Cancellation of the unsent requests is simple. Just remove it from the queue.
+ //
+ // Asynchronous cancellation adds message to MPMServer's IPC queue but since we
+ // queue all requests we can safely always call the SendCancelRequest()
+
+ // If the cancelled request is the active one.
+ //
+ S60MCPRLOGSTRING2( "S60MCPR::CMPMPolicyRequests<%x>::CancelRequest() %d", this, (TInt)aRequestCode )
+ if ( iPolicyRequests[0].iRequestType == aRequestCode )
+ {
+ // Cancel the query if active
+ //
+ if ( IsActive() )
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::CancelRequest() Cancelling active request", this )
+#ifdef _DEBUG
+ TInt ret = iMpm.SendCancelRequest( aRequestCode );
+#else
+ iMpm.SendCancelRequest( aRequestCode );
+#endif
+ __ASSERT_DEBUG( ret == KErrNone, User::Panic( KS60MCprPanic, ret ) );
+ // Prevent the callback.
+ iPolicyRequests[0].Cancel();
+ }
+ // Completed or not started. Just remove the request.
+ //
+ else
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::CancelRequest() Cancelling non-active request", this )
+ iPolicyRequests[0].Cleanup();
+ // remove it.
+ iPolicyRequests.Remove(0);
+ }
+ }
+ // Else we need to find it from the queue
+ //
+ else
+ {
+ S60MCPRLOGSTRING1( "S60MCPR::CMPMPolicyRequests<%x>::CancelRequest() Cancelling pending request", this )
+ TInt count = iPolicyRequests.Count();
+ for (TInt i = 1; i < count; i++)
+ {
+ if ( iPolicyRequests[i].iRequestType == aRequestCode )
+ {
+ // Cancellable request found, clean it up
+ iPolicyRequests[i].Cleanup();
+ // remove it.
+ iPolicyRequests.Remove(i);
+ break; // first occurence is enough.
+ }
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMPMPolicyRequests::CreatePolicyRequestL
+// -----------------------------------------------------------------------------
+//
+void CMPMPolicyRequests::CreatePolicyRequestL( TPolicyServerOperations aRequestCode,
+ const TUint32& aIapId )
+ {
+ // Sanity check that we're still in business.
+ if ( !iMpm.Connected() )
+ {
+ return;
+ }
+
+ PolicyRequest policydata = PolicyRequest();
+
+ policydata.iRequestType = aRequestCode;
+ policydata.iConnId = iConnId;
+ policydata.iIapId = aIapId;
+
+ // Add request to array of uncompleted requests
+ iPolicyRequests.AppendL( policydata );
+
+ // Submit it.
+ IssueRequest();
+ }
+
+
+// End of file