linklayerprotocols/ethernetnif/EthInt/Ethbase.cpp
changeset 0 af10295192d8
child 23 23b59305592d
child 25 d15a50675083
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Ethernet and 802.3 protocol suite common link layer (interface) code 
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 #include <f32file.h>
       
    23 #include <e32std.h>	// for TTime
       
    24 #include <nifman.h>
       
    25 #include <nifvar.h>
       
    26 #include <nifutl.h>
       
    27 #include <es_mbuf.h>
       
    28 #include <nifmbuf.h>
       
    29 #include <comms-infras/nifprvar.h>
       
    30 #include <comms-infras/connectionsettings.h>	// for KSlashChar
       
    31 #include <commdb.h>
       
    32 #include "EthProto.h"
       
    33 #include "PKTDRV.H"
       
    34 #include <in_sock.h> // Header is retained, but in_sock.h is modified for ipv6
       
    35 #include <d32ethernet.h>
       
    36 #include "CLanIp4Bearer.h"
       
    37 #include "CLanIp6Bearer.h"
       
    38 #include "eth_log.h"
       
    39 #include <cdbcols.h>
       
    40 #include <cdblen.h>
       
    41 #include "CLanxBearer.h"
       
    42 #include "eth_log.h"
       
    43 #include "EthProvision.h"
       
    44 #include <comms-infras/ss_metaconnprov.h>					// for SAccessPointConfig
       
    45 #include <comms-infras/ss_log.h>
       
    46 #include <comms-infras/linkmessages.h>
       
    47 #include <elements/nm_messages_base.h>
       
    48 #include <elements/nm_messages_child.h>
       
    49 
       
    50 using namespace Messages;
       
    51 using namespace MeshMachine;
       
    52 using namespace ESock;
       
    53 using namespace Elements;
       
    54 
       
    55 _LIT8(KDescIp, "ip");
       
    56 _LIT8(KDescIcmp, "icmp");
       
    57 _LIT8(KDescIp6, "ip6");
       
    58 
       
    59 /**
       
    60 Constant supports Broadcasting or Multicasting
       
    61 @internalComponent
       
    62 */
       
    63 
       
    64 /**
       
    65 Packet driver Function Pointer
       
    66 @internalComponent
       
    67 */
       
    68 typedef CPktDrvFactory* (*TPktDrvFactoryNewL)();
       
    69 
       
    70 EXPORT_C CLANLinkCommon::CLANLinkCommon(CSubConnectionFlowFactoryBase& aFactory, const TNodeId& aSubConnId, CProtocolIntfBase* aProtocolIntf)
       
    71 	: CSubConnectionFlowBase(aFactory, aSubConnId, aProtocolIntf), iMMState(EStopped)
       
    72 {
       
    73    	LOG_NODE_CREATE(KEthLogTag2, CLANLinkCommon);
       
    74 }
       
    75 
       
    76 /**
       
    77 Loads, creates and starts the packet driver.
       
    78 The packet driver's name is found from the LAN service table in commdb.
       
    79 The name then has '.drv' appended and its driver factory is found using DoFindDriverFactoryL.
       
    80 If found, the packet driver is created using the factory's NewDriverL method and the driver state is set to EDrvStarted.
       
    81 @note Should be called from the ConstructL phase of the CLANLinkCommon initialisation.
       
    82 */
       
    83 void CLANLinkCommon::LoadPacketDriverL()
       
    84 {
       
    85 	TBuf<KCommsDbSvrDefaultTextFieldLength+4> drvName;	// plus 4 is for the filename extension added below
       
    86 
       
    87 	ASSERT(iLanLinkProvision);
       
    88 
       
    89 	if (LinkProvision().PacketDriverName().Length() == 0)
       
    90 		{
       
    91 		__FLOG_STATIC(KEther802LogTag1,KEthLogTag2, _L("Empty packet driver name - is .cfg file up-to-date?  See ether802.ini for information on required fields in commdb."));
       
    92 		User::Leave(KErrArgument);
       
    93 		}
       
    94 
       
    95 	drvName.Copy(LinkProvision().PacketDriverName());
       
    96 
       
    97 	if(!(drvName.Right(4)==KPacketDriverFileExtension())) // no != for comparing strings, so a bit of laboured logic
       
    98 		{
       
    99 		drvName.Append(KPacketDriverFileExtension);
       
   100 		}
       
   101 
       
   102 	// Ref counted library ownership to ensure the library is not unloaded prematurely
       
   103 	CPktDrvFactory* pktFactory = (CPktDrvFactory *)DoCreateDriverFactoryL(TUid::Uid(KUidNifmanPktDrv), drvName);
       
   104 	CleanupStack::PushL(pktFactory);
       
   105 	iPktDrvOwner = new(ELeave)CPacketDriverOwner(pktFactory);
       
   106 	CleanupStack::Pop();
       
   107 	iPktDrvOwner->Open();
       
   108 
       
   109 	iPktDrv=pktFactory->NewDriverL(this);
       
   110 }
       
   111 
       
   112 EXPORT_C CLANLinkCommon* CLANLinkCommon::NewL(CSubConnectionFlowFactoryBase& aFactory, const TNodeId& aSubConnId, CProtocolIntfBase* aProtocolIntf)
       
   113 	{
       
   114 	CLANLinkCommon* s=new (ELeave) CLANLinkCommon(aFactory, aSubConnId, aProtocolIntf);
       
   115 	CleanupStack::PushL(s);
       
   116 	s->ConstructL();
       
   117 	CleanupStack::Pop();
       
   118 	return s;
       
   119 	}
       
   120 
       
   121 /** Ethernet Type - Encapsulation
       
   122 @internalComponent
       
   123 */
       
   124 _LIT(KEtherType,"encapsulation");
       
   125 
       
   126 /**
       
   127 Reads the Link layer Ethernet settings in Ether802.ini. Currently this is just the ethernet
       
   128 encapsulation type, stored in parameter encapsulation in section [ethernet], sets iEtherType
       
   129 on the basis of the encapsulation type: ELLCEthernet, if the encapsulation parameter = 1, or
       
   130 EStandardEthernet otherwise.
       
   131 */
       
   132 void CLANLinkCommon::ReadEthintSettingsL()
       
   133 {
       
   134 	CESockIniData* ini = CESockIniData::NewL(ETHER802_CONFIG_FILENAME);
       
   135 	CleanupStack::PushL(ini);
       
   136 	TInt encapType = 0;
       
   137 	ini->FindVar(KEthernetSection,KEtherType,encapType);
       
   138 
       
   139 	CleanupStack::PopAndDestroy();
       
   140 
       
   141 	switch(encapType)
       
   142 		{
       
   143 		case 0 :
       
   144 			__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Framing type set to Ethernet II"));
       
   145 			iEtherType=EStandardEthernet;
       
   146 			break;
       
   147 		case 1 :
       
   148 			__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Framing type set to IEEE802.3 LLC-SNAP"));
       
   149 			iEtherType=ELLCEthernet;
       
   150 			break;
       
   151 		default :
       
   152 			__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Unrecognised or no framing type in config file - framing type set to Ethernet II"));
       
   153 			iEtherType=EStandardEthernet;  // not a valid type
       
   154 		}
       
   155 }
       
   156 
       
   157 /**
       
   158 Implementation of the pure virtual from CLANLinkBase, for use by the bearers. Returns the
       
   159 hardware interface obtained from the packet layer in the aBuffer descriptor in a 6 byte binary
       
   160 Big-endian format.
       
   161 @return ETrue if the hardware address was non-zero, EFalse otherwise.
       
   162 */
       
   163 TBool CLANLinkCommon::ReadMACSettings()
       
   164 {
       
   165 	TBuf8<KMACByteLength> drvMacAddr;
       
   166 	TUint8* config=iPktDrv->GetInterfaceAddress();
       
   167 	drvMacAddr.Append(&config[0],KMACByteLength); // First 3 bytes of config not part of address
       
   168 	iMacAddr.Copy(drvMacAddr); // update Ethints copy of the MAC address
       
   169 	TUint bearerLim = iBearers->Count();
       
   170 	for(TUint index=0;index<bearerLim;index++)
       
   171 		{
       
   172 		CLanxBearer* bearer=(*iBearers)[index];
       
   173 		bearer->UpdateMACAddr();
       
   174 		}
       
   175 
       
   176 	// check that the macaddress has been passed and is not 0;
       
   177 	return CheckMac(iMacAddr); // wrong.
       
   178 }
       
   179 
       
   180 
       
   181 TUint CLANLinkCommon::Mtu() const
       
   182 {
       
   183 	if(iEtherType==ELLCEthernet)
       
   184 		{
       
   185 		__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("MTU - value for LLC frames"));
       
   186 		return KEtherMaxFrame;
       
   187 		}
       
   188 	__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("MTU - default setting"));
       
   189 	return KDefaultMtuSetting;
       
   190 }
       
   191 
       
   192 /**
       
   193 The CLANLinkCommon::ConstructL performs all the memory allocating initialisations. It's
       
   194 iContainer is allocated, using NewL; its iPktDriverFactories is created using its
       
   195 iContainer->CreateL. A dynamic array of 16 iBearers are created.
       
   196 @param TDesC Unused
       
   197 */
       
   198 EXPORT_C void CLANLinkCommon::ConstructL()
       
   199 {
       
   200 	__FLOG_STATIC(KEther802LogTag1,KEthLogTag2, _L("Ethint started"));
       
   201 
       
   202 	// Initialise class members that do not need to be read from the database
       
   203 	iBearers = new (ELeave) CLanxBearerPtrArray(16);
       
   204 	iOnlyThisBearer = NULL;
       
   205 
       
   206 	__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Reading Ethint settings"));
       
   207 	ReadEthintSettingsL();
       
   208 
       
   209 #ifdef TCPDUMP_LOGGING
       
   210 	__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Libpcap format logging enabled"));
       
   211 	iLogger = CEthLog::NewL();
       
   212 	iLogger->DumpTcpDumpFileHeader();
       
   213 #endif // TCPDUMP_LOGGING
       
   214 }
       
   215 
       
   216 /**
       
   217 Destructor. If there are any iPktDrvFactories, these are deleted first, by closing each Factory's
       
   218 RLibrary iLib handle and then deleting the object. Then all the bearers are deleted . Finally,
       
   219 the packet driver, the logical device driver and the physical device driver are freed and then
       
   220 the packet driver is deleted.
       
   221 */
       
   222 EXPORT_C  CLANLinkCommon::~CLANLinkCommon()
       
   223 {
       
   224 #ifdef TCPDUMP_LOGGING
       
   225 	delete iLogger;
       
   226 #endif // TCPDUMP_LOGGING
       
   227 
       
   228 	delete iPktDrv;
       
   229 	if(iPktDrvOwner != NULL ) // iPktDrvOwner may not be created if leave occurs while loading the driver.
       
   230 	{
       
   231 		iPktDrvOwner->Close();
       
   232 	}
       
   233 	ASSERT(0 == iBearers->Count());
       
   234 	delete iBearers;
       
   235 
       
   236    	LOG_NODE_DESTROY(KEthLogTag2, CLANLinkCommon);
       
   237 }
       
   238 
       
   239 /**
       
   240 Checks the descriptor for a valid (non-zero) MAC address.
       
   241 @param aMacAddr A reference to a the descriptor containing the new MAC
       
   242 @return ETrue if the MAC address was non-zero, EFalse otherwise.
       
   243 */
       
   244 TBool CLANLinkCommon::CheckMac(TDes8& aMacAddr)
       
   245 {
       
   246 	for (TUint i=0;i<=5;i++)
       
   247 		{
       
   248 		if (aMacAddr[i] != 0)
       
   249 			return ETrue;
       
   250 		}
       
   251 	return EFalse;
       
   252 }
       
   253 
       
   254 /**
       
   255 This method is intended for use when a device does not have the correct MAC address when ARP is started
       
   256 (e.g. IRLAN). It must be called by the packet driver as soon as an interface address is available.
       
   257 It should be called before the packet driver sends LinkLayerUp to nifman,otherwise packets could
       
   258 be sent with an invalid hardware address.
       
   259 */
       
   260 EXPORT_C void CLANLinkCommon::FoundMACAddrL()
       
   261 {
       
   262 	iValidMacAddr = ReadMACSettings();
       
   263 }
       
   264 
       
   265 /**
       
   266 Link Layer Up
       
   267 Called by the packet driver when it is happy
       
   268 @internalTechnology
       
   269 */
       
   270 EXPORT_C void CLANLinkCommon::LinkLayerUp()
       
   271 {
       
   272 	//some drivers have a valid MAC only after negotiation finishes
       
   273 	iValidMacAddr = ReadMACSettings();
       
   274 	PostDataClientStartedMessage();
       
   275 
       
   276 	__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L ("CLANLinkCommon::LinkLayerUp()"));
       
   277 
       
   278 	/**
       
   279 	   With the new comms framework, this KLinkLayerOpen always sent and then will be caught and swallowed
       
   280 	   at the ipproto layer if a netcfgext is being used. */
       
   281 #ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   282 	if (LinkProvision().ConfigDaemonName().Length() == 0)
       
   283   		{
       
   284 #endif
       
   285 
       
   286 #ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   287 		}
       
   288 #endif
       
   289 
       
   290 	TUint bearerLim = iBearers->Count();
       
   291 	for(TUint index=0;index<bearerLim;index++)
       
   292 		{
       
   293 		CLanxBearer *bearer=(*iBearers)[index];
       
   294 		bearer->StartSending((CProtocolBase*)this);
       
   295 		}
       
   296 }
       
   297 
       
   298 EXPORT_C void CLANLinkCommon::LinkLayerDown(TInt aError, TAction aAction) // Notify the Protocol that the line is down
       
   299 /**
       
   300 Link Layer Down
       
   301 Called by the packet driver when the link has gone down
       
   302 
       
   303 @param aError error code
       
   304 @param aAction whether a reconnect is required or not
       
   305 @internalTechnology
       
   306 */
       
   307 	{
       
   308 	// If a stop was requested from the SCpr then this LinkLayerDown()
       
   309 	// was expected. This also means the SCpr has already been sent a
       
   310 	// TCFDataClient::TStopped and the packet driver has been stopped.
       
   311 	// If on the other hand the stop was not requested a TDataClientGoneDown
       
   312 	// message needs to be sent to the SCpr and the packet driver still
       
   313 	// needs a StopInterface call - usually this would mean that aAction
       
   314 	// is EReconnect
       
   315 	if (iStopRequested == EFalse && iMMState == EStarted)
       
   316 	    {
       
   317 	   
       
   318 	    PostFlowGoingDownMessage(aError, (aAction == EReconnect) ? MNifIfNotify::EReconnect : MNifIfNotify::EDisconnect);
       
   319 	    iPktDrv->StopInterface();
       
   320 		iMMState = EStopped;
       
   321 	    }
       
   322 	}
       
   323 
       
   324 /**
       
   325 Given the RMBufChain &aPdu, which contains a PktInfo at the start, Convert the PktInfo into
       
   326 an ether frame header. The source and dest address is already assumed to be filled, i.e.
       
   327 multi-cast or whatever. aPdu is returned modified.
       
   328 @param aPdu  Contains a PktInfo.
       
   329 @param aType The Ether type for the packet,
       
   330 @return  An error code, KErrNone if the Ethernet header could be prepended, or KErrGeneral
       
   331 		 if it could not.
       
   332 */
       
   333 TInt CLANLinkCommon::EtherFrame(RMBufChain &aPdu, TUint16 aType)
       
   334 {
       
   335 	TInt ret;
       
   336 	//To start with, we need a buffer for the ethernet header,
       
   337 	//and the packet info.
       
   338 
       
   339 	//Create an ether header
       
   340 	RMBufChain ethHdr;
       
   341 	TUint etherHeaderSize = (iEtherType==EStandardEthernet) ?
       
   342 	KEtherHeaderSize : KEtherLLCHeaderSize;
       
   343 	TRAP(ret, ethHdr.AllocL(etherHeaderSize));
       
   344 	if (ret != KErrNone)
       
   345 		{
       
   346 		return ret;
       
   347 		}
       
   348 	TEtherLLCFrame *hdrBuf=(TEtherLLCFrame*)ethHdr.First()->Buffer();
       
   349 
       
   350 	//Get the packet info:
       
   351 	RMBufPktInfo* info = RMBufPacket::PeekInfoInChain(aPdu);
       
   352 
       
   353 	// Fill in the dest, src Mac addresses:
       
   354 	hdrBuf->SetDestAddr(info->iDstAddr);
       
   355 	hdrBuf->SetSrcAddr(iMacAddr);
       
   356 	switch(iEtherType)
       
   357 		{
       
   358 		case EStandardEthernet:
       
   359 			BigEndian::Put16((TUint8*)&hdrBuf->iTypeLen,aType);
       
   360 			break;
       
   361 		case ELLCEthernet:
       
   362 			// Several fields to fill in. According to nifmbuf.h,
       
   363 			// info->iLength gives the actual length of the packet.
       
   364 			BigEndian::Put16((TUint8*)&hdrBuf->iTypeLen,static_cast<TInt16>(info->iLength));
       
   365 			hdrBuf->iDSAP=KLLC_SNAP_DSAP;
       
   366 			hdrBuf->iSSAP=KLLC_SNAP_SSAP;
       
   367 			hdrBuf->iCtrl=KLLC_SNAP_CTRL;
       
   368 			hdrBuf->SetOUI(0);
       
   369 			hdrBuf->SetType(aType);
       
   370 			break;
       
   371 		default:
       
   372 			// Can't handle any other kind of Ethernet header.
       
   373 			return KErrGeneral;
       
   374 		}
       
   375 	//Remove the original first Packet - by trimming the info from the packet.
       
   376 	TUint dummyLength=aPdu.Length(); // At this point, info becomes invalid.
       
   377 	aPdu.TrimStart(dummyLength-info->iLength);
       
   378 	//Finally, add the saved packet buffer to the mac header
       
   379 	aPdu.Prepend(ethHdr);
       
   380 	return KErrNone;
       
   381 }
       
   382 
       
   383 /**
       
   384 FrameSend frames the aPdu packet, giving it a type field defined by aType and then sends it via
       
   385 the packet driver's Send method, returning its return value. If there is an error framing the
       
   386 packet, the packet is dropped and KErrGeneral is returned.
       
   387 @param aPdu      The Packet to be sent (actually an RMBufPkt).
       
   388 @param aProtocol A pointer to the protocol which sent the packet (ignored)
       
   389 @param aType     The Type field in the Ethernet header when framing. For iEtherFrame== EStandardEthernet,
       
   390 				 this is stored in the iType field, for ELLCEthernet, this is stored in the
       
   391 				 iTypeHi:iTypeLo fields.
       
   392 @return 0 Tells the higher layer to send no more data else
       
   393 		1 Tells higher layer that it can send more data
       
   394 */
       
   395 TInt CLANLinkCommon::FrameSend(RMBufChain& aPdu,TAny* /*aProtocol*/, TUint16 aType)
       
   396 {
       
   397 	// Call down from the Protocol
       
   398 	// The data begins in the second MBuf - because the first one
       
   399 	// is the info. The upper layer must have filled in the destination
       
   400 	// and source Mac addresses before this method is called and must
       
   401 	// supply the ether header type in aType.
       
   402 	// EtherFrame strips off the info and replaces it by the proper
       
   403 	// ether header.
       
   404 
       
   405 	// Caller Flow controls off if the return to this method is <= 0
       
   406 	if(EtherFrame(aPdu,aType)==KErrNone)
       
   407 		{
       
   408 		// Dump it to the log in pcap format
       
   409 #ifdef TCPDUMP_LOGGING
       
   410 		//Find absolute time now
       
   411 		TTime timeNow;
       
   412 		timeNow.HomeTime();
       
   413 
       
   414 		iLogger->DumpFrame(timeNow,aPdu);
       
   415 #endif
       
   416 
       
   417 		return iPktDrv->Send(aPdu);
       
   418 		}
       
   419 	else
       
   420 		{ // drop the packet and return an error - incorrectly formatted.
       
   421 		// which error though?
       
   422 		aPdu.Free();
       
   423 		}
       
   424 	return KErrGeneral; // Should be a better error code though.
       
   425 }
       
   426 
       
   427 
       
   428 /**
       
   429 GetProtocolType extracts protocol header information from an ethernet packet and is called
       
   430 when processing a packet.
       
   431 @param  aPdu			 An Ethernet packet (actually, it is really an RMBufPkt with a packed
       
   432 						 info, not an RMBufChain)
       
   433 @param  aEtherType       The Ether type for the packet, which is the type field for the packet,
       
   434 						 for example: KIPFrameType (=0x800) or KIP6FrameType (0x8dd). Note:
       
   435 						 GetProtocolType makes no restrictions on valid EtherTypes, since
       
   436 						 this is handled by the bearers.
       
   437 @param  aPayloadPtr      A pointer to the beginning of the actual payload after the Ethernet
       
   438 					     header (or the Ethernet LLC header).
       
   439 @param  aEtherHeaderSize The size of the Ethernet header, either the standard ethernet header
       
   440 						 size (KEtherHeaderSize==14), or the LLC header size (KEtherLLCHeaderSize= standard+8).
       
   441 @return An error code, KErrNone, if a valid procol type could be extracted, or KErrNotSupported otherwise.
       
   442 */
       
   443 TInt CLANLinkCommon::GetProtocolType(RMBufChain& aPdu,
       
   444 									 TUint16& aEtherType, TUint8*& aPayloadPtr,
       
   445 									 TUint& aEtherHeaderSize) const
       
   446 {
       
   447 	RMBuf* chnptr=aPdu.First(); // Start of received packet
       
   448 	// Start of actual packet data  (Ethernet II)
       
   449 	TEtherFrame *etherFrame=(TEtherFrame*)(chnptr->Next()->Ptr());
       
   450 
       
   451 	if ((aEtherType=etherFrame->GetType())>=1536)
       
   452 		{ // Standard Ethernet type
       
   453 		__ASSERT_DEBUG(chnptr->Next()->Length() >= KEtherHeaderSize, Panic(EIeee802AddrBadMBuf));
       
   454 		__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L ("CLANLinkCommon::GetProtocolType ()  Got Ethernet-II-type frame"));
       
   455 
       
   456 		if (chnptr->Next()->Length() == KEtherHeaderSize)
       
   457 			{
       
   458 			aPayloadPtr = chnptr->Next()->Ptr();
       
   459 			}
       
   460 		else
       
   461 			{
       
   462 			aPayloadPtr = etherFrame->iData;
       
   463 			}
       
   464 		aEtherHeaderSize=KEtherHeaderSize;
       
   465 		}
       
   466 	else // It's an LLC Ethernet frame (802.3)
       
   467 		{
       
   468 		if(chnptr->Next()->Length() >= KEtherLLCHeaderSize)
       
   469 		    {
       
   470 		    TEtherLLCFrame *etherLLCFrame = (TEtherLLCFrame*)etherFrame;
       
   471 		    if(etherLLCFrame->iDSAP==KLLC_SNAP_DSAP &&
       
   472 			etherLLCFrame->iSSAP==KLLC_SNAP_SSAP &&
       
   473 			etherLLCFrame->iCtrl==KLLC_SNAP_CTRL)
       
   474 			{ // Valid LLC-SNAP Frame.
       
   475 			__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L ("CLANLinkCommon::GetProtocolType ()  Got 802.3-type frame, with LLC and SNAP headers"));
       
   476 			aEtherType=etherLLCFrame->GetType(); // Standard Ethernet type.
       
   477 			aPayloadPtr=etherLLCFrame->iData;
       
   478 			aEtherHeaderSize=KEtherLLCHeaderSize;
       
   479 			}
       
   480 		    else
       
   481 			{
       
   482 			__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L ("CLANLinkCommon::GetProtocolType ()  Got what initially looked like a 802.3-type frame, but no SNAP header"));
       
   483 			aEtherType=0;
       
   484 			aPayloadPtr=0;
       
   485 			aEtherHeaderSize=0;
       
   486 			return KErrNotSupported;
       
   487 			}
       
   488 		    }
       
   489 		else
       
   490 		    {
       
   491 	            return KErrCorrupt;
       
   492 		    }
       
   493 		}
       
   494 	return KErrNone;
       
   495 }
       
   496 
       
   497 /**
       
   498 Process processes a packet received from the packet driver.
       
   499 @param aPdu The Packet to be sent (actually an RMBufPkt).
       
   500 @param aLLC Unclear.
       
   501 */
       
   502 EXPORT_C void CLANLinkCommon::Process(RMBufChain& aPdu, TAny* /*aLLC*/)
       
   503 {
       
   504 	TUint16 etherCode;
       
   505 	TUint8* etherPtr;
       
   506 	TUint etherHeaderSize;
       
   507 	TBool packetProcessed=EFalse;
       
   508 	TInt ret=GetProtocolType(aPdu,etherCode,etherPtr,etherHeaderSize);
       
   509 	if (ret==KErrNone)
       
   510 		{ // It's an ethernet packet of some kind.
       
   511 
       
   512 		// Dump it to the log in pcap format
       
   513 #ifdef TCPDUMP_LOGGING
       
   514 		//Find absolute time now
       
   515 		TTime timeNow;
       
   516 		timeNow.HomeTime();
       
   517 
       
   518 		RMBufPacket& pkt = (RMBufPacket&)aPdu;
       
   519 		pkt.Unpack();
       
   520 		iLogger->DumpFrame(timeNow,aPdu);
       
   521 		pkt.Pack();
       
   522 #endif
       
   523 
       
   524 		TUint bearerLim = iBearers->Count();
       
   525 		for(TUint index=0;index<bearerLim && !packetProcessed;index++)
       
   526 			{
       
   527 			CLanxBearer* bearer=(*iBearers)[index];
       
   528 			if (BearerIsActive(bearer))
       
   529 				{
       
   530 				if(bearer->WantsProtocol(etherCode,etherPtr))
       
   531 					{
       
   532 					RMBufPacket& pkt = (RMBufPacket&)aPdu;
       
   533 					pkt.Unpack();
       
   534 					pkt.TrimStart(etherHeaderSize);
       
   535 					pkt.Pack();
       
   536 					bearer->Process(aPdu, (TAny*)(TUint32)etherCode);	// process expects ether type, but fixed function definition...
       
   537 					packetProcessed=ETrue;
       
   538 					}
       
   539 				}
       
   540 			}
       
   541 		}
       
   542 	if (ret!=KErrNone || !packetProcessed)
       
   543 		{
       
   544 		__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L ("CLANLinkCommon::Process() - dropping packet - unrecognised type"));
       
   545 		aPdu.Free(); // Something strange about the packet - bin it
       
   546 		}
       
   547 }
       
   548 
       
   549 /**
       
   550 Implementation of pure virtual from CLANLinkBase for use by the packet driver.
       
   551 Resume Sending is a notification call into NIF from the lower layer telling the NIF that a
       
   552 previous sending congestion situation has been cleared and it can accept more downstack data.
       
   553 NIF subsequently calls all the bearers' StartSending() methods directly.
       
   554 */
       
   555 EXPORT_C void CLANLinkCommon::ResumeSending()
       
   556 {
       
   557 	TUint bearerLim = iBearers->Count();
       
   558 	for(TUint index=0;index<bearerLim;index++)
       
   559 		{
       
   560 		CLanxBearer* bearer=(*iBearers)[index];
       
   561 		bearer->StartSending((CProtocolBase*)this);
       
   562 		}
       
   563 }
       
   564 
       
   565 /**
       
   566 
       
   567 */
       
   568 EXPORT_C TInt CLANLinkCommon::ReadInt(const TDesC& /*aField*/, TUint32& /*aValue*/)
       
   569 {
       
   570 	return KErrNotSupported;
       
   571 }
       
   572 
       
   573 /**
       
   574 
       
   575 */
       
   576 EXPORT_C TInt CLANLinkCommon::WriteInt(const TDesC& /*aField*/, TUint32 /*aValue*/)
       
   577 {
       
   578 	return KErrNotSupported;
       
   579 }
       
   580 
       
   581 /**
       
   582 
       
   583 */
       
   584 EXPORT_C TInt CLANLinkCommon::ReadDes(const TDesC& /*aField*/, TDes8& /*aValue*/)
       
   585 {
       
   586 	return KErrNotSupported;
       
   587 }
       
   588 
       
   589 /**
       
   590 
       
   591 */
       
   592 EXPORT_C TInt CLANLinkCommon::ReadDes(const TDesC& aField, TDes16& aValue)
       
   593 {
       
   594 	// Emulate reading of following parameters only:
       
   595 	// LAN_BEARER\LAN_BEARER_LDD_FILENAME
       
   596 	// LAN_BEARER\LAN_BEARER_LDD_NAME
       
   597 	// LAN_BEARER\LAN_BEARER_PDD_FILENAME
       
   598 	// LAN_BEARER\LAN_BEARER_PDD_NAME
       
   599 
       
   600 	_LIT(KLanBearer, "LANBearer\\");
       
   601 	const TInt KLanBearerTokenSize = 10;
       
   602 
       
   603 	TPtrC field(aField.Left(KLanBearerTokenSize));	// "LANBearer"
       
   604 
       
   605 	if (field.Compare(KLanBearer()) == 0)
       
   606 		{
       
   607 		_LIT(KLanBearerLddFilename, "LDDFilename");
       
   608 		_LIT(KLanBearerLddName, "LDDName");
       
   609 		_LIT(KLanBearerPddFilename, "PDDFilename");
       
   610 		_LIT(KLanBearerPddName, "PDDName");
       
   611 
       
   612 		field.Set(aField.Mid(KLanBearerTokenSize));	// skip "LANBearer\\"
       
   613 		if (field.CompareF(KLanBearerLddFilename) == 0)
       
   614 			{
       
   615 			aValue.Copy(LinkProvision().LddFilename());
       
   616 			}
       
   617 		else
       
   618 		if (field.CompareF(KLanBearerLddName) == 0)
       
   619 			{
       
   620 			aValue.Copy(LinkProvision().LddName());
       
   621 			}
       
   622 		else
       
   623 		if (field.CompareF(KLanBearerPddFilename) == 0)
       
   624 			{
       
   625 			aValue.Copy(LinkProvision().PddFilename());
       
   626 			}
       
   627 		else
       
   628 		if (field.CompareF(KLanBearerPddName) == 0)
       
   629 			{
       
   630 			aValue.Copy(LinkProvision().PddName());
       
   631 			}
       
   632 		else
       
   633 			{
       
   634 			return KErrNotSupported;
       
   635 			}
       
   636 		return KErrNone;
       
   637 		}
       
   638 	else
       
   639 		{
       
   640 		return KErrNotSupported;
       
   641 		}
       
   642 }
       
   643 
       
   644 /**
       
   645 
       
   646 */
       
   647 EXPORT_C TInt CLANLinkCommon::WriteDes(const TDesC& /*aField*/, const TDesC8& /*aValue*/)
       
   648 {
       
   649 	return KErrNotSupported;
       
   650 }
       
   651 
       
   652 /**
       
   653 
       
   654 */
       
   655 EXPORT_C TInt CLANLinkCommon::WriteDes(const TDesC& /*aField*/, const TDesC16& /*aValue*/)
       
   656 {
       
   657 	return KErrNotSupported;
       
   658 }
       
   659 
       
   660 /**
       
   661 
       
   662 */
       
   663 EXPORT_C TInt CLANLinkCommon::ReadBool(const TDesC& /*aField*/, TBool& /*aValue*/)
       
   664 {
       
   665 	return KErrNotSupported;
       
   666 }
       
   667 
       
   668 /**
       
   669 
       
   670 */
       
   671 EXPORT_C TInt CLANLinkCommon::WriteBool(const TDesC& /*aField*/, TBool /*aValue*/)
       
   672 {
       
   673 	return KErrNotSupported;
       
   674 }
       
   675 
       
   676 /**
       
   677 
       
   678 */
       
   679 EXPORT_C void CLANLinkCommon::IfProgress(TInt aStage, TInt aError)
       
   680 {
       
   681 	PostProgressMessage(aStage, aError);
       
   682 }
       
   683 
       
   684 /**
       
   685 
       
   686 */
       
   687 EXPORT_C void CLANLinkCommon::NifEvent(TNetworkAdaptorEventType /*aEventType*/, TUint /*aEvent*/, const TDesC8& /*aEventData*/, TAny* /*aSource*/)
       
   688 {
       
   689 }
       
   690 
       
   691 
       
   692 /**
       
   693 Load a factory and check the Uid etc
       
   694 function always opens factory CObject if successful
       
   695 */
       
   696 CPktDrvFactory* CLANLinkCommon::DoCreateDriverFactoryL(TUid aUid2,const TDesC& aFilename)
       
   697 {
       
   698 	TParse parse;
       
   699 	User::LeaveIfError(parse.Set(aFilename,0,0));
       
   700 
       
   701 	CPktDrvFactory* f=0;
       
   702 
       
   703 	TAutoClose<RLibrary> lib;
       
   704 	User::LeaveIfError(lib.iObj.Load(aFilename));
       
   705 	lib.PushL();
       
   706 	// The Uid check
       
   707 	if(lib.iObj.Type()[1]!=aUid2)
       
   708 		User::Leave(KErrBadLibraryEntryPoint);
       
   709 
       
   710 	TPktDrvFactoryNewL libEntry=(TPktDrvFactoryNewL)lib.iObj.Lookup(1);
       
   711 	if (libEntry==NULL)
       
   712 		User::Leave(KErrNoMemory);
       
   713 
       
   714 	f =(*libEntry)(); // Opens CObject (can leave)
       
   715 
       
   716 	CleanupStack::PushL(f);
       
   717 	f->Install(lib.iObj); // Transfers the library object if successful
       
   718 
       
   719 	// Can pop the library now - auto close will have no effect because handle is null
       
   720 	CleanupStack::Pop();
       
   721 	lib.Pop();
       
   722 
       
   723 	return f;
       
   724 }
       
   725 
       
   726 
       
   727 // ======================================================================================
       
   728 //
       
   729 // from MFlowBinderControl
       
   730 
       
   731 EXPORT_C MLowerControl* CLANLinkCommon::GetControlL(const TDesC8& aName)
       
   732 /**
       
   733 Request from upper CFProtocol to retrieve our MLowerControl class.
       
   734 
       
   735 @param aName Protocol Name.  Presently, only "ip" and "ip6" are supported.
       
   736 @return pointer to our MLowerControl class instance.  We leave on an error, hence this routine should
       
   737 never return NULL.
       
   738 */
       
   739 	{
       
   740 	CLanxBearer* bearer=NULL;
       
   741     if (aName.CompareF(KDescIp6) == 0)
       
   742     	{
       
   743         bearer = new(ELeave) CLanIp6Bearer(this);
       
   744         }
       
   745 	else if (aName.CompareF(KDescIp) == 0 || aName.CompareF(KDescIcmp) == 0)
       
   746 		{
       
   747         bearer = new(ELeave) CLanIp4Bearer(this);
       
   748         }
       
   749 	else
       
   750 		{
       
   751 		User::Leave(KErrNotSupported);
       
   752 		}
       
   753 
       
   754     CleanupStack::PushL(bearer);
       
   755     bearer->ConstructL();
       
   756 
       
   757 	// Must have provisioning information to operate
       
   758 	ASSERT(iLanLinkProvision);
       
   759 	iBearers->AppendL(bearer);
       
   760 	ProvisionBearerConfigL(aName);
       
   761     CleanupStack::Pop();
       
   762     return bearer;
       
   763 	}
       
   764 
       
   765 EXPORT_C MLowerDataSender* CLANLinkCommon::BindL(const TDesC8& aProtocol, MUpperDataReceiver* aReceiver, MUpperControl* aControl)
       
   766 /**
       
   767 Request from upper CFProtocol to bind to this module.
       
   768 
       
   769 @param aProtocol protocol name (e.g. "ip", "ip6" etc).
       
   770 @param aReceiver pointer to MUpperDataReceiver instance of upper CFProtocol
       
   771 @param aControl pointer to MUpperControl instance of upper CFProtocol
       
   772 @return pointer to our MLowerDataSender instance (eventually passed to the upper CFProtocol)
       
   773 */
       
   774 	{
       
   775 	TInt index = 0;
       
   776 	CLanxBearer* bearer = FindBearerByProtocolName(aProtocol, index);
       
   777 	if (bearer)
       
   778 		{
       
   779 		bearer->SetUpperPointers(aReceiver, aControl);
       
   780 		if (iValidMacAddr)
       
   781 			{
       
   782 			aControl->StartSending();
       
   783 			}
       
   784 		}
       
   785 	else
       
   786 		{
       
   787 		User::Leave(KErrNotSupported);
       
   788 		}
       
   789 
       
   790     iSubConnectionProvider.RNodeInterface::PostMessage(Id(), TCFControlProvider::TActive().CRef());
       
   791 	return bearer;
       
   792 	}
       
   793 
       
   794 EXPORT_C void CLANLinkCommon::Unbind(MUpperDataReceiver* /*aReceiver*/, MUpperControl* aControl)
       
   795 /**
       
   796 Request from upper CFProtocol to unbind from this module.
       
   797 
       
   798 @param aReceiver pointer to data receiver class of upper CFProtocol (originally passed to it in downward BindL() request)
       
   799 @param aControl pointer to control class of upper CFProtocol (originally passed to it in downward BindL() request)
       
   800 */
       
   801 
       
   802 	{
       
   803 	TInt index = 0;
       
   804 	CLanxBearer* bearer = FindBearerByUpperControl(aControl, index);
       
   805 	ASSERT(bearer);
       
   806 	iBearers->Delete(index);
       
   807 	delete bearer;
       
   808 
       
   809 	// If no-one remains bound to us, signal data client idle to SCPR
       
   810 	MaybePostDataClientIdle();
       
   811 	}
       
   812 
       
   813 
       
   814 //
       
   815 // Utilities
       
   816 //
       
   817 
       
   818 CLanxBearer* CLANLinkCommon::FindBearerByProtocolName(const TDesC8& aProtocol, TInt& aIndex) const
       
   819 /**
       
   820 Search the iBearers array searching for a match by protocol name.
       
   821 
       
   822 @param aProtocol name of protocol (in)
       
   823 @param aIndex on success, index of found entry (>=0), else -1.
       
   824 @return pointer to CLanxBearer entry on success else NULL.
       
   825 */
       
   826 	{
       
   827 	TInt count = iBearers->Count();
       
   828 	for (TInt i = 0 ; i < count ; ++i)
       
   829 		{
       
   830 		CLanxBearer* bearer = iBearers->At(i);
       
   831 		if (bearer->ProtocolName() == aProtocol)
       
   832 			{
       
   833 			aIndex = i;
       
   834 			return bearer;
       
   835 			}
       
   836 		}
       
   837 	aIndex = -1;
       
   838 	return NULL;
       
   839 	}
       
   840 
       
   841 CLanxBearer* CLANLinkCommon::FindBearerByUpperControl(const MUpperControl* aUpperControl, TInt& aIndex) const
       
   842 /**
       
   843 Search the iBearers array searching for a match by protocol name.
       
   844 
       
   845 @param aProtocol name of protocol (in)
       
   846 @param aIndex on success, index of found entry (>=0), else -1.
       
   847 @return pointer to CLanxBearer entry on success else NULL.
       
   848 */
       
   849 	{
       
   850 	TInt count = iBearers->Count();
       
   851 	for (TInt i = 0 ; i < count ; ++i)
       
   852 		{
       
   853 		CLanxBearer* bearer = iBearers->At(i);
       
   854 		if (bearer->MatchesUpperControl(aUpperControl))
       
   855 			{
       
   856 			aIndex = i;
       
   857 			return bearer;
       
   858 			}
       
   859 		}
       
   860 	aIndex = -1;
       
   861 	return NULL;
       
   862 	}
       
   863 
       
   864 // =====================================================================================
       
   865 //
       
   866 // Messages::ANode
       
   867 
       
   868 EXPORT_C void CLANLinkCommon::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage)
       
   869 /**
       
   870 Routine called on an incoming message from SCPR
       
   871 
       
   872 @param aCFMessage incoming message
       
   873 @return KErrNone, else a system wide error code.
       
   874 */
       
   875     {
       
   876     CSubConnectionFlowBase::ReceivedL(aSender, aRecipient, aMessage);
       
   877 	if (TEBase::ERealmId == aMessage.MessageId().Realm())
       
   878 		{
       
   879 		switch (aMessage.MessageId().MessageId())
       
   880 			{
       
   881 		case TEBase::TError::EId :
       
   882 			SubConnectionError(static_cast<TEBase::TError&>(aMessage).iValue);
       
   883 			break;
       
   884 		case TEBase::TCancel::EId :
       
   885 			CancelStartFlow();
       
   886 			break;
       
   887 		default:
       
   888 			ASSERT(EFalse);
       
   889 			}
       
   890 		}
       
   891 	else if (TEChild::ERealmId == aMessage.MessageId().Realm())
       
   892 		{
       
   893 		switch (aMessage.MessageId().MessageId())
       
   894 			{
       
   895 		case TEChild::TDestroy::EId :
       
   896 			Destroy();
       
   897 			break;
       
   898 		default:
       
   899 			ASSERT(EFalse);
       
   900 			}
       
   901 		}
       
   902 	else if (TCFDataClient::ERealmId == aMessage.MessageId().Realm())
       
   903 		{
       
   904 		switch (aMessage.MessageId().MessageId())
       
   905 			{
       
   906 		case TCFDataClient::TStart::EId :
       
   907 			StartFlowL();
       
   908 			break;
       
   909 		case TCFDataClient::TProvisionConfig::EId :
       
   910 			ProvisionConfig(static_cast<TCFDataClient::TProvisionConfig&>(aMessage).iConfig);
       
   911 			break;
       
   912 		case TCFDataClient::TStop::EId :
       
   913 			StopFlow(static_cast<TCFDataClient::TStop&>(aMessage).iValue);
       
   914 			break;
       
   915 		case TCFDataClient::TBindTo::EId :
       
   916             { 
       
   917 			TCFDataClient::TBindTo& bindToReq = message_cast<TCFDataClient::TBindTo>(aMessage);
       
   918 			if (!bindToReq.iNodeId.IsNull())
       
   919 				{
       
   920 				User::Leave(KErrNotSupported);
       
   921 				}
       
   922 			RClientInterface::OpenPostMessageClose(Id(), aSender, TCFDataClient::TBindToComplete().CRef());
       
   923             }
       
   924 			break;
       
   925 		default:
       
   926 			ASSERT(EFalse);
       
   927 			}
       
   928 		}
       
   929 	else if (TLinkMessage::ERealmId == aMessage.MessageId().Realm())
       
   930 		{
       
   931 		switch (aMessage.MessageId().MessageId())
       
   932 			{
       
   933 		case TLinkMessage::TAgentToFlowNotification::EId:
       
   934 			{
       
   935 			TLinkMessage::TAgentToFlowNotification& msg = message_cast<TLinkMessage::TAgentToFlowNotification>(aMessage);
       
   936 			if(msg.iValue < KVendorSpecificNotificationStart)
       
   937 				{
       
   938 				User::Leave(KErrNotSupported);
       
   939 				}
       
   940 			else
       
   941 				{
       
   942 				User::LeaveIfError((iPktDrv) ? iPktDrv->Notification(
       
   943 					static_cast<TAgentToNifEventType>(msg.iValue), NULL) : KErrNotSupported);
       
   944 				}
       
   945 			}
       
   946 			break;
       
   947 		default:
       
   948 			ASSERT(EFalse);
       
   949 			}; //endswitch
       
   950 		}
       
   951 	else		// (message and realm not recognised within this domain)
       
   952 		{
       
   953 		ASSERT(EFalse);
       
   954 		}
       
   955     }
       
   956 
       
   957 //
       
   958 // Methods for handling incoming SCPR messages
       
   959 //
       
   960 
       
   961 void CLANLinkCommon::StartFlowL()
       
   962 	{
       
   963 	iStopRequested = EFalse;
       
   964 
       
   965 	ASSERT(iMMState == EStopped);
       
   966 
       
   967 	if (iSavedError != KErrNone)
       
   968 		{
       
   969 		// If there were errors during prior processing of the TProvisionConfig message,
       
   970 		// leave here and cause a TError response to TCFDataClient::TStart.
       
   971 		User::Leave(iSavedError);
       
   972 		}
       
   973 
       
   974 	iValidMacAddr = ReadMACSettings();
       
   975 
       
   976 	__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Starting Interface"));
       
   977 	iMMState = EStarting;
       
   978 	User::LeaveIfError(iPktDrv->StartInterface());
       
   979 	}
       
   980 
       
   981 
       
   982 void CLANLinkCommon::CancelStartFlow()
       
   983     {
       
   984     if (iMMState == EStarting)
       
   985         {
       
   986     	iStopRequested = ETrue;
       
   987 
       
   988     	iPktDrv->StopInterface();
       
   989     	PostFlowDownMessage(KErrCancel);
       
   990 		}
       
   991     }
       
   992 
       
   993 void CLANLinkCommon::StopFlow(TInt aError)
       
   994 	{
       
   995 	iStopRequested = ETrue;
       
   996 	iMMState = EStopping;
       
   997 
       
   998 	iPktDrv->StopInterface();
       
   999 	PostFlowDownMessage(aError);
       
  1000 	}
       
  1001 
       
  1002 void CLANLinkCommon::SubConnectionGoingDown()
       
  1003 	{
       
  1004 	}
       
  1005 
       
  1006 void CLANLinkCommon::SubConnectionError(TInt /*aError*/)
       
  1007 	{
       
  1008 	}
       
  1009 
       
  1010 
       
  1011 /*
       
  1012 Provisioning description for Ethernet CFProtocol Flow:
       
  1013 
       
  1014 - on receipt of the TProvisionConfig message, the pointer contained within is stored
       
  1015   in iAccessPointConfig and the provisioning information contained within the AccessPointConfig
       
  1016   array is validated:
       
  1017 	- TLanLinkProvision must be present.  It is added by the EtherMCPr and populated from CommsDat.  A pointer to it
       
  1018 	  is stored in iLanLinkProvision.
       
  1019 	- at least one of TLanIp4Provision or TLanIp6Provision must be present.  They are added by the EtherMCPr and
       
  1020 	  populated from CommsDat.
       
  1021 
       
  1022 - the packet driver is loaded.
       
  1023 
       
  1024 - if any of the above steps fail, the resulting error is saved in iSaveError so that when TCFDataClient::TStart message is
       
  1025   subsequently received, a TError message can be sent in response (there is no response to TProvisionConfig message).
       
  1026 */
       
  1027 
       
  1028 void CLANLinkCommon::ProvisionConfig(const RMetaExtensionContainerC& aConfigData)
       
  1029 	{
       
  1030 	__FLOG_STATIC(KEther802LogTag1,KEthLogTag2,_L("CLANLinkCommon:\tProvisionConfig message received"));
       
  1031 
       
  1032 	AccessPointConfig().Close();
       
  1033 	AccessPointConfig().Open(aConfigData);
       
  1034 	
       
  1035     ASSERT(iLanLinkProvision == NULL); // Should only happen once
       
  1036 
       
  1037     iLanLinkProvision = static_cast<const TLanLinkProvision*>(AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TLanLinkProvision::EUid, TLanLinkProvision::ETypeId)));
       
  1038     if (iLanLinkProvision == NULL)
       
  1039         {
       
  1040         __FLOG_STATIC(KEther802LogTag1,KEthLogTag2,_L("CLANLinkCommon:\tProvisionConfig() - no Ethernet Link configuration"));
       
  1041 		iSavedError = KErrCorrupt;
       
  1042 		return;
       
  1043         }
       
  1044 
       
  1045     iLanIp4Provision = static_cast<const TLanIp4Provision*>(AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TLanIp4Provision::EUid, TLanIp4Provision::ETypeId)));
       
  1046     if (iLanIp4Provision == NULL)
       
  1047         {
       
  1048         __FLOG_STATIC(KEther802LogTag1,KEthLogTag2,_L("CLANLinkCommon:\tProvisionConfig() - no IP4 configuration"));
       
  1049         }
       
  1050 
       
  1051     iLanIp6Provision = static_cast<const TLanIp6Provision*>(AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TLanIp6Provision::EUid, TLanIp6Provision::ETypeId)));
       
  1052     if (iLanIp6Provision == NULL)
       
  1053         {
       
  1054         __FLOG_STATIC(KEther802LogTag1,KEthLogTag2,_L("CLANLinkCommon:\tProvisionConfig() - no IP6 config provisioned"));
       
  1055         }
       
  1056 
       
  1057 	if (iLanIp4Provision == NULL && iLanIp6Provision == NULL)
       
  1058 		{
       
  1059 		// At least one set of IP4/6 provisioning information must be present
       
  1060 		iSavedError = KErrCorrupt;
       
  1061 		return;
       
  1062 		}
       
  1063 
       
  1064     TRAPD(err, ProvisionConfigL());
       
  1065     if (err != KErrNone)
       
  1066         {
       
  1067         iSavedError = err;
       
  1068         }
       
  1069     }
       
  1070 
       
  1071 
       
  1072 void CLANLinkCommon::ProvisionConfigL()
       
  1073 	{
       
  1074 	// Provision Bearers
       
  1075 	if (iBearers->Count())
       
  1076 		{
       
  1077 	    ProvisionBearerConfigL(KDescIp());
       
  1078 		ProvisionBearerConfigL(KDescIp6());
       
  1079 		}
       
  1080 
       
  1081 	__FLOG_STATIC(KEther802LogTag1, KEthLogTag2, _L("Loading packet driver"));
       
  1082     LoadPacketDriverL();
       
  1083 	}
       
  1084 
       
  1085 void CLANLinkCommon::Destroy()
       
  1086 	{
       
  1087 	ASSERT(iMMState==EStopped);
       
  1088 	DeleteThisFlow();
       
  1089 	}
       
  1090 
       
  1091 // Utility functions
       
  1092 
       
  1093 void CLANLinkCommon::ProvisionBearerConfigL(const TDesC8& aName)
       
  1094 	{
       
  1095 	TInt index = -1;
       
  1096 	CLanxBearer* bearer = FindBearerByProtocolName(aName, index);
       
  1097 	if (bearer)
       
  1098 		{
       
  1099         if (aName.CompareF(KDescIp) == 0)
       
  1100 		    {
       
  1101 		    if (iLanIp4Provision)
       
  1102 		        {
       
  1103 		        bearer->SetProvisionL(iLanIp4Provision); // CLanIp4Bearer
       
  1104 		        }
       
  1105 		    }
       
  1106 		else if (aName.CompareF(KDescIp6) == 0)
       
  1107 		    {
       
  1108 		    if (iLanIp6Provision)
       
  1109 		        {
       
  1110 		        bearer->SetProvisionL(iLanIp6Provision); // CLanIp6Bearer
       
  1111 		        }
       
  1112 		    }
       
  1113 		}
       
  1114 	}
       
  1115 
       
  1116 void CLANLinkCommon::PostProgressMessage(TInt aStage, TInt aError)
       
  1117 	{
       
  1118 	//Be careful when sending TStateChange message as RNodeChannelInterface will override the activity id
       
  1119 	iSubConnectionProvider.RNodeInterface::PostMessage(Id(), TCFMessage::TStateChange(TStateChange( aStage, aError)).CRef());
       
  1120 	}
       
  1121 
       
  1122 void CLANLinkCommon::PostFlowDownMessage(TInt aError)
       
  1123 	{
       
  1124 	if (iMMState == EStopping)
       
  1125     	{
       
  1126     	iLastRequestOriginator.ReplyTo(Id(), TCFDataClient::TStopped(aError).CRef());
       
  1127     	}
       
  1128     else if (iMMState == EStarting)
       
  1129     	{
       
  1130     	iLastRequestOriginator.ReplyTo(Id(), TEBase::TError(TCFDataClient::TStart::Id(), aError).CRef());
       
  1131     	}
       
  1132     else if (iMMState == EStarted)
       
  1133     	{
       
  1134     	iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TDataClientGoneDown(aError).CRef());
       
  1135     	}
       
  1136     iMMState = EStopped;
       
  1137 	}
       
  1138 
       
  1139 void CLANLinkCommon::PostFlowGoingDownMessage(TInt aError, MNifIfNotify::TAction aAction)
       
  1140 	{
       
  1141 	// TDataClientGoneDown only makes sense if the flow was actually started
       
  1142 	ASSERT(iMMState == EStarted);
       
  1143 	iMMState = EStopped;
       
  1144 	iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TDataClientGoneDown(aError, aAction).CRef());
       
  1145 	}
       
  1146 
       
  1147 void CLANLinkCommon::PostDataClientStartedMessage()
       
  1148 	{
       
  1149 	iMMState = EStarted;
       
  1150 	iLastRequestOriginator.ReplyTo(Id(), TCFDataClient::TStarted().CRef());
       
  1151 	}
       
  1152 
       
  1153 void CLANLinkCommon::MaybePostDataClientIdle()
       
  1154 	{
       
  1155 	if (iBearers->Count() == 0)
       
  1156 		{
       
  1157 		iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TIdle().CRef());
       
  1158 		}
       
  1159 	}
       
  1160 
       
  1161 
       
  1162 /**
       
  1163 Sets the BigEndian 32-bit value at iDstAddr to aDestAddr
       
  1164 Support methods for TEtherLLCFrame.
       
  1165 Note: These Methods should really go in a file for themselves.
       
  1166 @param aDest The destination IP address.
       
  1167 */
       
  1168 void TEtherLLCFrame::SetDestAddr( TDesC8& aDest)
       
  1169 {
       
  1170 	// copied a word at a time, remember BigEndian portability.
       
  1171 	for(TUint ix=0; ix<3; ix++)
       
  1172 		{
       
  1173 		BigEndian::Put16((TUint8*)&iDestAddr[ix],(TUint16)(((aDest[ix*2]<<8)|aDest[ix*2+1])&0xffff));
       
  1174 		}
       
  1175 }
       
  1176 
       
  1177 /**
       
  1178 Sets the BigEndian 32-bit value at iSrcAddr to aSrcAddr.
       
  1179 @param aSrc The source IP address.
       
  1180 */
       
  1181 void TEtherLLCFrame::SetSrcAddr(TDesC8& aSrc)
       
  1182 {
       
  1183 	for(TUint ix=0; ix<3; ix++)
       
  1184 		{
       
  1185 		BigEndian::Put16((TUint8*)&iSrcAddr[ix],(TUint16)(((aSrc[ix*2]<<8)|aSrc[ix*2+1])&0xffff));
       
  1186 		}
       
  1187 }
       
  1188 
       
  1189 /**
       
  1190 aOUI is in native order, but the result is always stored in network byte order.
       
  1191 Can't use the bigendian methods, because they only work for 16 and 32 -bit items.
       
  1192 @param aOUI Byte order.
       
  1193 */
       
  1194 void TEtherLLCFrame::SetOUI(TUint32 aOUI)
       
  1195 {
       
  1196 	//aOUI is in native order, but the result is
       
  1197 	//always stored in network byte order.
       
  1198 	//Can't use the bigendian methods, because
       
  1199 	//they only work for 16 and 32 -bit items.
       
  1200 	OUI[0] = (TUint8)((aOUI>>16)&0xff);
       
  1201 	OUI[1] = (TUint8)((aOUI>>8)&0xff);
       
  1202 	OUI[2] = (TUint8)(aOUI&0xff);
       
  1203 }
       
  1204 
       
  1205 const TLanLinkProvision& CLANLinkCommon::LinkProvision()
       
  1206 	{
       
  1207 	return *iLanLinkProvision;
       
  1208 	}
       
  1209 
       
  1210 void CLANLinkCommon::SetAllowedBearer(CLanxBearer* aBearer)
       
  1211 	{
       
  1212 		iOnlyThisBearer = aBearer;
       
  1213 	}
       
  1214  TBool CLANLinkCommon::BearerIsActive(CLanxBearer* aBearer)
       
  1215 	{
       
  1216 		if (!iOnlyThisBearer ||
       
  1217 				aBearer == iOnlyThisBearer)
       
  1218 			{
       
  1219 			return ETrue;
       
  1220 			}
       
  1221 		return EFalse;
       
  1222 	}
       
  1223