// Copyright (c) 2007-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 <etelqos.h>
#include <comms-infras/ss_metaconnprov.h>
#include <comms-infras/ss_nodeinterfaces.h>
#include <elements/nm_messages_errorrecovery.h>
#include <comms-infras/ss_mcprnodemessages.h>
#include "pdpmcpr.h"
#include "pdpmcprstates.h"
using namespace ESock;
using namespace NetStateMachine;
using namespace Messages;
namespace PdpMCprStates
{
}
namespace PdpMCprErrorRecoveryActivity
{
DEFINE_SMELEMENT(CPdpErrorRecoveryActivity::TAwaitingContentionResult, NetStateMachine::MState, PdpMCprStates::TContext)
TBool CPdpErrorRecoveryActivity::TAwaitingContentionResult::Accept()
{
TPDPMessages::TPdpContentionResultMessage* msg = message_cast<TPDPMessages::TPdpContentionResultMessage>(&iContext.iMessage);
CPdpErrorRecoveryActivity& activity = static_cast<CPdpErrorRecoveryActivity&>(*iContext.iNodeActivity);
if(msg && msg->iNodeId == activity.iPendingCprId)
{
return ETrue;
}
return EFalse;
}
DEFINE_SMELEMENT(CPdpErrorRecoveryActivity::TPdpContentionNoTagOrError, NetStateMachine::MStateFork, PdpMCprStates::TContext)
TInt CPdpErrorRecoveryActivity::TPdpContentionNoTagOrError::TransitionTag()
{
CPdpErrorRecoveryActivity& activity = static_cast<CPdpErrorRecoveryActivity&>(*iContext.iNodeActivity);
if (activity.iPendingCprId == Messages::TNodeId::NullId())
{
return MeshMachine::KErrorTag;
}
else
{
return MeshMachine::KNoTag;
}
}
DEFINE_SMELEMENT(CPdpErrorRecoveryActivity::TProcessErrorRecoveryReq, NetStateMachine::MStateTransition, PdpMCprStates::TContext)
void CPdpErrorRecoveryActivity::TProcessErrorRecoveryReq::DoL()
{
TEErrorRecovery::TErrorRecoveryRequest& req = message_cast<TEErrorRecovery::TErrorRecoveryRequest>(iContext.iMessage);
TInt error = req.iErrContext.iStateChange.iError;
#ifdef SYMBIAN_NETWORKING_CONTENTION_MANAGEMENT
if (req.iErrContext.iStateChange.iError == KErrUmtsMaxNumOfContextExceededByNetwork ||
req.iErrContext.iStateChange.iError == KErrUmtsMaxNumOfContextExceededByPhone)
{
// Get sender's priority
TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TCFClientType(TCFClientType::EData));
ESock::RCFNodePriorityInterface* dataClient;
TBool wasFound = EFalse;
TUint cprPriority = KMaxTUint;
while ((dataClient = static_cast<RCFNodePriorityInterface*>(iter++)) != NULL)
{
if (dataClient->RecipientId() == req.iErrContext.iOriginator)
{
cprPriority = dataClient->Priority();
wasFound = ETrue;
}
}
if (wasFound)
{
TInt err = KErrNone;
TBool result = EFalse;
TRAP(err, result = iContext.Node().GetTierManager()->HandleContentionL(&iContext.Node(), req.iErrContext.iOriginator, cprPriority));
if (err == KErrNone && result)
{
CPdpErrorRecoveryActivity& activity = static_cast<CPdpErrorRecoveryActivity&>(*iContext.iNodeActivity);
activity.iPendingCprId = req.iErrContext.iOriginator;
activity.iCprActivity = req.iErrContext.iActivitySigId;
activity.iCprMessageId = req.iErrContext.iMessageId;
activity.iErrorCode = error;
// The contention request has been added into query, Reset message error code.
// TErrResponse will be send from Mcpr's ContentionResolved function.
error = KErrNone;
}
}
}
#endif
if (error != KErrNone)
{
TErrResponse propagateResp(TErrResponse::EPropagate, error, req.iErrContext.iMessageId);
TEErrorRecovery::TErrorRecoveryResponse rawResp (propagateResp);
TCFSafeMessage::TResponseCarrierWest<TEErrorRecovery::TErrorRecoveryResponse> resp(rawResp, iContext.iSender);
iContext.PostToSender(resp);
}
}
DEFINE_SMELEMENT(CPdpErrorRecoveryActivity::TProcessContentionResult, NetStateMachine::MStateTransition, PdpMCprStates::TContext)
void CPdpErrorRecoveryActivity::TProcessContentionResult::DoL()
{
TPDPMessages::TPdpContentionResultMessage* msg = message_cast<TPDPMessages::TPdpContentionResultMessage>(&iContext.iMessage);
CPdpErrorRecoveryActivity& activity = static_cast<CPdpErrorRecoveryActivity&>(*iContext.iNodeActivity);
if (msg->iValue != 0)
{
TErrResponse retryResp(TErrResponse::ERetry, 0, activity.iCprMessageId);
TEErrorRecovery::TErrorRecoveryResponse rawResp (retryResp);
TCFSafeMessage::TResponseCarrierWest<TEErrorRecovery::TErrorRecoveryResponse> resp(rawResp, activity.iOriginators[0].RecipientId());
iContext.PostToSender(resp);
}
else
{
TErrResponse propagateResp(TErrResponse::EPropagate, activity.iErrorCode, activity.iCprMessageId);
TEErrorRecovery::TErrorRecoveryResponse rawResp (propagateResp);
TCFSafeMessage::TResponseCarrierWest<TEErrorRecovery::TErrorRecoveryResponse> resp(rawResp, activity.iOriginators[0].RecipientId());
iContext.PostToSender(resp);
}
}
}