linklayerprotocols/ethernetnif/INC/EthProto.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 01 Apr 2010 00:00:09 +0300
branchRCL_3
changeset 12 e9cc36e353d4
parent 0 af10295192d8
permissions -rw-r--r--
Revision: 201013 Kit: 201013

// Copyright (c) 2003-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:
// Historical Note: this file was originally copied from networking/ether802/inc/ethinter.h.
// 
//

/**
 @file
 @internalComponent 
*/

#if !defined(__ETHER802_H__)
#define __ETHER802_H__

#include <networking/pktdrv.h>
#include <comms-infras/nifif.h> //needed for cnififfactory.
#include <in_sock.h>

#include <comms-infras/commsdebugutility.h>
#include <comms-infras/ss_subconnflow.h>
#include <comms-infras/ss_flowbinders.h>
#include <networking/pktdrv_internal.h>

#ifdef __FLOG_ACTIVE
#define TCPDUMP_LOGGING // log all ethernet frame in pcap format
#endif // __FLOG_ACTIVE

class TLanLinkProvision;
class TLanIp4Provision;
class TLanIp6Provision;

const TInt KUidEthintNifmanInterface = 0x10000541;
const TInt KAuthenticationComplete = 5;
const TInt KEtherMaxFrame = 1492;
const TInt KEtherSpeedInKbps = 10000;
const TInt KProtocolAddressSize=4; //Address size of IP4
const TInt KNetworkAddressSize=6; //Address size for Ether MAC
const TInt KArpMacMulticastMask=0x7FFFFF;


enum TEtherHeaderType{EStandardEthernet, ELLCEthernet}; // Ethernet header types

/*******************************************************************************
* A quick intro to the Ethernet packet format:
*
* A plain frame looks like this:
*
* struct EtherFrame {
*   TUint64 iDestAddr, iSrcAddr;
*   TUint16 iType; // Denotes the Protocol Type == Service Access Point == SAP
*   TUint8  iData[1500]; // Payload.
* };
*
* iType denotes the type of the payload, 0x0800 denotes IP.
*                                        0x0806 denotes ARP.
*                                        >=Min, <=1500 denotes LLC.
* A frame may also contain an extra 'LLC' field which encapsulates the original
* payload in a 5 byte header. The LLC field is somewhat complex, but here we
* confine ourselves to the LLC-SNAP variant.
*
* struct EtherLLCFrame {
*   TUint64 iDestAddr, iSrcAddr;
*   TUint16 iLen; // Denotes the Len and must be <=1500 so as not to conflict
*                 // With iType interpretation.
*   TUint8 iDSAP=0xAA; // Which denotes an LLC-SNAP frame.
*   TUint8 iSSAP=0xAA; // Which denotes an LLC-SNAP frame.
*   TUint8 iCTRL=3;    // Which denotes an LLC-SNAP frame encapsulated by
*                      // Ethernet.
*   TUint24 OUI=iDstAddr&0xffffff; // 0 is also a valid value.
*   TUint16 iType; // The actual iType as described earlier.
*   TUint8  iData[1492]; // Payload.
* };
*
*******************************************************************************/

_LIT(ETHER802_CONFIG_FILENAME, "ether802.ini");
_LIT(KInterfaceSection,"interface_settings");
_LIT(KEthernetSection,"ethernet_settings");

const TUint32 KDefaultSpeedMetricSetting = 0;
const TUint32 KDefaultMtuSetting = 1500;
const TUint32 KMACByteLength = 6;
const TUint32 KDestAddrOffset = 8;

// For the purposes of Wants, we define the protocol code as a pair:
// EtherType, IPType... we don't know the link layer above is definitely
// using IP packets...
const TUint16 KIPFrameType = 0x800;
const TUint16 KIP6FrameType = 0x86DD;
const TUint16 KArpFrameType= 0x806;
const TUint8 KLLC_SNAP_DSAP = 0xAA;
const TUint8 KLLC_SNAP_SSAP = 0xAA;
const TUint8 KLLC_SNAP_CTRL = 3;

/**
@internalComponent
*/
struct TEtherFrame
{
	TUint16 GetType() const { return BigEndian::Get16((TUint8*)&iTypeLen); }
	TUint16 iDestAddr[3];
	TUint16 iSrcAddr[3];
	TUint16 iTypeLen; // Denotes the Protocol Type <=> Service Access Point <=> SAP
	TUint8  iData[KDefaultMtuSetting]; // Payload.
};

const TUint KEtherHeaderSize=14;
const TUint KEtherLLCHeaderSize=KEtherHeaderSize+8;

/**
@internalComponent
*/
struct TEtherLLCFrame
{
	TUint16 GetType() const { return (TUint16)((iTypeHi<<8)|iTypeLo); }
	void SetType(TUint16 aType)
		{
		iTypeHi=(TUint8)(aType>>8); iTypeLo=(TUint8)(aType&0xff);
		}
	void SetDestAddr( TDesC8& aDest);
	void SetSrcAddr( TDesC8& aSrc);
	void SetOUI( TUint32 aOUI);
	TUint16 iDestAddr[3];
	TUint16 iSrcAddr[3];
	TUint16 iTypeLen;
	TUint8 iDSAP; // Which denotes an LLC-SNAP frame.
	TUint8 iSSAP; // Which denotes an LLC-SNAP frame.
	TUint8 iCtrl;    // Which denotes an LLC-SNAP frame encapsulated by
	// Ethernet.
	TUint8 OUI[3];
	TUint8 iTypeHi;
	TUint8 iTypeLo; // The actual iType as described earlier.
	TUint8 iData[1492]; // Payload.
};

class CLanxBearer;
typedef CArrayPtrFlat<CLanxBearer> CLanxBearerPtrArray;

class CEthLog;

/**
Main LAN Nif Control object creates lower layer objects :-
Packet Driver & EtherXXX
Calls back to protocol (iProtocol) and nifman (iNotifier in CNifIfBase)
Calls down to EtherXX (iMacLayer)
@internalComponent
*/
class CLANLinkCommon : public ESock::CSubConnectionFlowBase, public ESock::MFlowBinderControl
{
	friend class CPktDrvBase;
public:
	enum TAction
		{
		EReconnect,
		EDisconnect
		};
	IMPORT_C static CLANLinkCommon* NewL(ESock::CSubConnectionFlowFactoryBase& aFactory, const Messages::TNodeId& aSubConnId, ESock::CProtocolIntfBase* aProtocolIntf);
	IMPORT_C CLANLinkCommon(ESock::CSubConnectionFlowFactoryBase& aFactory, const Messages::TNodeId& aSubConnId, ESock::CProtocolIntfBase* aProtocolIntf);
	IMPORT_C virtual ~CLANLinkCommon();
	IMPORT_C void ConstructL();

	// from MFlowBinderControl
	IMPORT_C virtual ESock::MLowerControl* GetControlL(const TDesC8& aProtocol);
	IMPORT_C virtual ESock::MLowerDataSender* BindL(const TDesC8& aProtocol, ESock::MUpperDataReceiver* aReceiver, ESock::MUpperControl* aControl);
	IMPORT_C virtual void Unbind(ESock::MUpperDataReceiver* aReceiver, ESock::MUpperControl* aControl);
	virtual ESock::CSubConnectionFlowBase* Flow()
    	{
    	return this;
    	}

	// from Messages::ANode
	IMPORT_C virtual void ReceivedL(const Messages::TRuntimeCtxId& aSender, const Messages::TNodeId& aRecipient, Messages::TSignatureBase& aMessage);

	// Dispatch functions for messages received from SCPR.

	void StartFlowL();
	void CancelStartFlow();
	void StopFlow(TInt aError);
	void SubConnectionGoingDown();
	void SubConnectionError(TInt aError);
	void BindToL(Messages::TNodeId& aCommsBinder);

	void Destroy();

	// Utility functions for sending messages to SCPR.
	void PostProgressMessage(TInt aStage, TInt aError);
	void PostDataClientStartedMessage();
	void PostFlowDownMessage(TInt aError);
	void PostFlowGoingDownMessage(TInt aError, MNifIfNotify::TAction aAction);
	void MaybePostDataClientIdle();

	// CSubConnectionFlowBase
	MFlowBinderControl* DoGetBinderControlL()
    	{
    	return this;
    	}

	//
	// Upcalls from the packet driver
	//
	IMPORT_C void Process(RMBufChain& aPdu, TAny* aMAC=0);
	IMPORT_C void ResumeSending(); // Flow Control unblocked
	IMPORT_C void LinkLayerUp(); // Notify the Protocol that the line is up
	IMPORT_C void LinkLayerDown(TInt aError, TAction aAction); // Notify the Protocol that the line is down
	IMPORT_C void FoundMACAddrL(); // Added for interfaces that take a while to find their MAC addrs

	IMPORT_C TInt ReadInt(const TDesC& aField, TUint32& aValue);
    IMPORT_C TInt WriteInt(const TDesC& aField, TUint32 aValue);
    IMPORT_C TInt ReadDes(const TDesC& aField, TDes8& aValue);
    IMPORT_C TInt ReadDes(const TDesC& aField, TDes16& aValue);
    IMPORT_C TInt WriteDes(const TDesC& aField, const TDesC8& aValue);
	IMPORT_C TInt WriteDes(const TDesC& aField, const TDesC16& aValue);
	IMPORT_C TInt ReadBool(const TDesC& aField, TBool& aValue);
    IMPORT_C TInt WriteBool(const TDesC& aField, TBool aValue);
	IMPORT_C void IfProgress(TInt aStage, TInt aError);
	IMPORT_C void IfProgress(TSubConnectionUniqueId aSubConnectionUniqueId, TInt aStage, TInt aError);
	IMPORT_C void NifEvent(TNetworkAdaptorEventType aEventType, TUint aEvent, const TDesC8& aEventData, TAny* aSource=0);

	TUint Mtu() const;

	TUint SpeedMetric() const {return KEtherSpeedInKbps; }
	TEtherHeaderType EtherType() const { return iEtherType; }
	const TBuf8<KMACByteLength>& MacAddress() const;

	TInt FrameSend(RMBufChain& aPdu, TAny* aSource=0, TUint16 aType=KIPFrameType);

	void SetAllowedBearer(CLanxBearer* aBearer);
    TBool BearerIsActive(CLanxBearer* aBearer);

private:
	//
	// Configuration methods
	TBool ReadMACSettings();
	void ReadEthintSettingsL();
	TInt EtherFrame(RMBufChain &aChain, TUint16 aType=KIPFrameType);
	TBool CheckMac(TDes8& aMacAddr); // checks that the packet driver has returned a valid MAC address,
	//New.
	TInt GetProtocolType(RMBufChain& aPdu, TUint16& aEtherType, TUint8*& aPayloadPtr, TUint& aEtherHeaderSize) const;
	//
	// Driver managment
	void LoadPacketDriverL();

	// Search CLanxBearer array by various keys (used in bind/unbind/provisioning)
	CLanxBearer* FindBearerByProtocolName(const TDesC8& aProtocol, TInt& aIndex) const;
	CLanxBearer* FindBearerByUpperControl(const ESock::MUpperControl* aUpperControl, TInt& aIndex) const;

	// Provisioning
	void ProvisionConfig(const ESock::RMetaExtensionContainerC& aConfigData);
	void ProvisionConfigL();
	void ProvisionBearerConfigL(const TDesC8& aName);
	const TLanLinkProvision& LinkProvision();

protected:
	// Creates packet driver methods
	CPktDrvFactory* DoCreateDriverFactoryL(TUid aUid2,const TDesC& aFilename);
	CPacketDriverOwner* iPktDrvOwner; // We create this but do not own it

	// This class creates the packet driver and binds it to the mac layer
	CPktDrvBase*		iPktDrv;

	//MAC Address
	TBuf8<KMACByteLength> iMacAddr;
	//indicates if iMacAddr contains a valid Mac address
	TBool iValidMacAddr;

	TEtherHeaderType	iEtherType;

	// Bearer List:
	CLanxBearerPtrArray  *iBearers;
	CLanxBearer			 *iOnlyThisBearer;

	#ifdef TCPDUMP_LOGGING
	private:
		CEthLog* iLogger;
	#endif // TCPDUMP_LOGGING

	// Provisioning related
	const TLanLinkProvision* iLanLinkProvision;		// link provisioning information from SCPR
	const TLanIp4Provision* iLanIp4Provision;		// ip4 provisioning information from SCPR
	const TLanIp6Provision* iLanIp6Provision;		// ip6 provisioning information from SCPR
	TBool iStopRequested;

	TInt iSavedError;								// saved errors from processing TProvisionConfig message

	enum TMeshMashineFlowState
      	{
      	EStopped,
      	EStarting,
      	EStarted,
      	EStopping,
      	};
	TMeshMashineFlowState iMMState;
};

inline const TBuf8<KMACByteLength>& CLANLinkCommon::MacAddress() const
{
	return iMacAddr;
}



#endif