linklayerprotocols/ethernetnif/EthInt/ethmcpr.cpp
author William Roberts <williamr@symbian.org>
Wed, 10 Nov 2010 13:36:07 +0000
branchRCL_3
changeset 79 4b172931a477
parent 0 af10295192d8
permissions -rw-r--r--
Make configchange.pl run ceddump.exe with -dtextshell - Bug 3932

// 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:
// Ethernet MCPR
// 
//

/**
 @file
 @internalComponent
*/

#include <comms-infras/ss_log.h>
#include <comms-infras/agentmcpractivities.h>
#include <comms-infras/coremcpractivities.h>
#include <comms-infras/ss_tiermanagerutils.h>
#include <comms-infras/ss_msgintercept.h>

#include "ethmcpr.h"
#include "EthProvision.h"

#define KEthMCprTag KESockMetaConnectionTag

using namespace Messages;
using namespace MeshMachine;
using namespace ESock;
using namespace NetStateMachine;
using namespace MCprActivities;
using namespace EthMCprStates;



// No Bearer Activity
namespace EthMCPRNoBearerActivity
{
DECLARE_DEFINE_NODEACTIVITY(ECFActivityNoBearer, EthMCPRNoBearer, TCFControlProvider::TNoBearer)
	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingNoBearer, MeshMachine::TNoTag)
	LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendBearer)
NODEACTIVITY_END()
}



// Activity Map
namespace EthMCprStates
{
DEFINE_EXPORT_ACTIVITY_MAP(stateMap)
	ACTIVITY_MAP_ENTRY(EthMCPRNoBearerActivity, EthMCPRNoBearer)
ACTIVITY_MAP_END_BASE(AgentMCprActivities, agentMCprActivities)
} // namespace EthMCprStates

//-=========================================================
//
//CEthMetaConnectionProvider implementation
//
//-=========================================================

EXPORT_C CEthMetaConnectionProvider* CEthMetaConnectionProvider::NewL(ESock::CMetaConnectionProviderFactoryBase& aFactory, const TProviderInfo& aProviderInfo)
    {
    // coverity[alloc_fn] coverity[alias] coverity[assign]
    CEthMetaConnectionProvider* self = new (ELeave) CEthMetaConnectionProvider(aFactory, aProviderInfo, EthMCprStates::stateMap::Self());
    // coverity[push]
    CleanupStack::PushL(self);
    // coverity[alias] coverity[double_push]
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
    }

EXPORT_C void CEthMetaConnectionProvider::ConstructL()
	{
	CAgentMetaConnectionProvider::ConstructL();
	SetAccessPointConfigFromDbL();
	}

EXPORT_C CEthMetaConnectionProvider::CEthMetaConnectionProvider(CMetaConnectionProviderFactoryBase& aFactory,
    							     const ESock::TProviderInfo& aProviderInfo,
								     const MeshMachine::TNodeActivityMap& aActivityMap)
:	CAgentMetaConnectionProvider(aFactory,aProviderInfo,aActivityMap)
	{
	LOG_NODE_CREATE(KEthMCprTag, CEthMetaConnectionProvider);
	}

EXPORT_C  CEthMetaConnectionProvider::~CEthMetaConnectionProvider()
	{
	LOG_NODE_DESTROY(KEthMCprTag, CEthMetaConnectionProvider);
	}

EXPORT_C void CEthMetaConnectionProvider::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage)
    {
	__CFLOG_VAR((KEthMCprTag, KEthMCprSubTag, _L8("CEthMetaConnectionProvider [this=%08x]::ReceivedL() aCFMessage=%d"),
	   this, aCFMessage.MessageId().MessageId()));

	ESOCK_DEBUG_MESSAGE_INTERCEPT(aSender, aMessage, aRecipient);

	TNodeContext<CEthMetaConnectionProvider> ctx(*this, aMessage, aSender, aRecipient);
    CCoreMetaConnectionProvider::Received(ctx);
    User::LeaveIfError(ctx.iReturn);
	}

void CEthMetaConnectionProvider::SetAccessPointConfigFromDbL()
    {
	__CFLOG_VAR((KEthMCprFactoryTag, KEthMCprFactorySubTag, _L8("CEthMetaConnectionProvider %08x:\tSetAccessPointConfigFromDbL()"), this));

    RMetaExtensionContainer mec;
    mec.Open(AccessPointConfig());
    CleanupClosePushL(mec);
    
	
	// Open an IAP specific view on CommsDat
	CCommsDatIapView* iapView = OpenIapViewLC();

	// Presumptions:
	// - none of the extensions can already exist in the AccessPointConfig array.  AppendExtensionL()
	//   is presumed to panic if adding the same extension a second time.
	// - if we have added several extensions to the AccessPointConfig array before getting a failure
	//   and leaving, it is presumed that the MCPr will be destroyed and AccessPointConfig destructor
	//   will clean up the extensions immediately afterwards.

    ProvisionLinkConfigL(iapView, mec);
    ProvisionNetworkConfigL(iapView, mec);
    
	CleanupStack::PopAndDestroy(); // CloseIapView();

	AccessPointConfig().Close();
	AccessPointConfig().Open(mec);
    CleanupStack::PopAndDestroy(&mec);
	}



void CEthMetaConnectionProvider::ProvisionLinkConfigL(CCommsDatIapView* aIapView, ESock::RMetaExtensionContainer& aMec)
    {
	TLanLinkProvision* linkProvision = new (ELeave) TLanLinkProvision;
	CleanupStack::PushL(linkProvision);

	// Initialise the link config

	// NOTE:
	// All the LANBearer strings are read as 16-bit values and copied into the
	// 8-bit buffers in the provisioning structure to save memory
	HBufC* buf = NULL;
	TInt err(KErrNone);

	// Config Daemon Name
	err = aIapView->GetText(KCDTIdLANConfigDaemonName, buf);
	if (err == KErrNone  && buf != NULL) 
	    {
    	linkProvision->SetConfigDaemonName(*buf);
    	delete buf;
    	buf= NULL;
	    }
	else if (err == KErrNotFound)
	    {
	    linkProvision->SetConfigDaemonName (KNullDesC);
	    }
	else
	    {
	    User::Leave(err);
	    }

	// LDD Filename
	err = aIapView->GetText(KCDTIdLANBearerLddFilename, buf);
	if (err == KErrNone && buf != NULL) 
	    {
    	linkProvision->SetLddFilename(*buf);
    	delete buf;
    	buf= NULL;
	    }
	else if (err == KErrNotFound)
	    {
	    linkProvision->SetLddFilename (KNullDesC);
	    }
	else
	    {
	    User::Leave(err);
	    }

	// LDD Name
	err = aIapView->GetText(KCDTIdLANBearerLddName, buf);
	if (err == KErrNone && buf != NULL) 
	    {
    	linkProvision->SetLddName(*buf);
    	delete buf;
    	buf= NULL;
	    }
	else if (err == KErrNotFound)
	    {
	    linkProvision->SetLddName (KNullDesC);
	    }
	else
	    {
	    User::Leave(err);
	    }

	// PDD Filename
	err = aIapView->GetText(KCDTIdLANBearerPddFilename, buf);
	if (err == KErrNone && buf != NULL) 
	    {
    	linkProvision->SetPddFilename(*buf);
    	delete buf;
    	buf= NULL;
	    }
	else if (err == KErrNotFound)
	    {
	    linkProvision->SetPddFilename (KNullDesC);
	    }
	else
	    {
	    User::Leave(err);
	    }

	// PDD Name
	err = aIapView->GetText(KCDTIdLANBearerPddName, buf);
	if (err == KErrNone && buf != NULL) 
	    {
    	linkProvision->SetPddName(*buf);
    	delete buf;
    	buf= NULL;
	    }
	else if (err == KErrNotFound)
	    {
	    linkProvision->SetPddName (KNullDesC);
	    }
	else
	    {
	    User::Leave(err);
	    }

	// Packet Driver Name - required info, always error
	aIapView->GetTextL(KCDTIdLANBearerPacketDriverName, buf);
	linkProvision->SetPacketDriverName(*buf);
 	delete buf;

	// Append the provisioning object to the CAccessPointConfig array
 	aMec.AppendExtensionL(linkProvision);
	CleanupStack::Pop(linkProvision);
    }


void CEthMetaConnectionProvider::ProvisionNetworkConfigL(CCommsDatIapView* aIapView, ESock::RMetaExtensionContainer& aMec)
    {
	HBufC* buf = NULL;
    aIapView->GetTextL(KCDTIdLANIfNetworks, buf);
    CleanupStack::PushL(buf);
    if (buf->Length() == 0)
        {
        User::Leave(KErrCorrupt);
        }

    TPtrC16 networks;
    networks.Set(*buf);
    TPtrC16 current;
    TUint32 order = 0;
    TInt commaPos = 0;
    while (commaPos != KErrNotFound)
        {
        commaPos = networks.LocateF(',');
        if (commaPos == KErrNotFound)
            {
            // take all of string
            current.Set(networks);
            }
        else
            {
            current.Set(networks.Ptr(), commaPos);
            }

        if (!current.CompareF(_L("ip")))
            {
            ProvisionIp4ConfigL(aIapView, order, aMec);
            }
        else if (!current.CompareF(_L("ip6")))
            {
            ProvisionIp6ConfigL(aIapView, order, aMec);
            }
        else
            {
            User::Leave(KErrCorrupt);
            }

        order++;
        networks.Set(networks.Mid(commaPos+1));
        }

    CleanupStack::PopAndDestroy(buf);
    }


void CEthMetaConnectionProvider::ProvisionIp4ConfigL(CCommsDatIapView* aIapView, TUint32 aOrder, ESock::RMetaExtensionContainer& aMec)
    {
	TLanIp4Provision* ip4Provision = new (ELeave) TLanIp4Provision;
	CleanupStack::PushL(ip4Provision);

	ip4Provision->SetOrder(aOrder);

	// Read IP address configuration parameters
	TBool serverRequired;
	aIapView->GetBoolL(KCDTIdLANIpAddrFromServer, serverRequired);

	TUint32 addr;
	TInt err;

	ip4Provision->SetLocalAddr(KInetAddrNone);
	ip4Provision->SetNetMask(KInetAddrNone);
	ip4Provision->SetDefGateway(KInetAddrNone);

	if (!serverRequired)
		{
		GetIp4AddrL(aIapView, KCDTIdLANIpAddr, addr);
  		ip4Provision->SetLocalAddr(addr);
		err = GetIp4Addr(aIapView, KCDTIdLANIpNetMask, addr);
		if (err == KErrNone)
			{
			ip4Provision->SetNetMask(addr);
			}

		err = GetIp4Addr(aIapView, KCDTIdLANIpGateway, addr);
		if (err == KErrNone)
		    {
		    ip4Provision->SetDefGateway(addr);
		    }
		else if (err == KErrNotFound || err == KErrArgument)
		    {
		    ip4Provision->SetDefGateway(ip4Provision->LocalAddr());
		    }
		else
		    {
		    User::Leave(err);
		    }

		// Because CommDB doesn't define a Broadcast Address field, we must
		// calculate the broadcast address. This is based on the localAddr
		// and the netMask.

		TInetAddr localAddr(ip4Provision->LocalAddr(), 0);
		TInetAddr netMask(ip4Provision->NetMask(), 0);
		TInetAddr broadcast;
		broadcast.SubNetBroadcast(ip4Provision->LocalAddr(), ip4Provision->NetMask());
		ip4Provision->SetBroadcastAddr(broadcast.Address());
   		}

	ip4Provision->SetPrimaryDns(KInetAddrNone);
	ip4Provision->SetSecondaryDns(KInetAddrNone);

	aIapView->GetBoolL(KCDTIdLANIpDNSAddrFromServer, serverRequired);
  	if (!serverRequired)
  		{
  		err = GetIp4Addr(aIapView, KCDTIdLANIpNameServer1, addr);
  		if (err == KErrNone)
  		    {
  		    ip4Provision->SetPrimaryDns(addr);
		    err = GetIp4Addr(aIapView, KCDTIdLANIpNameServer2, addr);
		    if (err == KErrNone)
		        {
		        ip4Provision->SetSecondaryDns(addr);
		        }
  		    }

  		if (err != KErrNone && err != KErrNotFound && err != KErrArgument)
  		    {
  		    User::Leave(err);
  		    }
     	}

	// Append the provisioning object to the CAccessPointConfig array
  	aMec.AppendExtensionL(ip4Provision);
	CleanupStack::Pop(ip4Provision);
    }


void CEthMetaConnectionProvider::ProvisionIp6ConfigL(CCommsDatIapView* aIapView, TUint32 aOrder, ESock::RMetaExtensionContainer& aMec)
    {
	TLanIp6Provision* ip6Provision = new (ELeave) TLanIp6Provision;
	CleanupStack::PushL(ip6Provision);

	ip6Provision->SetOrder(aOrder);

	// Determine whether static DNS configuration is required.
	TBool dynamicDns = ETrue;

	// By default, Ensure that static DNS addresses are set as unspecified,
	// so they are not used in Control(KSoIfConfig).
	ip6Provision->SetPrimaryDns(KInet6AddrNone);
	ip6Provision->SetSecondaryDns(KInet6AddrNone);

	// Ignore any errors from reading this field - default to dynamicDns = ETrue
	(void) aIapView->GetBool(KCDTIdLANIp6DNSAddrFromServer, dynamicDns);

	if (!dynamicDns)
		{
		// Read static DNS addresses
		TInt err;
		TIp6Addr addr6;
  		err = GetIp6Addr(aIapView, KCDTIdLANIp6NameServer1, addr6);
  		if (err == KErrNone)
  		    {
  		    ip6Provision->SetPrimaryDns(addr6);
		    err = GetIp6Addr(aIapView, KCDTIdLANIp6NameServer2, addr6);
		    if (err == KErrNone)
		        {
		        ip6Provision->SetSecondaryDns(addr6);
		        }
  		    }

  		if (err != KErrNone && err != KErrNotFound && err != KErrArgument)
  		    {
  		    User::Leave(err);
  		    }
		}

	// Append the provisioning object to the CAccessPointConfig array
	aMec.AppendExtensionL(ip6Provision);
	CleanupStack::Pop(ip6Provision);
    }