wlan_bearer/wlannwif/src/Wlanbase.cpp
changeset 0 c40eb8fe8501
equal deleted inserted replaced
-1:000000000000 0:c40eb8fe8501
       
     1 /*
       
     2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implements functions for LAN interface
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 24 %
       
    20 */
       
    21 
       
    22 #include <f32file.h>
       
    23 #include <e32std.h> // for TTime
       
    24 #include <nifvar.h>
       
    25 #include <nifutl.h>
       
    26 #include <es_mbuf.h>
       
    27 #include <nifmbuf.h>
       
    28 #include <comms-infras/nifprvar.h>
       
    29 #include <comms-infras/connectionsettings.h>  // for KSlashChar
       
    30 #include <commdb.h>
       
    31 #include "WlanProto.h"
       
    32 #include "carddrv.h"
       
    33 #include <in_sock.h> // Header is retained, but in_sock.h is modified for ipv6
       
    34 #include "CLanIp4Bearer.h"
       
    35 #include "CLanIp6Bearer.h"
       
    36 #include <cdbcols.h>
       
    37 #include <cdblen.h>
       
    38 #include "CLanxBearer.h"
       
    39 #include "WlanProvision.h"
       
    40 #include <comms-infras/ss_metaconnprov.h> // for SAccessPointConfig
       
    41 #include <comms-infras/linkmessages.h>
       
    42 #include <elements/nm_messages_base.h>
       
    43 #include <elements/nm_messages_child.h>
       
    44 
       
    45 // From old wlan implementation
       
    46 #include <ip4_hdr.h>
       
    47 #include <ip6_hdr.h>
       
    48 #include <centralrepository.h>
       
    49 #include "am_debug.h"
       
    50 #include "EtherCardApi.h"
       
    51 #include "wlandevicesettingsinternalcrkeys.h"
       
    52 #include "NifWLMServerIf.h"
       
    53 
       
    54 
       
    55 using namespace ESock;
       
    56 using namespace Messages;
       
    57 
       
    58 _LIT8(KDescIp, "ip");
       
    59 _LIT8(KDescIcmp, "icmp");
       
    60 _LIT8(KDescIp6, "ip6");
       
    61 
       
    62 const TInt KLanxBearerPtrArrayGranularity = 2;
       
    63 const TInt KContinueSending = 1;
       
    64 const TInt KMaxDSCPValues = 64;
       
    65 
       
    66 /**
       
    67  * Mapping of user priority values to the corresponding access classes.
       
    68  */
       
    69 const TWlmAccessClass KUPtoAC[E8021DUserPriorityMax] =
       
    70     {
       
    71     EWlmAccessClassBestEffort,      // E8021DUserPriorityBE
       
    72     EWlmAccessClassBackground,      // E8021DUserPriorityBK1
       
    73     EWlmAccessClassBackground,      // E8021DUserPriorityBK2
       
    74     EWlmAccessClassBestEffort,      // E8021DUserPriorityEE
       
    75     EWlmAccessClassVideo,           // E8021DUserPriorityCL
       
    76     EWlmAccessClassVideo,           // E8021DUserPriorityVI
       
    77     EWlmAccessClassVoice,           // E8021DUserPriorityVO
       
    78     EWlmAccessClassVoice,           // E8021DUserPriorityNC
       
    79     };
       
    80 
       
    81 /**
       
    82  * Mapping of access class transitions on packet downgrade.
       
    83  */
       
    84 const TWlmAccessClass KNextAC[EWlmAccessClassMax] =
       
    85     {
       
    86     EWlmAccessClassBackground,      // EWlmAccessClassBestEffort -> EWlmAccessClassBackground
       
    87     EWlmAccessClassMax,             // EWlmAccessClassBackground -> EWlmAccessClassMax
       
    88     EWlmAccessClassBestEffort,      // EWlmAccessClassVideo -> EWlmAccessClassBestEffort
       
    89     EWlmAccessClassVideo            // EWlmAccessClassVoice -> EWlmAccessClassVideo
       
    90     };
       
    91 
       
    92 /**
       
    93  * Mapping of IP TOS (DSCP) bits to the corresponding user priority values.
       
    94  */
       
    95 const T8021DPriority KDSCPtoUP[KMaxDSCPValues] =
       
    96     {
       
    97     /* DSCP bits as binary format, DSCP byte in IPv4 packet as HEX */
       
    98     
       
    99     /* 000000, 0x00 */E8021DUserPriorityBE,  /* 000001, 0x04 */E8021DUserPriorityBE,  
       
   100     /* 000010, 0x08 */E8021DUserPriorityBE,  /* 000011, 0x0C */E8021DUserPriorityBE,
       
   101     /* 000100, 0x10 */E8021DUserPriorityBE,  /* 000101, 0x14 */E8021DUserPriorityBE,  
       
   102     /* 000110, 0x18 */E8021DUserPriorityBE,  /* 000111, 0x1C */E8021DUserPriorityBE,
       
   103     /* 001000, 0x20 */E8021DUserPriorityBK1, /* 001001, 0x24 */E8021DUserPriorityBK1,  
       
   104     /* 001010, 0x28 */E8021DUserPriorityEE,  /* 001011, 0x2C */E8021DUserPriorityEE,
       
   105     /* 001100, 0x30 */E8021DUserPriorityEE,  /* 001101, 0x34 */E8021DUserPriorityEE,  
       
   106     /* 001110, 0x38 */E8021DUserPriorityEE,  /* 001111, 0x3C */E8021DUserPriorityEE,
       
   107 
       
   108     /* 010000, 0x40 */E8021DUserPriorityEE,  /* 010001, 0x44 */E8021DUserPriorityEE,  
       
   109     /* 010010, 0x48 */E8021DUserPriorityEE,  /* 010011, 0x4C */E8021DUserPriorityEE,
       
   110     /* 010100, 0x50 */E8021DUserPriorityEE,  /* 010101, 0x54 */E8021DUserPriorityEE,  
       
   111     /* 010110, 0x58 */E8021DUserPriorityEE,  /* 010111, 0x5C */E8021DUserPriorityEE,
       
   112     /* 011000, 0x60 */E8021DUserPriorityVI,  /* 011001, 0x64 */E8021DUserPriorityVI,  
       
   113     /* 011010, 0x68 */E8021DUserPriorityVI,  /* 011011, 0x6C */E8021DUserPriorityVI,
       
   114     /* 011100, 0x70 */E8021DUserPriorityVI,  /* 011101, 0x74 */E8021DUserPriorityVI,  
       
   115     /* 011110, 0x78 */E8021DUserPriorityVI,  /* 011111, 0x7C */E8021DUserPriorityVI,
       
   116 
       
   117     /* 100000, 0x80 */E8021DUserPriorityVI,  /* 100001, 0x84 */E8021DUserPriorityVI,  
       
   118     /* 100010, 0x88 */E8021DUserPriorityVI,  /* 100011, 0x8C */E8021DUserPriorityVI,
       
   119     /* 100100, 0x90 */E8021DUserPriorityVI,  /* 100101, 0x94 */E8021DUserPriorityVI,  
       
   120     /* 100110, 0x98 */E8021DUserPriorityVI,  /* 100111, 0x9C */E8021DUserPriorityVI,
       
   121     /* 101000, 0xA0 */E8021DUserPriorityCL,  /* 101001, 0xA4 */E8021DUserPriorityCL,  
       
   122     /* 101010, 0xA8 */E8021DUserPriorityCL,  /* 101011, 0xAC */E8021DUserPriorityCL,
       
   123     /* 101100, 0xB0 */E8021DUserPriorityCL,  /* 101101, 0xB4 */E8021DUserPriorityCL,  
       
   124     /* 101110, 0xB8 */E8021DUserPriorityVO,  /* 101111, 0xBC */E8021DUserPriorityVO,
       
   125 
       
   126     /* 110000, 0xC0 */E8021DUserPriorityNC,  /* 110001, 0xC4 */E8021DUserPriorityNC,  
       
   127     /* 110010, 0xC8 */E8021DUserPriorityNC,  /* 110011, 0xCC */E8021DUserPriorityNC,
       
   128     /* 110100, 0xD0 */E8021DUserPriorityNC,  /* 110101, 0xD4 */E8021DUserPriorityNC,  
       
   129     /* 110110, 0xD8 */E8021DUserPriorityNC,  /* 110111, 0xDC */E8021DUserPriorityNC,
       
   130     /* 111000, 0xE0 */E8021DUserPriorityNC,  /* 111001, 0xE4 */E8021DUserPriorityNC,  
       
   131     /* 111010, 0xE8 */E8021DUserPriorityNC,  /* 111011, 0xEC */E8021DUserPriorityNC,
       
   132     /* 111100, 0xF0 */E8021DUserPriorityNC,  /* 111101, 0xF4 */E8021DUserPriorityNC,  
       
   133     /* 111110, 0xF8 */E8021DUserPriorityNC,  /* 111111, 0xFC */E8021DUserPriorityNC
       
   134     };
       
   135 
       
   136 /**
       
   137  * Inactivity timeouts per access class.
       
   138  */
       
   139 const TUint KTsInactivityTime[EWlmAccessClassMax] =
       
   140     {
       
   141     600000000,    // 600 seconds for EWlmAccessClassBestEffort
       
   142     600000000,    // 600 seconds for EWlmAccessClassBackground
       
   143     120000000,    // 120 seconds for EWlmAccessClassVideo
       
   144     30000000,     // 30 seconds for EWlmAccessClassVoice
       
   145     };
       
   146 
       
   147 EXPORT_C CLANLinkCommon::CLANLinkCommon(CSubConnectionFlowFactoryBase& aFactory, const TNodeId& aSubConnId, CProtocolIntfBase* aProtocolIntf)
       
   148   : CSubConnectionFlowBase(aFactory, aSubConnId, aProtocolIntf), iMMState(EStopped)
       
   149     {
       
   150     DEBUG("CLANLinkCommon::CLANLinkCommon()");
       
   151     LOG_NODE_CREATE(KWlanLog, CLANLinkCommon);
       
   152     }
       
   153 
       
   154 
       
   155 // -----------------------------------------------------------------------------
       
   156 // CLANLinkCommon::LoadPacketDriverL
       
   157 // -----------------------------------------------------------------------------
       
   158 //
       
   159 void CLANLinkCommon::LoadPacketDriverL()
       
   160     {
       
   161     DEBUG("CLANLinkCommon::LoadPacketDriverL() - Creates only new class instance");
       
   162 
       
   163     iPktDrv = CPcCardPktDrv::NewL( this ); 
       
   164     }
       
   165 
       
   166 // -----------------------------------------------------------------------------
       
   167 // CLANLinkCommon::NewL
       
   168 // -----------------------------------------------------------------------------
       
   169 //
       
   170 EXPORT_C CLANLinkCommon* CLANLinkCommon::NewL(CSubConnectionFlowFactoryBase& aFactory, const TNodeId& aSubConnId, CProtocolIntfBase* aProtocolIntf)
       
   171     {
       
   172     DEBUG("CLANLinkCommon::NewL()");
       
   173   
       
   174     CLANLinkCommon* s=new (ELeave) CLANLinkCommon(aFactory, aSubConnId, aProtocolIntf);
       
   175     CleanupStack::PushL(s);
       
   176     s->ConstructL();
       
   177     CleanupStack::Pop(s);
       
   178     return s;
       
   179     }
       
   180 
       
   181 // -----------------------------------------------------------------------------
       
   182 // CLANLinkCommon::ReadMACSettings
       
   183 // -----------------------------------------------------------------------------
       
   184 //
       
   185 TBool CLANLinkCommon::ReadMACSettings()
       
   186     {
       
   187     DEBUG("CLANLinkCommon::ReadMACSettings()");
       
   188 
       
   189     TBuf8<KMACByteLength> drvMacAddr;
       
   190     TUint8* config=iPktDrv->GetInterfaceAddress();
       
   191     drvMacAddr.Append(&config[0],KMACByteLength); // First 3 bytes of config not part of address
       
   192     iMacAddr.Copy(drvMacAddr); // update Ethints copy of the MAC address
       
   193     TUint bearerLim = iBearers->Count();
       
   194     for(TUint index=0;index<bearerLim;index++)
       
   195         {
       
   196         CLanxBearer* bearer=(*iBearers)[index];
       
   197         bearer->UpdateMACAddr();
       
   198         }
       
   199 
       
   200     // check that the macaddress has been passed and is not 0;
       
   201     return CheckMac(iMacAddr); // wrong.
       
   202     }
       
   203 
       
   204 // -----------------------------------------------------------------------------
       
   205 // CLANLinkCommon::Mtu
       
   206 // -----------------------------------------------------------------------------
       
   207 //
       
   208 TUint CLANLinkCommon::Mtu() const 
       
   209     {
       
   210     DEBUG("CLanLinkCommon::Mtu()");
       
   211     
       
   212     TInt err = KErrNone;
       
   213     CRepository* repository = NULL;
       
   214     TRAP( err, repository = CRepository::NewL( KCRUidWlanDeviceSettingsRegistryId ) );
       
   215     if( err != KErrNone )
       
   216         {
       
   217         DEBUG1( "Could not access repository (%d), using default value for mtu(1500)", err );
       
   218         return KEtherMaxDataLen;
       
   219         }
       
   220     // No need to use CleanupStack because no possibility to leave
       
   221 
       
   222     TInt temp = 0;
       
   223     err = repository->Get( KWlanMTU, temp );
       
   224     if( err == KErrNone ) 
       
   225         {
       
   226         delete repository;
       
   227         DEBUG1("MTU value from cenrep is:%d", temp);
       
   228         if( temp > KEtherMaxDataLen || temp <= 0 )
       
   229             {
       
   230             DEBUG("MTU from cenrep is out of range 1-1500, setting it to 1500");
       
   231             temp = KEtherMaxDataLen;
       
   232             }
       
   233         return temp;
       
   234         }
       
   235     else
       
   236         {
       
   237         DEBUG1( "Could not access repository (%d), using default value for mtu(1500)", err );
       
   238         delete repository;
       
   239         return KEtherMaxDataLen;
       
   240         } 
       
   241     }
       
   242 
       
   243 // -----------------------------------------------------------------------------
       
   244 // CLANLinkCommon::ConstructL
       
   245 // -----------------------------------------------------------------------------
       
   246 //
       
   247 EXPORT_C void CLANLinkCommon::ConstructL()
       
   248     {
       
   249     DEBUG("CLANLinkCommon::ConstructL()");
       
   250 
       
   251     // Initialise class members that do not need to be read from the database
       
   252     iBearers = new (ELeave) CLanxBearerPtrArray(KLanxBearerPtrArrayGranularity);
       
   253     iEtherType = EStandardEthernet;
       
   254 
       
   255     iOnlyThisBearer = NULL;
       
   256     }
       
   257 
       
   258 // -----------------------------------------------------------------------------
       
   259 // CLANLinkCommon::~CLANLinkCommon
       
   260 // -----------------------------------------------------------------------------
       
   261 //
       
   262 EXPORT_C CLANLinkCommon::~CLANLinkCommon()
       
   263     {
       
   264     DEBUG("CLANLinkCommon::~CLANLinkCommon()");
       
   265 
       
   266     delete iPktDrv;
       
   267     ASSERT(0 == iBearers->Count());
       
   268     delete iBearers;
       
   269     delete iPeriodic;
       
   270     delete iWLMServerCommon;
       
   271 	for( TUint idx( 0 ); idx < EWlmAccessClassMax; ++idx )
       
   272 	    {
       
   273 	    delete iAcArray[idx];	    
       
   274 	    }
       
   275 
       
   276     LOG_NODE_DESTROY(KWlanLog, CLANLinkCommon);
       
   277     }
       
   278 
       
   279 // -----------------------------------------------------------------------------
       
   280 // CLANLinkCommon::CheckMac
       
   281 // -----------------------------------------------------------------------------
       
   282 //
       
   283 TBool CLANLinkCommon::CheckMac(TDes8& aMacAddr)
       
   284     {
       
   285     DEBUG("CLANLinkCommon::CheckMac()");
       
   286 
       
   287     TUint MacBytes = 6;
       
   288     for (TUint i=0;i<MacBytes;i++)
       
   289         {
       
   290         if (aMacAddr[i] != 0)
       
   291             {
       
   292             return ETrue;
       
   293             }
       
   294         }
       
   295     return EFalse;
       
   296     }
       
   297 
       
   298 // -----------------------------------------------------------------------------
       
   299 // CLANLinkCommon::AcTrafficModeChanged
       
   300 // -----------------------------------------------------------------------------
       
   301 //
       
   302 void CLANLinkCommon::AcTrafficModeChanged(
       
   303     TWlmAccessClass aAccessClass,
       
   304     TWlmAcTrafficMode aMode )
       
   305     {
       
   306     DEBUG( "CLANLinkCommon::AcTrafficModeChanged()" );
       
   307 
       
   308     iAcArray[aAccessClass]->SetTrafficMode( aMode );
       
   309     }
       
   310 
       
   311 // -----------------------------------------------------------------------------
       
   312 // CLANLinkCommon::AcTrafficModeChanged
       
   313 // -----------------------------------------------------------------------------
       
   314 //
       
   315 void CLANLinkCommon::AcTrafficStatusChanged(
       
   316     TWlmAccessClass aAccessClass,
       
   317     TWlmAcTrafficStatus aStatus )
       
   318     {
       
   319     DEBUG( "CLANLinkCommon::AcTrafficStatusChanged()" );
       
   320 
       
   321     iAcArray[aAccessClass]->SetTrafficStatus( aStatus );
       
   322     }
       
   323 
       
   324 // -----------------------------------------------------------------------------
       
   325 // CLANLinkCommon::LinkLayerUp
       
   326 // -----------------------------------------------------------------------------
       
   327 //
       
   328 /**
       
   329 Link Layer Up
       
   330 Called by the packet driver when it is happy
       
   331 */
       
   332 EXPORT_C void CLANLinkCommon::LinkLayerUp()
       
   333     {
       
   334     DEBUG("CLANLinkCommon::LinkLayerUp()");
       
   335     
       
   336     //some drivers have a valid MAC only after negotiation finishes
       
   337     iValidMacAddr = ReadMACSettings();
       
   338     PostDataClientStartedMessage();
       
   339 
       
   340     /**
       
   341      * With the new comms framework, this KLinkLayerOpen always sent and then will be caught and swallowed
       
   342      * at the ipproto layer if a netcfgext is being used.
       
   343      */
       
   344   
       
   345     /**
       
   346      * We are forced to signal link layer open from here even though there may not
       
   347      * be a configured IP address.  This is a dirty fix because of politics...
       
   348      */
       
   349     PostProgressMessage(KLinkLayerOpen, KErrNone);
       
   350 
       
   351     TUint bearerLim = iBearers->Count();
       
   352     for(TUint index=0;index<bearerLim;index++)
       
   353         {
       
   354         CLanxBearer *bearer=(*iBearers)[index];
       
   355         bearer->StartSending((CProtocolBase*)this);
       
   356         }
       
   357 
       
   358 	// Get current traffic status for access classes.
       
   359 	TWlmAcTrafficStatusArray acArray;
       
   360 	TInt ret = iWLMServerCommon->GetAcTrafficStatus( acArray );
       
   361 	if( ret != KErrNone )
       
   362 	    {
       
   363 	    DEBUG1( "CLANLinkCommon::LinkLayerUp() - RWLMServer::GetAcTrafficStatus() failed with %d",
       
   364 	        ret );
       
   365 
       
   366 	    // Assume all access classes are admitted.
       
   367 	    for( TUint idx( 0 ); idx < EWlmAccessClassMax; ++idx )
       
   368 	         {
       
   369 	         iAcArray[idx]->SetTrafficStatus( EWlmAcTrafficStatusAdmitted );
       
   370 	         }
       
   371 	    }
       
   372 	else
       
   373 	    {
       
   374 	    // Update access class instances with the current status.
       
   375         for( TUint idx( 0 ); idx < EWlmAccessClassMax; ++idx )
       
   376              {
       
   377              iAcArray[idx]->SetTrafficStatus( acArray[idx] );
       
   378              }
       
   379 	    }
       
   380     }
       
   381 
       
   382 // -----------------------------------------------------------------------------
       
   383 // CLANLinkCommon::LinkLayerDown
       
   384 // -----------------------------------------------------------------------------
       
   385 //
       
   386 EXPORT_C void CLANLinkCommon::LinkLayerDown(TInt aError, TAction aAction)
       
   387 /**
       
   388 Link Layer Down
       
   389 Called by the packet driver when the link has gone down
       
   390 
       
   391 @param aError error code
       
   392 @param aAction whether a reconnect is required or not
       
   393 */
       
   394     {
       
   395     DEBUG("CLANLinkCommon::LinkLayerDown()");
       
   396     
       
   397     // If a stop was requested from the SCpr then this LinkLayerDown()
       
   398     // was expected. This also means the SCpr has already been sent a
       
   399     // TDataClientStopped and the packet driver has been stopped.
       
   400     // If on the other hand the stop was not requested a TDataClientGoneDown
       
   401     // message needs to be sent to the SCpr and the packet driver still
       
   402     // needs a StopInterface call - usually this would mean that aAction
       
   403     // is EReconnect
       
   404     if (iStopRequested == EFalse && iMMState == EStarted)
       
   405         {
       
   406         PostProgressMessage(KLinkLayerClosed, aError);
       
   407         PostFlowGoingDownMessage(aError, (aAction == EReconnect) ? MNifIfNotify::EReconnect : MNifIfNotify::EDisconnect);
       
   408         iPktDrv->StopInterface();
       
   409         MaybePostDataClientIdle();
       
   410         iMMState = EStopped;
       
   411         }
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CLANLinkCommon::StopCb
       
   416 // -----------------------------------------------------------------------------
       
   417 //
       
   418 TInt CLANLinkCommon::StopCb(TAny* aThisPtr)
       
   419     {
       
   420     DEBUG("CLANLinkCommon::StopCb()");
       
   421     
       
   422     CLANLinkCommon* self = static_cast<CLANLinkCommon*>(aThisPtr);
       
   423     self->StopInterface();
       
   424     return KErrNone;
       
   425     }
       
   426 
       
   427 // -----------------------------------------------------------------------------
       
   428 // CLANLinkCommon::StopInterface
       
   429 // -----------------------------------------------------------------------------
       
   430 //
       
   431 void CLANLinkCommon::StopInterface()
       
   432     {
       
   433     DEBUG("CLANLinkCommon::StopInterface()");
       
   434     
       
   435     if(iPeriodic)
       
   436         {
       
   437         iPeriodic->Cancel();
       
   438         delete iPeriodic;
       
   439         iPeriodic = NULL;
       
   440         }
       
   441 
       
   442     iPktDrv->StopInterface();
       
   443     PostProgressMessage(KLinkLayerClosed, iError);
       
   444     PostFlowDownMessage(iError);
       
   445 
       
   446     MaybePostDataClientIdle();
       
   447     }
       
   448 
       
   449 // -----------------------------------------------------------------------------
       
   450 // CLANLinkCommon::EtherFrame
       
   451 // -----------------------------------------------------------------------------
       
   452 //
       
   453 TInt CLANLinkCommon::EtherFrame(RMBufChain &aPdu, TDesC8& aDestAddr, TUint16 aType, TUint8& aDscp)
       
   454     {
       
   455     RMBufChain ethHdr;
       
   456     TUint etherHeaderSize = (iEtherType==EStandardEthernet) ?
       
   457         KEtherHeaderSize : KEtherLLCHeaderSize;
       
   458 
       
   459     TRAPD(ret, ethHdr.AllocL(etherHeaderSize));
       
   460     if(ret != KErrNone)
       
   461         {
       
   462         return ret;
       
   463         }
       
   464 
       
   465     TEtherLLCFrame *hdrBuf = reinterpret_cast<TEtherLLCFrame*>(ethHdr.First()->Buffer());
       
   466 
       
   467     //Get the packet info:
       
   468     RMBufPktInfo* info = RMBufPacket::PeekInfoInChain(aPdu);
       
   469 
       
   470     // Fill in the dest, src Mac addresses:
       
   471     hdrBuf->SetDestAddr(aDestAddr);
       
   472     hdrBuf->SetSrcAddr(iMacAddr);
       
   473 
       
   474     switch(iEtherType)
       
   475         {
       
   476         case EStandardEthernet:
       
   477             BigEndian::Put16((TUint8*)&hdrBuf->iType,aType);
       
   478             break;
       
   479         case ELLCEthernet:
       
   480             // Several fields to fill in. According to nifmbuf.h,
       
   481             // info->iLength gives the actual length of the packet.
       
   482             BigEndian::Put16((TUint8*)&hdrBuf->iLen,static_cast<TInt16>(info->iLength));
       
   483             hdrBuf->iDSAP=KLLC_SNAP_DSAP;
       
   484             hdrBuf->iSSAP=KLLC_SNAP_SSAP;
       
   485             hdrBuf->iCtrl=KLLC_SNAP_CTRL;
       
   486             hdrBuf->SetOUI(0);
       
   487             hdrBuf->SetType(aType);
       
   488             break;
       
   489         default:
       
   490             // Can't handle any other kind of Ethernet header.
       
   491             return KErrGeneral;
       
   492         }
       
   493 
       
   494     //Remove the original first Packet - by trimming the info from the packet.
       
   495     aPdu.TrimStart(aPdu.Length() - info->iLength); // At this point, info becomes invalid.
       
   496 
       
   497     //Extract the DSCP value as aPdu points to IP packet now
       
   498     if (KIPFrameType == aType)
       
   499         {
       
   500         TInet6HeaderIP4 *ipv4hdr = (TInet6HeaderIP4 *)aPdu.First()->Ptr();
       
   501         TUint8 TOS = ipv4hdr->TOS();
       
   502         aDscp = (TOS >> 2) & 0xff;
       
   503         DEBUG2( "CLanLinkCommon::EtherFrame() - DSCP of the IPv4 packet: 0x%02X (%u)",
       
   504 	        aDscp, aDscp );
       
   505         }
       
   506     else if (KIP6FrameType == aType)
       
   507         {
       
   508         TInet6HeaderIP *ipv6hdr = (TInet6HeaderIP *)aPdu.First()->Ptr();
       
   509         TUint8 TrafficClass = ipv6hdr->TrafficClass();
       
   510         aDscp = (TrafficClass >> 2) & 0xff;     
       
   511         DEBUG2( "CLanLinkCommon::EtherFrame() - DSCP of the IPv6 packet: 0x%02X (%u)",
       
   512 	        aDscp, aDscp );
       
   513         }
       
   514 
       
   515     //Finally, add the saved packet buffer to the mac header
       
   516     aPdu.Prepend(ethHdr);
       
   517     return KErrNone;
       
   518     }
       
   519 
       
   520 // -----------------------------------------------------------------------------
       
   521 // CLANLinkCommon::FrameSend
       
   522 // -----------------------------------------------------------------------------
       
   523 //
       
   524 TInt CLANLinkCommon::FrameSend(
       
   525     RMBufChain& aPdu,
       
   526     TDesC8& aDestAddr,
       
   527     TUint16 aType )
       
   528 	{
       
   529 	// Call down from the Protocol
       
   530 	// The data begins in the second MBuf - because the first one
       
   531 	// is the info. The upper layer must have filled in the destination
       
   532 	// and source Mac addresses before this method is called and must
       
   533 	// supply the ether header type in aType.
       
   534 	// EtherFrame strips off the info and replaces it by the proper
       
   535 	// ether header.
       
   536 
       
   537 	TUint8 dscp( 0 );
       
   538 	TInt err = EtherFrame( aPdu, aDestAddr, aType, dscp );
       
   539 	if( err != KErrNone )
       
   540 	    {
       
   541 	    // drop the packet but _don't_ return an error (if we return
       
   542 	    // an error from here, the stack thinks it is fatal...)
       
   543 	    aPdu.Free();
       
   544 	    return KContinueSending;
       
   545 	    }
       
   546 
       
   547     // Map DSCP values to desired access class and user priority values.
       
   548 	T8021DPriority userPriority( KDSCPtoUP[dscp] );
       
   549 	TWlmAccessClass accessClass( KUPtoAC[userPriority] );	
       
   550 	TBool dropPacket( EFalse );
       
   551 
       
   552     // ARP packets are treated as Voice traffic.
       
   553 	if( aType == KArpFrameType )
       
   554 	    {
       
   555         DEBUG( "CLanLinkCommon::FrameSend() - ARP packet" );
       
   556 
       
   557         userPriority = E8021DUserPriorityNC;
       
   558         accessClass = EWlmAccessClassVoice;
       
   559 	    }
       
   560 
       
   561 	if( iAcArray[accessClass]->IsAdmitted() )
       
   562 	    {
       
   563 	    DEBUG1( "CLanLinkCommon::FrameSend() - traffic admitted on AC %u",
       
   564 	        accessClass );
       
   565 	    }
       
   566 	else
       
   567 	    {
       
   568 	    DEBUG1( "CLanLinkCommon::FrameSend() - traffic NOT admitted on AC %u",
       
   569 	        accessClass );
       
   570 
       
   571 	    // Find an admitted access class.
       
   572 	    DownGradePacket( userPriority, dropPacket );
       
   573 	    }
       
   574 
       
   575 	if( !dropPacket )
       
   576 	    {
       
   577 	    //Prepend UP value to the packet
       
   578 	    RMBufChain UPBuf;
       
   579 	    TRAPD( allocRet, UPBuf.AllocL( sizeof(TUint8) ) );
       
   580 	    if( allocRet != KErrNone )
       
   581 	        {
       
   582 	        // drop the packet but _don't_ return an error (if we return
       
   583 	        // an error from here, the stack thinks it is fatal...)
       
   584 	        aPdu.Free();
       
   585 	        return KContinueSending;
       
   586 	        }
       
   587 
       
   588 	    (UPBuf.First())->Put((TUint8)userPriority);
       
   589 	    aPdu.Prepend( UPBuf );
       
   590 
       
   591 	    DEBUG2( "CLanLinkCommon::FrameSend() - sending packet on AC %u with UP %u",
       
   592 	        KUPtoAC[userPriority],
       
   593 	        userPriority );
       
   594 	    TInt ret = iPktDrv->Send( aPdu );
       
   595 
       
   596 	    // ARP packets will never triggers traffic stream creation.
       
   597 	    if( aType == KArpFrameType )
       
   598 	        {
       
   599 	        return ret;
       
   600 	        }
       
   601 
       
   602 	    // Notify the per-AC handler.
       
   603 	    iAcArray[accessClass]->OnFrameSend();
       
   604 
       
   605 	    if( ret != KContinueSending )
       
   606 	        {
       
   607 	        // Suspend inactivity timer for all ACs if NIF Queue is full.
       
   608 	        for( TUint idx( 0 ); idx < EWlmAccessClassMax; ++idx )
       
   609 	            {
       
   610 	            iAcArray[idx]->SuspendInactivityTimer();
       
   611 	            }
       
   612 	        }
       
   613 
       
   614 	    return ret;
       
   615 	    }
       
   616 	else
       
   617 	    {
       
   618 	    DEBUG( "CLanLinkCommon::FrameSend() - no ACs admitted, dropping packet" );
       
   619 
       
   620 	    aPdu.Free();
       
   621 
       
   622 	    return KContinueSending;
       
   623 	    }
       
   624 	}
       
   625 
       
   626 // -----------------------------------------------------------------------------
       
   627 // CLANLinkCommon::DownGradePacket
       
   628 // -----------------------------------------------------------------------------
       
   629 //
       
   630 void CLANLinkCommon::DownGradePacket(
       
   631     T8021DPriority& aUP,
       
   632     TBool& aDrop )
       
   633     {
       
   634     DEBUG1( "CLanLinkCommon::DownGradePacket() - UP before downgrade: %u",
       
   635         aUP );
       
   636 
       
   637     /**
       
   638      * This method wouldn't be called if downgrade wasn't needed,
       
   639      * so we don't have to check Voice priority at all.   
       
   640      */
       
   641     TWlmAccessClass accessClass( KNextAC[KUPtoAC[aUP]] );
       
   642     while( accessClass != EWlmAccessClassMax )
       
   643         {
       
   644         if( iAcArray[accessClass]->IsAdmitted() )
       
   645             {
       
   646             aUP = KACtoUP[accessClass];
       
   647             aDrop = EFalse;
       
   648     
       
   649             DEBUG1( "CLanLinkCommon::DownGradePacket() - UP after downgrade: %u",
       
   650                 aUP );
       
   651 
       
   652             return;
       
   653             }
       
   654 
       
   655         accessClass = KNextAC[accessClass];
       
   656         }
       
   657 
       
   658     DEBUG( "CLanLinkCommon::DownGradePacket() - packet will be dropped" );
       
   659 
       
   660     aDrop = ETrue;
       
   661     }
       
   662 
       
   663 // -----------------------------------------------------------------------------
       
   664 // CLANLinkCommon::GetProtocolType
       
   665 // -----------------------------------------------------------------------------
       
   666 //
       
   667 TInt CLANLinkCommon::GetProtocolType(
       
   668     TUint8* aEtherHeader,
       
   669     TUint16& aEtherType )
       
   670     {
       
   671     TEtherFrame* etherFrame = reinterpret_cast<TEtherFrame*>(aEtherHeader);   
       
   672     TUint16 etherType = etherFrame->GetType();
       
   673   
       
   674     if( etherType >= KMinEtherType)
       
   675         {
       
   676         // type/length field >= 1536, this is Ethernet II frame
       
   677         aEtherType = etherType; 
       
   678         }
       
   679     else
       
   680         {
       
   681         // type/length field is something between KEtherLLCMaxLengthFieldValue
       
   682         // and KMinEtherType, this shouldn't happen...
       
   683         //__ASSERT_DEBUG(EFalse, User::Panic(_L("wlannif"), KErrGeneral));
       
   684         return KErrNotSupported;
       
   685         }
       
   686     return KErrNone;
       
   687     }
       
   688 
       
   689 // -----------------------------------------------------------------------------
       
   690 // CLANLinkCommon::Process
       
   691 // -----------------------------------------------------------------------------
       
   692 //
       
   693 void CLANLinkCommon::Process(
       
   694     RMBufChain& aPdu, 
       
   695     TUint8* aEtherHeader, 
       
   696     TUint8 aUPValue )
       
   697 	{
       
   698 	TUint16 etherCode(0);
       
   699 	TBool packetProcessed(EFalse);
       
   700 	TInt ret=GetProtocolType( aEtherHeader, etherCode );
       
   701 	if( ret==KErrNone )
       
   702 		{  // It's an ethernet packet of some kind.
       
   703 	    DEBUG2("CLANLinkCommon::Process() - UP: %u, ethertype: 0x%04X",
       
   704 	        aUPValue, etherCode );
       
   705 
       
   706 		TUint bearerLim = iBearers->Count();
       
   707 		for( TUint index=0;index<bearerLim && !packetProcessed; index++ )
       
   708 			{
       
   709 			CLanxBearer *bearer=(*iBearers)[index];
       
   710 		
       
   711 			if( bearer->WantsProtocol(
       
   712 			    etherCode, aPdu.First()->Next()->Buffer()) )
       
   713 				{	
       
   714 				bearer->Process( aPdu );
       
   715 				packetProcessed=ETrue;
       
   716 				}
       
   717 			}
       
   718 		}
       
   719 	if( ret!=KErrNone || !packetProcessed )
       
   720 	    {
       
   721 	    aPdu.Free(); // Something strange about the packet - bin it
       
   722 	    }
       
   723 	else
       
   724 	    {
       
   725         // Notify the per-AC handler.   
       
   726 	    iAcArray[KUPtoAC[aUPValue]]->OnFrameReceive();
       
   727 	    }
       
   728 	}
       
   729 
       
   730 // -----------------------------------------------------------------------------
       
   731 // CLANLinkCommon::ResumeSending
       
   732 // -----------------------------------------------------------------------------
       
   733 //
       
   734 EXPORT_C void CLANLinkCommon::ResumeSending()
       
   735     {
       
   736 	DEBUG( "CLanLinkCommon::ResumeSending()" );
       
   737 	
       
   738 	TUint bearerLim = iBearers->Count();
       
   739 	for( TUint index=0;index<bearerLim;index++ )
       
   740 		{
       
   741 		CLanxBearer *bearer=(*iBearers)[index];
       
   742 		bearer->StartSending( (CProtocolBase*)this );
       
   743 		}
       
   744 
       
   745     for( TUint idx( 0 ); idx < EWlmAccessClassMax; ++idx )
       
   746          {
       
   747          iAcArray[idx]->ResumeInactivityTimer();
       
   748          }
       
   749 	}
       
   750 
       
   751 /**
       
   752 
       
   753 */
       
   754 EXPORT_C TInt CLANLinkCommon::ReadInt(const TDesC& /*aField*/, TUint32& /*aValue*/)
       
   755 {
       
   756   return KErrNotSupported;
       
   757 }
       
   758   
       
   759 /**
       
   760 
       
   761 */
       
   762 EXPORT_C TInt CLANLinkCommon::WriteInt(const TDesC& /*aField*/, TUint32 /*aValue*/)
       
   763 {
       
   764   return KErrNotSupported;
       
   765 }
       
   766   
       
   767 /**
       
   768 
       
   769 */
       
   770 EXPORT_C TInt CLANLinkCommon::ReadDes(const TDesC& /*aField*/, TDes8& /*aValue*/)
       
   771 {
       
   772   return KErrNotSupported;
       
   773 }
       
   774   
       
   775 /**
       
   776 
       
   777 */
       
   778 EXPORT_C TInt CLANLinkCommon::ReadDes(const TDesC& /*aField*/, TDes16& /*aValue*/)
       
   779 {
       
   780   return KErrNotSupported;
       
   781 
       
   782 }
       
   783   
       
   784 /**
       
   785 
       
   786 */
       
   787 EXPORT_C TInt CLANLinkCommon::WriteDes(const TDesC& /*aField*/, const TDesC8& /*aValue*/)
       
   788 {
       
   789   return KErrNotSupported;
       
   790 }
       
   791   
       
   792 /**
       
   793 
       
   794 */
       
   795 EXPORT_C TInt CLANLinkCommon::WriteDes(const TDesC& /*aField*/, const TDesC16& /*aValue*/)
       
   796 {
       
   797   return KErrNotSupported;
       
   798 }
       
   799   
       
   800 /**
       
   801 
       
   802 */
       
   803 EXPORT_C TInt CLANLinkCommon::ReadBool(const TDesC& /*aField*/, TBool& /*aValue*/)
       
   804 {
       
   805   return KErrNotSupported;
       
   806 }
       
   807   
       
   808 /**
       
   809 
       
   810 */
       
   811 EXPORT_C TInt CLANLinkCommon::WriteBool(const TDesC& /*aField*/, TBool /*aValue*/)
       
   812 {
       
   813   return KErrNotSupported;
       
   814 }
       
   815   
       
   816 /**
       
   817 
       
   818 */
       
   819 EXPORT_C void CLANLinkCommon::IfProgress(TInt aStage, TInt aError)
       
   820 {
       
   821   PostProgressMessage(aStage, aError);
       
   822 }
       
   823   
       
   824 /**
       
   825 
       
   826 */
       
   827 EXPORT_C void CLANLinkCommon::IfProgress(TSubConnectionUniqueId /*aSubConnectionUniqueId*/, TInt aStage, TInt aError)
       
   828 {
       
   829   // Not quite correct - there is no subconnection id specific progress message.
       
   830   IfProgress(aStage, aError);
       
   831 }
       
   832   
       
   833 /**
       
   834 
       
   835 */
       
   836 EXPORT_C void CLANLinkCommon::NifEvent(TNetworkAdaptorEventType /*aEventType*/, TUint /*aEvent*/, const TDesC8& /*aEventData*/, TAny* /*aSource*/)
       
   837 {
       
   838 }
       
   839 
       
   840 // ======================================================================================
       
   841 //
       
   842 // from MFlowBinderControl
       
   843 
       
   844 // -----------------------------------------------------------------------------
       
   845 // CLANLinkCommon::GetControlL
       
   846 // -----------------------------------------------------------------------------
       
   847 //
       
   848 EXPORT_C MLowerControl* CLANLinkCommon::GetControlL(const TDesC8& aName)
       
   849 /**
       
   850 Request from upper CFProtocol to retrieve our MLowerControl class.
       
   851 
       
   852 @param aName Protocol Name.  Presently, only "ip" and "ip6" are supported.
       
   853 @return pointer to our MLowerControl class instance.  We leave on an error, hence this routine should
       
   854 never return NULL.
       
   855 */
       
   856   {
       
   857     DEBUG("CLANLinkCommon::GetControlL()");
       
   858   
       
   859   CLanxBearer* bearer=NULL;
       
   860     if (aName.CompareF(KDescIp6) == 0)
       
   861       {
       
   862         bearer = new(ELeave) CLanIp6Bearer(this);
       
   863         }
       
   864   else if (aName.CompareF(KDescIp) == 0 || aName.CompareF(KDescIcmp) == 0)
       
   865     {
       
   866         bearer = new(ELeave) CLanIp4Bearer(this);
       
   867         }
       
   868   else
       
   869     {
       
   870     User::Leave(KErrNotSupported);
       
   871     }
       
   872   
       
   873     CleanupStack::PushL(bearer);
       
   874     bearer->ConstructL();
       
   875 
       
   876   iBearers->AppendL(bearer);
       
   877   ProvisionBearerConfigL(aName);
       
   878     CleanupStack::Pop();
       
   879     return bearer;
       
   880   }
       
   881 
       
   882   
       
   883 // -----------------------------------------------------------------------------
       
   884 // CLANLinkCommon::BindL
       
   885 // -----------------------------------------------------------------------------
       
   886 //
       
   887 EXPORT_C MLowerDataSender* CLANLinkCommon::BindL(const TDesC8& aProtocol, MUpperDataReceiver* aReceiver, MUpperControl* aControl)
       
   888 /**
       
   889 Request from upper CFProtocol to bind to this module.
       
   890 
       
   891 @param aProtocol protocol name (e.g. "ip", "ip6" etc).
       
   892 @param aReceiver pointer to MUpperDataReceiver instance of upper CFProtocol
       
   893 @param aControl pointer to MUpperControl instance of upper CFProtocol
       
   894 @return pointer to our MLowerDataSender instance (eventually passed to the upper CFProtocol)
       
   895 */
       
   896   {
       
   897     DEBUG("CLANLinkCommon::BindL()");
       
   898     
       
   899   TInt index = 0;
       
   900   CLanxBearer* bearer = FindBearerByProtocolName(aProtocol, index);
       
   901   if (bearer)
       
   902     {
       
   903     bearer->SetUpperPointers(aReceiver, aControl);
       
   904     if (iValidMacAddr)
       
   905       {
       
   906       aControl->StartSending();
       
   907       }
       
   908     }
       
   909   else
       
   910     {
       
   911     User::Leave(KErrNotSupported);
       
   912     }
       
   913   iSubConnectionProvider.RNodeInterface::PostMessage(Id(), TCFControlProvider::TActive().CRef()); 
       
   914   return bearer;
       
   915   }
       
   916 
       
   917   
       
   918 // -----------------------------------------------------------------------------
       
   919 // CLANLinkCommon::Unbind
       
   920 // -----------------------------------------------------------------------------
       
   921 //
       
   922 EXPORT_C void CLANLinkCommon::Unbind(MUpperDataReceiver* /*aReceiver*/, MUpperControl* aControl)
       
   923 /**
       
   924 Request from upper CFProtocol to unbind from this module.
       
   925 
       
   926 @param aReceiver pointer to data receiver class of upper CFProtocol (originally passed to it in downward BindL() request)
       
   927 @param aControl pointer to control class of upper CFProtocol (originally passed to it in downward BindL() request)
       
   928 */
       
   929 
       
   930   {
       
   931     DEBUG("CLANLinkCommon::Unbind()");
       
   932     
       
   933   TInt index = 0;
       
   934   CLanxBearer* bearer = FindBearerByUpperControl(aControl, index);
       
   935   ASSERT(bearer);
       
   936   iBearers->Delete(index);
       
   937   delete bearer;
       
   938   
       
   939   // If no-one remains bound to us, signal data client idle to SCPR
       
   940   MaybePostDataClientIdle();
       
   941   }
       
   942 
       
   943 
       
   944 //
       
   945 // Utilities
       
   946 //
       
   947 
       
   948 // -----------------------------------------------------------------------------
       
   949 // CLANLinkCommon::FindBearerByProtocolName
       
   950 // -----------------------------------------------------------------------------
       
   951 //
       
   952 CLanxBearer* CLANLinkCommon::FindBearerByProtocolName(const TDesC8& aProtocol, TInt& aIndex) const
       
   953 /**
       
   954 Search the iBearers array searching for a match by protocol name.
       
   955 
       
   956 @param aProtocol name of protocol (in)
       
   957 @param aIndex on success, index of found entry (>=0), else -1.
       
   958 @return pointer to CLanxBearer entry on success else NULL.
       
   959 */
       
   960   {
       
   961     DEBUG("CLANLinkCommon::FindBearerByProtocolName()");
       
   962   
       
   963   TInt count = iBearers->Count();
       
   964   for (TInt i = 0 ; i < count ; ++i)
       
   965     {
       
   966     CLanxBearer* bearer = iBearers->At(i);
       
   967     if (bearer->ProtocolName() == aProtocol)
       
   968       {
       
   969       aIndex = i;
       
   970       return bearer;
       
   971       }
       
   972     }
       
   973   aIndex = -1;
       
   974   return NULL;
       
   975   }
       
   976 
       
   977 
       
   978 // -----------------------------------------------------------------------------
       
   979 // CLANLinkCommon::FindBearerByUpperControl
       
   980 // -----------------------------------------------------------------------------
       
   981 //
       
   982 CLanxBearer* CLANLinkCommon::FindBearerByUpperControl(const MUpperControl* aUpperControl, TInt& aIndex) const
       
   983 /**
       
   984 Search the iBearers array searching for a match by protocol name.
       
   985 
       
   986 @param aProtocol name of protocol (in)
       
   987 @param aIndex on success, index of found entry (>=0), else -1.
       
   988 @return pointer to CLanxBearer entry on success else NULL.
       
   989 */
       
   990   {
       
   991     DEBUG("CLANLinkCommon::FindBearerByUpperControl()");
       
   992   
       
   993   TInt count = iBearers->Count();
       
   994   for (TInt i = 0 ; i < count ; ++i)
       
   995     {
       
   996     CLanxBearer* bearer = iBearers->At(i);
       
   997     if (bearer->MatchesUpperControl(aUpperControl))
       
   998       {
       
   999       aIndex = i;
       
  1000       return bearer;
       
  1001       }
       
  1002     }
       
  1003   aIndex = -1;
       
  1004   return NULL;
       
  1005   }
       
  1006   
       
  1007 // =====================================================================================
       
  1008 //
       
  1009 // MCFNode
       
  1010 
       
  1011 // -----------------------------------------------------------------------------
       
  1012 // CLANLinkCommon::ReceivedL
       
  1013 // -----------------------------------------------------------------------------
       
  1014 //
       
  1015 EXPORT_C void CLANLinkCommon::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage)
       
  1016 /**
       
  1017 Routine called on an incoming message from SCPR
       
  1018 
       
  1019 @param aCFMessage incoming message
       
  1020 @return KErrNone, else a system wide error code.
       
  1021 */
       
  1022     {
       
  1023     DEBUG1("CLANLinkCommon::ReceivedL(), aCFMessage=%d", aMessage.MessageId().MessageId());
       
  1024     
       
  1025     CSubConnectionFlowBase::ReceivedL(aSender, aRecipient, aMessage);
       
  1026    
       
  1027     if (TEBase::ERealmId == aMessage.MessageId().Realm())
       
  1028         {
       
  1029         switch (aMessage.MessageId().MessageId())
       
  1030             {
       
  1031         case TEBase::TError::EId :
       
  1032             SubConnectionError(static_cast<TEBase::TError&>(aMessage).iValue);
       
  1033             break;
       
  1034         case TEBase::TCancel::EId :
       
  1035             CancelStartFlow();
       
  1036             break;                
       
  1037         default:
       
  1038             ASSERT(EFalse);
       
  1039             }
       
  1040         }
       
  1041     else if (TEChild::ERealmId == aMessage.MessageId().Realm())
       
  1042         {
       
  1043         switch (aMessage.MessageId().MessageId())
       
  1044             {
       
  1045         case TEChild::TDestroy::EId :
       
  1046             Destroy();
       
  1047             break;
       
  1048         default:
       
  1049             ASSERT(EFalse);
       
  1050             }
       
  1051         }
       
  1052     else if (TCFDataClient::ERealmId == aMessage.MessageId().Realm())
       
  1053         {
       
  1054         switch (aMessage.MessageId().MessageId())
       
  1055             {
       
  1056         case TCFDataClient::TStart::EId :
       
  1057             StartFlowL();
       
  1058             break;
       
  1059         case TCFDataClient::TProvisionConfig::EId:
       
  1060             ProvisionConfig(static_cast<TCFDataClient::TProvisionConfig&>(aMessage).iConfig);
       
  1061             break;
       
  1062         case TCFDataClient::TStop::EId :
       
  1063             StopFlow(static_cast<TCFDataClient::TStop&>(aMessage).iValue);
       
  1064             break;
       
  1065         case TCFDataClient::TBindTo::EId :
       
  1066       {
       
  1067             TCFDataClient::TBindTo& bindToReq = message_cast<TCFDataClient::TBindTo>(aMessage);
       
  1068             if (!bindToReq.iNodeId.IsNull())
       
  1069                 {
       
  1070                 User::Leave(KErrNotSupported);
       
  1071                 }
       
  1072             RClientInterface::OpenPostMessageClose(Id(), aSender, TCFDataClient::TBindToComplete().CRef());
       
  1073             break;
       
  1074       }
       
  1075     default:
       
  1076             ASSERT(EFalse);
       
  1077             }
       
  1078         }
       
  1079     else if (TLinkMessage::ERealmId == aMessage.MessageId().Realm())
       
  1080         {
       
  1081         switch (aMessage.MessageId().MessageId())
       
  1082             {
       
  1083             case TLinkMessage::TAgentToFlowNotification::EId:
       
  1084                 {                    
       
  1085               TLinkMessage::TAgentToFlowNotification& msg = message_cast<TLinkMessage::TAgentToFlowNotification>(aMessage);
       
  1086               if(msg.iValue != EAgentToNifEventVendorSpecific)
       
  1087                 {
       
  1088                 User::Leave(KErrNotSupported);
       
  1089                 }
       
  1090               else //EAgentToNifEventVendorSpecific
       
  1091                 {
       
  1092                 //User::LeaveIfError((iPktDrv) ? iPktDrv->Notification(
       
  1093                 //    static_cast<TAgentToNifEventType>(msg.iValue), NULL) : KErrNotSupported);
       
  1094                 DEBUG("CLANLinkCommon::ReceivedL(), rcvd disconnect notification from Agent");
       
  1095                 iError = KErrDisconnected;
       
  1096                 StopInterface();
       
  1097                 }         
       
  1098                 }
       
  1099                 break;
       
  1100             default:
       
  1101                 ASSERT(EFalse);             
       
  1102             }; //endswitch   
       
  1103         }
       
  1104     else
       
  1105         {
       
  1106         ASSERT(EFalse);
       
  1107         }
       
  1108     }
       
  1109 
       
  1110 //
       
  1111 // Methods for handling incoming SCPR messages
       
  1112 //
       
  1113 
       
  1114 // -----------------------------------------------------------------------------
       
  1115 // CLANLinkCommon::StartFlowL
       
  1116 // -----------------------------------------------------------------------------
       
  1117 //
       
  1118 void CLANLinkCommon::StartFlowL()
       
  1119   {
       
  1120     DEBUG("CLANLinkCommon::StartFlowL()");
       
  1121     
       
  1122     if ( !iPktDrv )
       
  1123         LoadPacketDriverL();
       
  1124   
       
  1125   iStopRequested = EFalse;
       
  1126   
       
  1127   ASSERT(iMMState == EStopped);
       
  1128 
       
  1129   if (iSavedError != KErrNone)
       
  1130     {
       
  1131     // If there were errors during prior processing of the TProvisionConfig message,
       
  1132     // leave here and cause a TError response to TDataClientStart.
       
  1133     User::Leave(iSavedError);
       
  1134     }
       
  1135 
       
  1136   iValidMacAddr = ReadMACSettings();
       
  1137   
       
  1138   iMMState = EStarting;
       
  1139   User::LeaveIfError(iPktDrv->StartInterface());
       
  1140   }
       
  1141 
       
  1142 
       
  1143 // -----------------------------------------------------------------------------
       
  1144 // CLANLinkCommon::CancelStartFlow
       
  1145 // -----------------------------------------------------------------------------
       
  1146 //
       
  1147 void CLANLinkCommon::CancelStartFlow()
       
  1148     {
       
  1149     if (iMMState == EStarting)
       
  1150         {
       
  1151       iStopRequested = ETrue;
       
  1152     
       
  1153       iPktDrv->StopInterface();
       
  1154       PostProgressMessage(KLinkLayerClosed, KErrCancel);
       
  1155       PostFlowDownMessage(KErrCancel);
       
  1156     
       
  1157       MaybePostDataClientIdle();
       
  1158       }
       
  1159     }
       
  1160 
       
  1161 
       
  1162 // half a second should be enough for sending DHCPRELEASE
       
  1163 static const TInt KDhcpReleaseDelay = 500000;
       
  1164   
       
  1165 // -----------------------------------------------------------------------------
       
  1166 // CLANLinkCommon::StopFlow
       
  1167 // -----------------------------------------------------------------------------
       
  1168 //
       
  1169 void CLANLinkCommon::StopFlow(TInt aError)
       
  1170   {
       
  1171     DEBUG("CLANLinkCommon::StopFlow()");
       
  1172     
       
  1173   iStopRequested = ETrue;
       
  1174 
       
  1175   iMMState = EStopping;
       
  1176   
       
  1177   iError = aError;
       
  1178 
       
  1179   TCallBack callback(StopCb, this);
       
  1180   TRAPD(err, iPeriodic = CPeriodic::NewL(CActive::EPriorityStandard));
       
  1181   if(err == KErrNone)
       
  1182       {
       
  1183     // Call the callback after KDhcpReleaseDelay. This is done only once,
       
  1184     // but we need to put something (KMaxTInt) to CPeriodic's interval.
       
  1185     iPeriodic->Start(TTimeIntervalMicroSeconds32(KDhcpReleaseDelay), TTimeIntervalMicroSeconds32(KMaxTInt), callback);
       
  1186       }
       
  1187   else
       
  1188       {
       
  1189     iPeriodic = NULL;
       
  1190       } 
       
  1191   }
       
  1192 
       
  1193 
       
  1194 // -----------------------------------------------------------------------------
       
  1195 // CLANLinkCommon::SubConnectionGoingDown
       
  1196 // -----------------------------------------------------------------------------
       
  1197 //
       
  1198 void CLANLinkCommon::SubConnectionGoingDown()
       
  1199   {
       
  1200   }
       
  1201   
       
  1202 // -----------------------------------------------------------------------------
       
  1203 // CLANLinkCommon::SubConnectionError
       
  1204 // -----------------------------------------------------------------------------
       
  1205 //
       
  1206 void CLANLinkCommon::SubConnectionError(TInt /*aError*/)
       
  1207   {
       
  1208   }
       
  1209 
       
  1210 
       
  1211 /*
       
  1212 Provisioning description for Ethernet CFProtocol Flow:
       
  1213 
       
  1214 - on receipt of the TProvisionConfig message, the pointer contained within is stored
       
  1215   in iAccessPointConfig and the provisioning information contained within the AccessPointConfig
       
  1216   array is validated:
       
  1217   - at least one of TLanIp4Provision or TLanIp6Provision must be present.  They are added by the EtherMCPr and
       
  1218     populated from CommsDat.
       
  1219 
       
  1220 - the packet driver is loaded.
       
  1221 
       
  1222 - if any of the above steps fail, the resulting error is saved in iSaveError so that when TDataClientStart message is
       
  1223   subsequently received, a TError message can be sent in response (there is no response to TProvisionConfig message).
       
  1224 */
       
  1225 
       
  1226 // -----------------------------------------------------------------------------
       
  1227 // CLANLinkCommon::ProvisionConfig
       
  1228 // -----------------------------------------------------------------------------
       
  1229 //
       
  1230 void CLANLinkCommon::ProvisionConfig( const RMetaExtensionContainerC& aConfigData )
       
  1231     {
       
  1232     DEBUG("CLANLinkCommon::ProvisionConfig()");
       
  1233 
       
  1234     iSavedError = KErrNone;
       
  1235 
       
  1236     AccessPointConfig().Close();
       
  1237     AccessPointConfig().Open(aConfigData);
       
  1238     
       
  1239     iLanIp4Provision = static_cast<const TLanIp4Provision*>(AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TLanIp4Provision::EUid, TLanIp4Provision::ETypeId)));
       
  1240     if (iLanIp4Provision)
       
  1241         {
       
  1242         DEBUG("CLANLinkCommon::ProvisionConfig() - IP4 config to be provisioned");
       
  1243         }
       
  1244 
       
  1245     iLanIp6Provision = static_cast<const TLanIp6Provision*>(AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TLanIp6Provision::EUid, TLanIp6Provision::ETypeId)));
       
  1246     if (iLanIp6Provision)
       
  1247         {
       
  1248         DEBUG("CLANLinkCommon::ProvisionConfig() - IP6 config to be provisioned");
       
  1249         }
       
  1250 
       
  1251     if (iLanIp4Provision == NULL && iLanIp6Provision == NULL)
       
  1252         {
       
  1253         // At least one set of IP4/6 provisioning information must be present
       
  1254         iSavedError = KErrCorrupt;
       
  1255         return;
       
  1256         }
       
  1257 
       
  1258     TRAPD(err, ProvisionConfigL());
       
  1259     if (err != KErrNone)
       
  1260         {
       
  1261         iSavedError = err;
       
  1262         }
       
  1263     }
       
  1264 
       
  1265 // -----------------------------------------------------------------------------
       
  1266 // CLANLinkCommon::ProvisionConfigL
       
  1267 // -----------------------------------------------------------------------------
       
  1268 //
       
  1269 void CLANLinkCommon::ProvisionConfigL()
       
  1270     {
       
  1271     DEBUG("CLANLinkCommon::ProvisionConfigL()");
       
  1272 
       
  1273     // Provision Bearers
       
  1274     if (iBearers->Count())
       
  1275         {
       
  1276         ProvisionBearerConfigL(KDescIp());
       
  1277         ProvisionBearerConfigL(KDescIp6());
       
  1278         }
       
  1279 
       
  1280     iWLMServerCommon =  new (ELeave) CLANNifWLMServerCommon(this);
       
  1281     iWLMServerCommon->ConstructL();
       
  1282 
       
  1283 	TBool isAutomaticMgmt( ETrue );
       
  1284 	CRepository* repository = NULL;	
       
  1285 	TRAP_IGNORE( repository = CRepository::NewL( KCRUidWlanDeviceSettingsRegistryId ) );
       
  1286 	if( repository )
       
  1287 	    {
       
  1288 	    TInt temp( 0 );
       
  1289 	    TInt ret = repository->Get( KWlanAutomaticTrafficStreamMgmt, temp );
       
  1290 	    if( ret == KErrNone &&
       
  1291 	        !temp )
       
  1292 	        {
       
  1293 	        isAutomaticMgmt = EFalse;
       
  1294 	        }
       
  1295 
       
  1296 	    delete repository;
       
  1297 	    repository = NULL;
       
  1298 	    }
       
  1299 
       
  1300 	for( TUint idx( 0 ); idx < EWlmAccessClassMax; ++idx )
       
  1301 	    {
       
  1302 	    iAcArray[idx] = CLANNifWLMServerPerAC::NewL(
       
  1303 	        static_cast<TWlmAccessClass>( idx ),
       
  1304 	        KTsInactivityTime[idx],
       
  1305 	        isAutomaticMgmt );
       
  1306 	    }
       
  1307     }
       
  1308 
       
  1309 // -----------------------------------------------------------------------------
       
  1310 // CLANLinkCommon::Destroy
       
  1311 // -----------------------------------------------------------------------------
       
  1312 //
       
  1313 void CLANLinkCommon::Destroy()
       
  1314   {
       
  1315     DEBUG("CLANLinkCommon::Destroy()");
       
  1316     
       
  1317   ASSERT(iMMState==EStopped);
       
  1318   DeleteThisFlow();
       
  1319   }
       
  1320 
       
  1321 // Utility functions
       
  1322 
       
  1323 void CLANLinkCommon::ProvisionBearerConfigL(const TDesC8& aName)
       
  1324   {
       
  1325     DEBUG("CLANLinkCommon::ProvisionBearerConfigL()");
       
  1326   
       
  1327   TInt index = -1;
       
  1328   CLanxBearer* bearer = FindBearerByProtocolName(aName, index);
       
  1329   if (bearer)
       
  1330     {
       
  1331         if (aName.CompareF(KDescIp) == 0)
       
  1332         {
       
  1333         if (iLanIp4Provision)
       
  1334             {
       
  1335             bearer->SetProvisionL(iLanIp4Provision); // CLanIp4Bearer
       
  1336             }
       
  1337         }
       
  1338     else if (aName.CompareF(KDescIp6) == 0) 
       
  1339         {
       
  1340         if (iLanIp6Provision)
       
  1341             {
       
  1342             bearer->SetProvisionL(iLanIp6Provision); // CLanIp6Bearer
       
  1343             }
       
  1344         }
       
  1345     }
       
  1346   }
       
  1347 
       
  1348 
       
  1349 // -----------------------------------------------------------------------------
       
  1350 // CLANLinkCommon::PostProgressMessage
       
  1351 // -----------------------------------------------------------------------------
       
  1352 //
       
  1353 void CLANLinkCommon::PostProgressMessage(TInt aStage, TInt aError)
       
  1354   {
       
  1355     DEBUG("CLANLinkCommon::PostProgressMessage()");
       
  1356   
       
  1357   //Be careful when sending TStateChange message as RNodeChannelInterface will override the activity id
       
  1358   iSubConnectionProvider.RNodeInterface::PostMessage(Id(), TCFMessage::TStateChange( Elements::TStateChange( aStage, aError) ).CRef());
       
  1359   }
       
  1360 
       
  1361 // -----------------------------------------------------------------------------
       
  1362 // CLANLinkCommon::SetAllowedBearer
       
  1363 // -----------------------------------------------------------------------------
       
  1364 //
       
  1365 void CLANLinkCommon::SetAllowedBearer(CLanxBearer* aBearer)
       
  1366   {
       
  1367     iOnlyThisBearer = aBearer;
       
  1368   }
       
  1369   
       
  1370 // -----------------------------------------------------------------------------
       
  1371 // CLANLinkCommon::BearereIsActive
       
  1372 // -----------------------------------------------------------------------------
       
  1373 //
       
  1374 TBool CLANLinkCommon::BearerIsActive(CLanxBearer* aBearer)
       
  1375   {
       
  1376     if (!iOnlyThisBearer || 
       
  1377         aBearer == iOnlyThisBearer)
       
  1378       {
       
  1379       return ETrue;
       
  1380       }
       
  1381     return EFalse;      
       
  1382   }
       
  1383 
       
  1384 // -----------------------------------------------------------------------------
       
  1385 // CLANLinkCommon::PostFlowDownMessage
       
  1386 // -----------------------------------------------------------------------------
       
  1387 //
       
  1388 void CLANLinkCommon::PostFlowDownMessage(TInt aError)
       
  1389   {
       
  1390     DEBUG("CLANLinkCommon::PostFlowDownMessage()");
       
  1391   
       
  1392   if (iMMState == EStopping)
       
  1393       {
       
  1394       iSubConnectionProvider.PostMessage(Id(), TCFDataClient::TStopped(aError).CRef());     
       
  1395       }
       
  1396     else if (iMMState == EStarting)
       
  1397       {
       
  1398       iSubConnectionProvider.PostMessage(Id(), TEBase::TError(TCFDataClient::TStart::Id(), aError).CRef());
       
  1399       }
       
  1400     else if (iMMState == EStarted)
       
  1401       {
       
  1402       iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TDataClientGoneDown(aError).CRef());
       
  1403       }     
       
  1404     iMMState = EStopped;  
       
  1405   }
       
  1406 
       
  1407 
       
  1408 // -----------------------------------------------------------------------------
       
  1409 // CLANLinkCommon::PostFlowGoingDownMessage
       
  1410 // -----------------------------------------------------------------------------
       
  1411 //
       
  1412 void CLANLinkCommon::PostFlowGoingDownMessage(TInt aError, MNifIfNotify::TAction /*aAction*/)
       
  1413   {
       
  1414     DEBUG("CLANLinkCommon::PostFlowGoingDownMessage()");
       
  1415     
       
  1416   // TDataClientGoneDown only makes sense if the flow was actually started
       
  1417   ASSERT(iMMState == EStarted); 
       
  1418   iMMState = EStopped;
       
  1419   iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TDataClientGoneDown(aError).CRef());
       
  1420   }
       
  1421 
       
  1422   
       
  1423 // -----------------------------------------------------------------------------
       
  1424 // CLANLinkCommon::PostDataClientStartedMessage
       
  1425 // -----------------------------------------------------------------------------
       
  1426 //
       
  1427 void CLANLinkCommon::PostDataClientStartedMessage()
       
  1428   {
       
  1429     DEBUG("CLANLinkCommon::PostDataClientStartedMessage()");
       
  1430   
       
  1431   iMMState = EStarted;
       
  1432   iSubConnectionProvider.PostMessage(Id(), TCFDataClient::TStarted().CRef());
       
  1433   }
       
  1434 
       
  1435 
       
  1436 // -----------------------------------------------------------------------------
       
  1437 // CLANLinkCommon::MaybePostDataClientIdle
       
  1438 // -----------------------------------------------------------------------------
       
  1439 //
       
  1440 void CLANLinkCommon::MaybePostDataClientIdle()
       
  1441   {
       
  1442     DEBUG("CLANLinkCommon::MaybePostDataClientIdle()");
       
  1443   
       
  1444   if (iBearers->Count() == 0 && iMMState == EStopped)
       
  1445     {
       
  1446     iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TIdle().CRef());
       
  1447     }
       
  1448   }
       
  1449 
       
  1450 
       
  1451 void TEtherLLCFrame::SetDestAddr( TDesC8& aDest)
       
  1452 {
       
  1453     DEBUG("TEtherLLCFrame::SetDestAddr()");
       
  1454 
       
  1455     Mem::Copy(iDestAddr, aDest.Ptr(), KMACByteLength);    
       
  1456 }
       
  1457 
       
  1458 // -----------------------------------------------------------------------------
       
  1459 // CLANLinkCommon::SetSrcAddr
       
  1460 // -----------------------------------------------------------------------------
       
  1461 //
       
  1462 void TEtherLLCFrame::SetSrcAddr(TDesC8& aSrc)
       
  1463 {
       
  1464     DEBUG("TEtherLLCFrame::SetSrcAddr()");
       
  1465 
       
  1466     Mem::Copy(iSrcAddr, aSrc.Ptr(), KMACByteLength);
       
  1467 }
       
  1468 
       
  1469 // -----------------------------------------------------------------------------
       
  1470 // CLANLinkCommon::SetOUI
       
  1471 // -----------------------------------------------------------------------------
       
  1472 //
       
  1473 void TEtherLLCFrame::SetOUI(TUint32 aOUI)
       
  1474 {
       
  1475     DEBUG("TEtherLLCFrame::SetOUI()");
       
  1476 
       
  1477   //aOUI is in native order, but the result is
       
  1478   //always stored in network byte order.
       
  1479   //Can't use the bigendian methods, because
       
  1480   //they only work for 16 and 32 -bit items.
       
  1481   OUI[0] = (TUint8)((aOUI>>16)&0xff);
       
  1482   OUI[1] = (TUint8)((aOUI>>8)&0xff);
       
  1483   OUI[2] = (TUint8)(aOUI&0xff);
       
  1484 }