realtimenetprots/rtp/cfrtp/src/rtpscpr.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:03:15 +0200
changeset 0 307788aac0a8
permissions -rw-r--r--
Revision: 201003 Kit: 201005

// 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:
// RTP SubConnection Provider implementation
// 
//

/**
 @file
 @internalComponent
*/


#include <comms-infras/ss_log.h>
#include <comms-infras/ss_nodemessages_factory.h>
#include "rtp_cfmessages.h"
#include "rtpscpr.h"
#include "rtpscprstates.h"



using namespace ESock;
using namespace NetStateMachine;
using namespace Messages;
using namespace MeshMachine;

namespace RTPSCprParamsRequest
{
#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
DECLARE_DEFINE_NODEACTIVITY(ECFActivityParamRequest, RTPSCprSetParams, TCFScpr::TSetParamsRequest)
	FIRST_NODEACTIVITY_ENTRY(PRStates::TAwaitingParamRequest, CoreNetStates::TNoTagOrBearerPresent)
	NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TPassToServiceProvider, CoreNetStates::TAwaitingParamResponse, CoreNetStates::TBearerPresent)
	LAST_NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TStoreParamsAndPostToOriginators)
	LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TStoreAndRespondWithCurrentParams)
NODEACTIVITY_END()
#else
DECLARE_DEFINE_NODEACTIVITY(ECFActivityParamRequest, RTPSCprSetParams, TCFScpr::TParamsRequest)
	FIRST_NODEACTIVITY_ENTRY(SCprStates::TAwaitingParamRequest, CoreNetStates::TNoTagOrBearerPresent)
	NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, SCprStates::TPassToServiceProvider, CoreNetStates::TAwaitingParamResponse, CoreNetStates::TBearerPresent)
	LAST_NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, SCprStates::TStoreParamsAndPostToOriginators)
	LAST_NODEACTIVITY_ENTRY(KNoTag, SCprStates::TStoreAndRespondWithCurrentParams)
NODEACTIVITY_END()
#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
}


//This will check if the scpr is of type RTP and then branch
//If RTP, it will send commsbinder request to IPCPR to make the deftIP SCPR its service provider
//If IPSCPR ( normal case ), it will send commsbinder to its servicwe provider
namespace RTPSCprNoBearerActivity
{
DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityNoBearer, RTPSCprNoBearer, TCFControlProvider::TNoBearer, PRActivities::CNoBearer::NewL)
	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingNoBearer, CoreNetStates::TNoTagOrBearerPresent)
	
	NODEACTIVITY_ENTRY(KNoTag, RtpSCprStates::TSendCommsBinderToCntrlProv, CoreNetStates::TAwaitingBinderResponse, MeshMachine::TNoTag)
	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendControlClientJoinRequest, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag)
	THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreActivities::ABindingActivity::TSendBindToComplete, MeshMachine::TNoTag)
	
	NODEACTIVITY_ENTRY(KNoTag, RtpSCprStates::TRequestCommsBinderRetry, CoreNetStates::TAwaitingBinderResponse, MeshMachine::TNoTag)
	NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, RtpSCprStates::TRequestCommsBinderRetry, CoreNetStates::TAwaitingBinderResponse, MeshMachine::TNoTag)
	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendBindTo, CoreNetStates::TAwaitingBindToComplete, MeshMachine::TNoTag)
	THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreActivities::ABindingActivity::TSendBindToComplete, PRActivities::CNoBearer::TNoTagOrDataClientsToStart)

	//Flow asking for a bearer needs to be started (provided KErrNone)
	NODEACTIVITY_ENTRY(CoreNetStates::KDataClientsToStart, PRActivities::CNoBearer::TStartOriginatingDataClient, CoreNetStates::TAwaitingDataClientStarted, MeshMachine::TNoTag)
		
	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
		
NODEACTIVITY_END()
}


// The activity will wait for ProvisionDone message from the flow. This will prevent the flow hanging in air with out a bearer while the 
// socket is writing data to it. Now there is a case where in flow couldnot bind to the SP also the NoBearer which the flow sends maynot 
// be completed. Unfortunately this activity has no way of knowing that the NoBearer sent by the flow has failed. The ProvisionDone message 
// has a response code which will give an indication as to whether the flow is ready to accept a BindTo from above.
namespace RTPSCprBinderRequestActivity
{
DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityBinderRequest, RTPSCprBinderRequest, ESock::TCFServiceProvider::TCommsBinderRequest, PRActivities::CCommsBinderActivity::NewL)
	FIRST_NODEACTIVITY_ENTRY(RtpSCprStates::TAwaitingBinderRequest, PRActivities::CCommsBinderActivity::TNoTagOrUseExistingBlockedByBinderRequest)
	NODEACTIVITY_ENTRY(KNoTag, RtpSCprStates::TCreateDataClient, CoreNetStates::TAwaitingDataClientJoin, MeshMachine::TNoTag)

	THROUGH_NODEACTIVITY_ENTRY(KNoTag, PRActivities::CCommsBinderActivity::TProcessDataClientCreation, MeshMachine::TTag<CoreStates::KUseExisting>) 
	NODEACTIVITY_ENTRY(CoreStates::KUseExisting, RtpSCprStates::TSetPostedToFlow, RtpSCprStates::TAwaitingReadyForBind, RtpSCprStates::TNoTagOrErrorTag)
	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TRaiseAndClearActivityError)
	// Below this point we need to modify the error handling approach. If we're getting a TError on TBinderResponse,
	// this means the client requesting the binder couldn't bind to it. As far as the client is concerned, this
	// activity is finished (it has flagged an error). The standard error handling will result in erroring
	// the originator. In this case we shouldn't error the originator, instead, wrap up quietly.
	NODEACTIVITY_ENTRY(KNoTag, PRActivities::CCommsBinderActivity::TSendBinderResponse, PRActivities::CCommsBinderActivity::TAwaitingBindToComplete, MeshMachine::TNoTagOrErrorTag)
	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TClearError)
NODEACTIVITY_END()
}


namespace RTPSCprActivities
{
DECLARE_DEFINE_ACTIVITY_MAP(activityMap)
    ACTIVITY_MAP_ENTRY(RTPSCprParamsRequest, RTPSCprSetParams)
	ACTIVITY_MAP_ENTRY(RTPSCprNoBearerActivity, RTPSCprNoBearer)
	ACTIVITY_MAP_ENTRY(RTPSCprBinderRequestActivity, RTPSCprBinderRequest)
ACTIVITY_MAP_END_BASE(SCprActivities, coreSCprActivities)
}
//-=========================================================
//
// CRtpSubConnectionProvider methods
//
//-=========================================================	
CRtpSubConnectionProvider* CRtpSubConnectionProvider::NewL(ESock::CSubConnectionProviderFactoryBase& aFactory)
/**
Construct a new RTP SubConnection Provider Object

@param aFactory factory that create this object
*/
	{
	CRtpSubConnectionProvider* self = new (ELeave) CRtpSubConnectionProvider(aFactory);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop();
	return self;
	}


CRtpSubConnectionProvider::~CRtpSubConnectionProvider()
    {
    LOG_NODE_DESTROY(KRTPSCprTag, CRtpSubConnectionProvider);
    iLocalParameterBundle.Close();
    }


CRtpSubConnectionProvider::CRtpSubConnectionProvider(ESock::CSubConnectionProviderFactoryBase& aFactory)
:CCoreSubConnectionProvider(aFactory, RTPSCprActivities::activityMap::Self())
    {
    LOG_NODE_CREATE(KRTPSCprTag, CRtpSubConnectionProvider);
    }

void CRtpSubConnectionProvider::ConstructL()
/**
RTP SubConnection Provider Second Phase Constructor
*/
	{
    CCoreSubConnectionProvider::ConstructL();
	}

void CRtpSubConnectionProvider::Received(MeshMachine::TNodeContextBase& aContext)
    {
  
	 	Messages::TNodeSignal::TMessageId noPeerIds[] = {
        TCFFactory::TPeerFoundOrCreated::Id(),
        TCFPeer::TJoinRequest::Id(),
        Messages::TNodeSignal::TMessageId()
        };

    MeshMachine::AMMNodeBase::Received(noPeerIds, aContext);
	MeshMachine::AMMNodeBase::PostReceived(aContext);
	}

void CRtpSubConnectionProvider::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aCFMessage)
    {
    RtpSCprStates::TContext ctx(*this, aCFMessage, aSender, aRecipient);
    CRtpSubConnectionProvider::Received(ctx);
    User::LeaveIfError(ctx.iReturn);
	}

RCFParameterFamilyBundle& CRtpSubConnectionProvider::GetOrCreateLocalParameterBundleL()
	{
	if( ! iLocalParameterBundle.IsNull())
		{
		return iLocalParameterBundle;
		}
	iLocalParameterBundle.CreateL();
	iLocalParameterBundle.Open();

	return iLocalParameterBundle;	
	}