bearermanagement/S60MCPR/src/s60mcprstates.cpp
changeset 0 5a93021fdf25
child 1 40cb640ef159
equal deleted inserted replaced
-1:000000000000 0:5a93021fdf25
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: S60 MCPR states implementation
       
    15 *
       
    16 */
       
    17 
       
    18 /**
       
    19 @file s60mcprstates.cpp
       
    20 S60 MCPR states implementation
       
    21 */
       
    22 
       
    23 #include <cdblen.h>
       
    24 
       
    25 #include "s60mcprstates.h"
       
    26 
       
    27 using namespace S60MCprStates;
       
    28 using namespace ESock;
       
    29 using namespace Messages;
       
    30 using namespace MeshMachine;
       
    31 
       
    32 // -----------------------------------------------------------------------------
       
    33 // THandleMPMStatusChange::DoL
       
    34 // -----------------------------------------------------------------------------
       
    35 //
       
    36 DEFINE_SMELEMENT(THandleMPMStatusChange, NetStateMachine::MStateTransition, TContext)
       
    37 void THandleMPMStatusChange::DoL()
       
    38     {
       
    39     TCFControlProvider::TDataClientStatusChange& msg = 
       
    40         Messages::message_cast<TCFControlProvider::TDataClientStatusChange>(iContext.iMessage);
       
    41 
       
    42     // Get MCPR
       
    43     CS60MetaConnectionProvider& node = iContext.Node();
       
    44 
       
    45     // Get the policy server's selection result 
       
    46     TInt iapid = node.PolicyPrefs().IapId();
       
    47     
       
    48     if ( iapid == 0 )
       
    49         {
       
    50         // Filter zeros out.
       
    51         // We don't need information of IPCPR status, we only care real connections.
       
    52         }
       
    53     else if ( msg.iValue == TCFControlProvider::TDataClientStatusChange::EStarted && 
       
    54               node.RequestPermissionToSendStarted() )
       
    55         {
       
    56         S60MCPRLOGSTRING2("S60MCPR<%x>::THandleMPMStatusChange::DoL() calling IAPConnectionStartedL IAP %d",(TInt*)&iContext.Node(),iapid)
       
    57         // TODO use progress notification KLinkLayerOpen once Symbian provides them.
       
    58         node.Policy()->IAPConnectionStartedL( iapid );  // codescanner::leave
       
    59         
       
    60         /** HACK ALERT
       
    61         *
       
    62         * Due to regression in MOBILITY the EStartedFlag for serviceprovider is set here!
       
    63         * TODO Remove this hack whenever possible!!!
       
    64         */
       
    65         node.ServiceProvider()->SetFlags( TCFClientType::EStarted );       
       
    66         }
       
    67     else if ( msg.iValue == TCFControlProvider::TDataClientStatusChange::EStopped &&
       
    68               node.RequestPermissionToSendStopped() )
       
    69         {
       
    70         S60MCPRLOGSTRING2("S60MCPR<%x>::THandleMPMStatusChange::DoL() calling IAPConnectionStoppedL IAP %d",(TInt*)&iContext.Node(),iapid)
       
    71         // Send request.
       
    72         // The problem with IAPConnectionStoppedL() is that to MPM it means
       
    73         // that IAP has gone down but actually the provider has just left.
       
    74         // policy->IAPConnectionStoppedL( node.iIapId );
       
    75         // Hence we mimic the situtation that application leaves the connection.
       
    76         node.Policy()->ApplicationLeavesConnectionL( iapid );  // codescanner::leave
       
    77         node.Policy()->ApplicationConnectionEndsL();  // codescanner::leave
       
    78         }
       
    79     }
       
    80 
       
    81 // -----------------------------------------------------------------------------
       
    82 // TReselectBestIAP::DoL
       
    83 // -----------------------------------------------------------------------------
       
    84 //
       
    85 DEFINE_SMELEMENT(TReselectBestIAP, NetStateMachine::MStateTransition, TContext)
       
    86 void TReselectBestIAP::DoL()
       
    87     {
       
    88     S60MCPRLOGSTRING1("S60MCPR<%x>::TReselectBestIAP::DoL()",(TInt*)&iContext.Node())
       
    89     
       
    90     // Get MCPR
       
    91     CS60MetaConnectionProvider& node = (CS60MetaConnectionProvider&)iContext.Node();
       
    92 
       
    93     // Build up the PolicyRequest.
       
    94     TConnPref* polpref = (TConnPref*)new ( ELeave ) TPolicyConnPref();  // codescanner::leave
       
    95     CleanupStack::PushL( polpref );  // codescanner::leave
       
    96 
       
    97     CReselectBestIAPCb* cb = new( ELeave ) CReselectBestIAPCb( node, iContext.iNodeActivity );  // codescanner::leave
       
    98     CleanupStack::PushL( cb );  // codescanner::leave
       
    99 
       
   100     // Send request
       
   101     node.Policy()->ReselectIAPL( polpref, cb );  // codescanner::leave
       
   102 
       
   103     // Pop three objects.
       
   104     CleanupStack::Pop( cb );
       
   105     CleanupStack::Pop( polpref );
       
   106     // Pop pref and cb objects.
       
   107     }
       
   108 
       
   109 
       
   110 // -----------------------------------------------------------------------------
       
   111 // TRequestReConnect::DoL
       
   112 // -----------------------------------------------------------------------------
       
   113 //
       
   114 DEFINE_SMELEMENT( TRequestReConnect, NetStateMachine::MStateTransition, TContext )
       
   115 void TRequestReConnect::DoL() // codescanner::leave
       
   116     {
       
   117     __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KS60MCprPanic, KPanicNoActivity));
       
   118     S60MCPRLOGSTRING1("S60MCPR<%x>::TRequestReConnect::DoL()",(TInt*)&iContext.Node())
       
   119     // We have AP that will go down. 
       
   120     // And the other AP that will go up.
       
   121     RNodeInterface* stoppingSP = NULL;
       
   122     RNodeInterface* startingSP = NULL;
       
   123 
       
   124     // The one that will be started is the one MPM selected.
       
   125     // Both must be present in the MCPR -plane.
       
   126 
       
   127     // Choose Service Providers to work on
       
   128     TClientIter<TDefaultClientMatchPolicy> iter = 
       
   129         iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider));
       
   130 
       
   131     RNodeInterface* itf = NULL;
       
   132     for ( itf = iter++; ( itf != NULL && ( stoppingSP == NULL || startingSP == NULL ) ); itf = iter++ )
       
   133         {
       
   134         // Only one of the selected MCPRs can be EStarted.
       
   135         //
       
   136         if ( itf->Flags() & TCFClientType::EStarted )
       
   137             {
       
   138             stoppingSP = itf; //Our current started Service Provider.
       
   139             itf->ClearFlags( TCFClientType::EActive );
       
   140             }
       
   141         // The other which is not EStarted must be EActive.
       
   142         //
       
   143         else if ( itf->Flags() & TCFClientType::EActive )
       
   144             {
       
   145             startingSP = itf; //And the new one to try next
       
   146             }
       
   147         }
       
   148     // One must be started since this is already a reconnection
       
   149     if ( stoppingSP==NULL )
       
   150         { 
       
   151         // Indication of a serious problem.
       
   152         S60MCPRLOGSTRING1("S60MCPR<%x>::TRequestReConnect::DoL() - started service provider not found.",(TInt*)&iContext.Node())
       
   153         ASSERT( EFalse );
       
   154         User::Leave( KErrCorrupt );  // codescanner::leave
       
   155         }
       
   156 
       
   157     //Sanity check.
       
   158     //The new provider must not be started, there can be only one started at a time.
       
   159     ASSERT( startingSP == NULL || ( startingSP->Flags() & TCFClientType::EStarted ) == 0 );
       
   160 
       
   161     //If there is no other Service Provider to try, return KErrNotFound
       
   162     if ( startingSP == NULL )
       
   163         {
       
   164         S60MCPRLOGSTRING1("S60MCPR<%x>::TRequestReConnect::DoL() - no more choices, abandoning recovery.",(TInt*)&iContext.Node())
       
   165         User::Leave( KErrNotFound );  // codescanner::leave
       
   166         }
       
   167 
       
   168     //Diagnostinc - there must be a data client or we cannot be here
       
   169     __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)),
       
   170                    User::Panic(KS60MCprPanic, KPanicNoDataClient));
       
   171 
       
   172     iContext.iNodeActivity->PostRequestTo( iContext.NodeId(),
       
   173                                            TCFMcpr::TReConnect( stoppingSP->RecipientId(), 
       
   174                                                                 startingSP->RecipientId()).CRef() );
       
   175     }
       
   176 
       
   177 
       
   178 // -----------------------------------------------------------------------------
       
   179 // TProcessError::DoL
       
   180 // -----------------------------------------------------------------------------
       
   181 //
       
   182 DEFINE_SMELEMENT( TProcessError, NetStateMachine::MStateTransition, TContext )
       
   183 void TProcessError::DoL() // codescanner::leave
       
   184     {
       
   185     __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KS60MCprPanic, KPanicNoActivity));
       
   186     // Get the MCPR
       
   187     CS60MetaConnectionProvider& node = (CS60MetaConnectionProvider&)iContext.Node();
       
   188 
       
   189     TInt error( KErrNone );
       
   190 
       
   191     // Get the error from the message or from the activity.
       
   192     // Since this transition could be triggered from almost anywhere, 
       
   193     // give preference to current Message.
       
   194     if ( iContext.iMessage.IsMessage<Messages::TEBase::TError>() )
       
   195         {
       
   196         S60MCPRLOGSTRING1("S60MCPR<%x>::TProcessError::DoL() Using iMessage as error source",(TInt*)&iContext.Node())
       
   197         error = message_cast<TEBase::TError>(&iContext.iMessage)->iValue;
       
   198         }
       
   199     else
       
   200         {
       
   201         S60MCPRLOGSTRING1("S60MCPR<%x>::TProcessError::DoL() Using CS60ErrorRecoveryActivity as error source",(TInt*)&iContext.Node())
       
   202         // Get the activity.
       
   203         CS60ErrorRecoveryActivity& activity = 
       
   204             static_cast<CS60ErrorRecoveryActivity&>(*iContext.iNodeActivity);
       
   205         Messages::TErrContext err =  activity.iOriginalErrContext;
       
   206         error = err.iStateChange.iError;
       
   207         }
       
   208 
       
   209     ASSERT( error != KErrNone );
       
   210     
       
   211     // Create the callback that will eventually create the message that completes this state.
       
   212     CProcessErrorCb* cb = new( ELeave ) CProcessErrorCb( node, iContext.iNodeActivity );  // codescanner::leave
       
   213     CleanupStack::PushL( cb );  // codescanner::leave
       
   214     // We always need to ask MPM to handle the error.
       
   215     node.Policy()->ProcessErrorL( error, cb );  // codescanner::leave
       
   216     CleanupStack::Pop( cb );
       
   217     // After this we wait for cancellation/error/completion.
       
   218     }
       
   219 
       
   220 
       
   221 // -----------------------------------------------------------------------------
       
   222 // TAwaitingSelectNextLayerCompletedOrError::Accept
       
   223 // -----------------------------------------------------------------------------
       
   224 //
       
   225 DEFINE_SMELEMENT( TAwaitingSelectNextLayerCompletedOrError, NetStateMachine::MState, TContext )
       
   226 TBool TAwaitingSelectNextLayerCompletedOrError::Accept()
       
   227     {
       
   228     TEBase::TError* msg = message_cast<TEBase::TError>(&iContext.iMessage);
       
   229     if( msg )
       
   230         {
       
   231         S60MCPRLOGSTRING1("S60MCPR<%x>::TAwaitingSelectNextLayerCompletedOrError::Accept() TError",(TInt*)&iContext.Node())
       
   232         iContext.iNodeActivity->SetError(msg->iValue);
       
   233         return ETrue;
       
   234         }
       
   235     if (iContext.iMessage.IsMessage<TCFSelector::TSelectComplete>())
       
   236         {
       
   237         if (message_cast<TCFSelector::TSelectComplete>(iContext.iMessage).iNodeId.IsNull())
       
   238             {
       
   239             S60MCPRLOGSTRING1("S60MCPR<%x>::TAwaitingSelectNextLayerCompletedOrError::Accept() TSelectComplete",(TInt*)&iContext.Node())
       
   240             return ETrue;
       
   241             }
       
   242         //Consume any other TSelectComplete messages
       
   243         iContext.iMessage.ClearMessageId();
       
   244         }
       
   245     return EFalse;
       
   246     }
       
   247 
       
   248 
       
   249 
       
   250 // -----------------------------------------------------------------------------
       
   251 // TAwaitingReselectBestIAPCompleteOrError::Accept
       
   252 // -----------------------------------------------------------------------------
       
   253 //
       
   254 DEFINE_SMELEMENT( TAwaitingReselectBestIAPCompleteOrError, NetStateMachine::MState, TContext )
       
   255 TBool TAwaitingReselectBestIAPCompleteOrError::Accept()
       
   256     {
       
   257     if ( iContext.iMessage.IsMessage<TCFS60MCPRMessage::TMPMReselectBestIAPCompletedMsg>() )
       
   258         {
       
   259         S60MCPRLOGSTRING1("S60MCPR<%x>::TAwaitingReselectBestIAPCompleteOrError::Accept() TMPMReselectBestIAPCompletedMsg Accepted",(TInt*)&iContext.Node())
       
   260         
       
   261         // Reselect completed.
       
   262         return ETrue;
       
   263         }
       
   264     else if ( iContext.iMessage.IsMessage<Messages::TEBase::TError>() )
       
   265         {
       
   266         S60MCPRLOGSTRING1("S60MCPR<%x>::TAwaitingReselectBestIAPCompleteOrError::Accept() TError",(TInt*)&iContext.Node())
       
   267         // Some error possibly sent by the MPM. Must be handled by the activity.
       
   268         Messages::TEBase::TError* msg = message_cast<TEBase::TError>(&iContext.iMessage);
       
   269         iContext.iNodeActivity->SetError(msg->iValue);
       
   270         return ETrue;
       
   271         }
       
   272     else if ( iContext.iMessage.IsMessage<Messages::TEBase::TCancel>() )
       
   273         {
       
   274         // Cancellation from the RConnection::Start(). 
       
   275         // Cancel MPM asynch.
       
   276         S60MCPRLOGSTRING1("S60MCPR<%x>::TAwaitingReselectBestIAPCompleteOrError::Accept() NOT Accept TCancel, Cancelling ReselectBestIAPL()",(TInt*)&iContext.Node())
       
   277 
       
   278         // Get the MCPR
       
   279         CS60MetaConnectionProvider& node = (CS60MetaConnectionProvider&)iContext.Node();
       
   280         
       
   281         node.Policy()->CancelReselectBestIAP();
       
   282         
       
   283         return EFalse;
       
   284         }
       
   285     else
       
   286         {
       
   287         // else
       
   288         return EFalse;
       
   289         }
       
   290     }
       
   291 
       
   292 // -----------------------------------------------------------------------------
       
   293 // TAwaitingProcessErrorCompleteOrError::Accept
       
   294 // -----------------------------------------------------------------------------
       
   295 //
       
   296 DEFINE_SMELEMENT( TAwaitingProcessErrorCompleteOrError, NetStateMachine::MState, TContext )
       
   297 TBool TAwaitingProcessErrorCompleteOrError::Accept()
       
   298     {
       
   299     if ( iContext.iMessage.IsMessage<TCFS60MCPRMessage::TMPMProcessErrorCompletedMsg>() )
       
   300         {
       
   301         S60MCPRLOGSTRING1("S60MCPR<%x>::TAwaitingProcessErrorCompleteOrError::Accept() TMPMProcessErrorCompletedMsg or Error", (TInt*)&iContext.Node())
       
   302         // ProcessErrorComplete completed.
       
   303         return ETrue;
       
   304         }
       
   305     else if ( iContext.iMessage.IsMessage<TEBase::TError>() )
       
   306         {
       
   307         // Processing continue in error transition.
       
   308         TEBase::TError* msg = message_cast<TEBase::TError>( &iContext.iMessage );
       
   309         iContext.iNodeActivity->SetError( msg->iValue );
       
   310         S60MCPRLOGSTRING2("S60MCPR<%x>::TAwaitingProcessErrorCompleteOrError::Accept() Error %d", (TInt*)&iContext.Node(),msg->iValue)
       
   311         return ETrue;
       
   312         }
       
   313     else if ( iContext.iMessage.IsMessage<TEBase::TCancel>() )
       
   314         {
       
   315         // Get the MCPR
       
   316         CS60MetaConnectionProvider& node = (CS60MetaConnectionProvider&)iContext.Node();
       
   317 
       
   318         node.Policy()->CancelProcessError();
       
   319         // should this be the same as ignore?
       
   320         S60MCPRLOGSTRING1("S60MCPR<%x>::TAwaitingProcessErrorCompleteOrError::Accept() NOT Accepted TCancel Cancelling ProcessError", (TInt*)&iContext.Node())
       
   321         return EFalse;
       
   322         }
       
   323     else
       
   324         {
       
   325         return EFalse;
       
   326         }
       
   327     }
       
   328 
       
   329 // -----------------------------------------------------------------------------
       
   330 // TAwaitingServiceIdRequest::Accept
       
   331 // -----------------------------------------------------------------------------
       
   332 //
       
   333 DEFINE_SMELEMENT( TAwaitingServiceIdRequest, NetStateMachine::MState, TContext )
       
   334 TBool TAwaitingServiceIdRequest::Accept()
       
   335     {
       
   336     ESock::TMCprGetConnectionSetting* msg = NULL;
       
   337 
       
   338     S60MCPRLOGSTRING2("TAwaitingServiceIdRequest: iContext.iMessage( %x %x )", 
       
   339             iContext.iMessage.MessageId().MessageId(), 
       
   340             iContext.iMessage.MessageId().Realm());
       
   341     S60MCPRLOGSTRING2(" == ( %x %x )?\n", 
       
   342             ESock::TMCprGetConnectionSetting::EId, 
       
   343             ESock::TMCprGetConnectionSetting::ERealm);
       
   344 
       
   345     if ( iContext.iMessage.IsMessage<ESock::TMCprGetConnectionSetting>() )  
       
   346         {
       
   347         S60MCPRLOGSTRING1("S60MCPR<%x>::TAwaitingServiceIdRequest::Accept() TMCprGetConnectionSetting", 
       
   348             (TInt*)&iContext.Node())
       
   349         msg = message_cast<ESock::TMCprGetConnectionSetting>(&iContext.iMessage);
       
   350 
       
   351         // Get MCPR
       
   352         CS60MetaConnectionProvider& node = (CS60MetaConnectionProvider&)iContext.Node();
       
   353 
       
   354         // Only EIntSetting is supported 
       
   355         // 
       
   356         if ( ( TMCprGetConnectionSetting::TConnectionSettingType)msg->iSettingType == 
       
   357                TMCprGetConnectionSetting::EIntSetting
       
   358                && node.PolicyPrefs().ServiceId() != 0 )
       
   359             {
       
   360             S60MCPRLOGSTRING1("S60MCPR<%x>::TAwaitingServiceIdRequest::Accept() TMCprGetConnectionSetting EIntSetting", 
       
   361                 (TInt*)&iContext.Node())
       
   362             return ETrue;
       
   363             }
       
   364         else
       
   365             {
       
   366             S60MCPRLOGSTRING1("S60MCPR<%x>::TAwaitingServiceIdRequest::Accept() TMCprGetConnectionSetting not processing EIntSetting", 
       
   367                 (TInt*)&iContext.Node())
       
   368             return EFalse;
       
   369             }
       
   370         }
       
   371     else
       
   372         {
       
   373         return EFalse;
       
   374         }
       
   375     }
       
   376 
       
   377 // -----------------------------------------------------------------------------
       
   378 // TRetrieveServiceId::DoL
       
   379 // -----------------------------------------------------------------------------
       
   380 //
       
   381 DEFINE_SMELEMENT( TRetrieveServiceId, NetStateMachine::MStateTransition, TContext )
       
   382 void TRetrieveServiceId::DoL()
       
   383     {
       
   384     S60MCPRLOGSTRING1("S60MCPR<%x>::TRetrieveServiceId::DoL()", (TInt*)&iContext.Node())
       
   385 
       
   386     // Get MCPR
       
   387     CS60MetaConnectionProvider& node = (CS60MetaConnectionProvider&)iContext.Node();
       
   388 
       
   389     // Get the policy server's selection result 
       
   390     TUint32 serviceId = node.PolicyPrefs().ServiceId();
       
   391     S60MCPRLOGSTRING2("S60MCPR<%x>::TRetrieveServiceId::DoL() ServiceId = %d", 
       
   392             (TInt*)&iContext.Node(), serviceId )
       
   393 
       
   394     TPckg<TUint32> pckg( serviceId );
       
   395 
       
   396     S60MCPRLOGSTRING1("S60MCPR<%x>::TRetrieveServiceId::DoL() Write ServiceId to ResponseMsg", 
       
   397             (TInt*)&iContext.Node())
       
   398     TCFSigLegacyRMessage2Ext& msg = static_cast<TCFSigLegacyRMessage2Ext&>( iContext.iMessage );
       
   399     msg.iMessage.WriteL( 1, pckg ); // codescanner::leave
       
   400 
       
   401     S60MCPRLOGSTRING1("S60MCPR<%x>::TRetrieveServiceId::DoL() Complete ResponseMsg", 
       
   402             (TInt*)&iContext.Node())
       
   403     RLegacyResponseMsg responseMsg( iContext, msg.iMessage, msg.iMessage.Int0() );
       
   404     responseMsg.Complete( KErrNone );
       
   405     }
       
   406 
       
   407 // -----------------------------------------------------------------------------
       
   408 // CReselectBestIAPCb::PolicyResponse 
       
   409 // -----------------------------------------------------------------------------
       
   410 //
       
   411 void CReselectBestIAPCb::PolicyResponse( PolicyRequest& aCompletedRequest )
       
   412     {
       
   413     using namespace ESock;
       
   414     TPolicyConnPref* policypref = (TPolicyConnPref*)aCompletedRequest.iPolicyPref;
       
   415 
       
   416     // Request to MPM failed for some reason
       
   417     if( aCompletedRequest.iStatus != KErrNone )
       
   418         {
       
   419         S60MCPRLOGSTRING2("S60MCPR<%x>::CReselectBestIAPCb::PolicyResponse() MPM Error %d",(TInt*)&iNode,aCompletedRequest.iStatus)
       
   420         Messages::TEBase::TError msg( TCFS60MCPRMessage::TMPMReselectBestIAPCompletedMsg::Id(), 
       
   421                                       aCompletedRequest.iStatus );
       
   422         if ( iLastRequestOriginator.IsOpen() )
       
   423             {
       
   424             iLastRequestOriginator.ReplyTo( iNode.Id(), msg );
       
   425             iLastRequestOriginator.Close();
       
   426             }
       
   427         return;
       
   428         }
       
   429 
       
   430     S60MCPRLOGSTRING3("S60MCPR<%x>::CReselectBestIAPCb::PolicyResponse() IAP %d NET %d",
       
   431             (TInt*)&iNode,policypref->IapId(),policypref->NetId())
       
   432     
       
   433     iNode.SetPolicyPrefs( *policypref );
       
   434     
       
   435     TCFS60MCPRMessage::TMPMReselectBestIAPCompletedMsg msg;
       
   436     if ( iLastRequestOriginator.IsOpen() )
       
   437         {
       
   438         iLastRequestOriginator.ReplyTo( iNode.Id(), msg );
       
   439         iLastRequestOriginator.Close();
       
   440         }
       
   441     }
       
   442 
       
   443 // -----------------------------------------------------------------------------
       
   444 // CProcessErrorCb::PolicyResponse
       
   445 // -----------------------------------------------------------------------------
       
   446 //
       
   447 void CProcessErrorCb::PolicyResponse( PolicyRequest& aCompletedRequest )
       
   448     {
       
   449     S60MCPRLOGSTRING3("S60MCPR<%x>::CProcessErrorCb::PolicyResponse() status=%d action=%d",
       
   450               (TInt*)&iNode,aCompletedRequest.iStatus,(TInt)aCompletedRequest.iNeededAction)
       
   451     // Validate that we can send a response.
       
   452     //
       
   453     if ( !iLastRequestOriginator.IsOpen() )
       
   454         {
       
   455         // response can't be sent.
       
   456         return;
       
   457         }
       
   458     // Request ok and valid one
       
   459     //
       
   460     if ( aCompletedRequest.iStatus == KErrNone &&
       
   461          ( aCompletedRequest.iNeededAction == EIgnoreError ||
       
   462            aCompletedRequest.iNeededAction == EDoReselection ))
       
   463         {
       
   464         TCFS60MCPRMessage::TMPMProcessErrorCompletedMsg msg( (TInt)aCompletedRequest.iNeededAction );
       
   465         iLastRequestOriginator.ReplyTo( iNode.Id(), msg );
       
   466         iLastRequestOriginator.Close();
       
   467         }
       
   468     // Propagate error
       
   469     //
       
   470     else
       
   471         {
       
   472         // Initialize
       
   473         TInt err = aCompletedRequest.iStatus;
       
   474         if ( err == KErrNone )
       
   475             {
       
   476             ASSERT( aCompletedRequest.iError != KErrNone );
       
   477             err = aCompletedRequest.iError != KErrNone ? aCompletedRequest.iError : KErrGeneral;
       
   478             }
       
   479         TEBase::TError msg( TCFS60MCPRMessage::TMPMProcessErrorCompletedMsg::Id(), err );
       
   480         iLastRequestOriginator.ReplyTo( iNode.Id(), msg );
       
   481         iLastRequestOriginator.Close();
       
   482         }
       
   483     }
       
   484 
       
   485 //  End of File
       
   486