wlan_bearer/wlanldd/wlan_common/umac_common/src/UmacDot11Associated.cpp
changeset 0 c40eb8fe8501
child 3 6524e815f76f
equal deleted inserted replaced
-1:000000000000 0:c40eb8fe8501
       
     1 /*
       
     2 * Copyright (c) 2005-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 the License "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:   Implementation of the WlanDot11Associated class
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 95 %
       
    20 */
       
    21 
       
    22 #include "config.h"
       
    23 #include "UmacDot11Associated.h"
       
    24 #include "UmacContextImpl.h"
       
    25 #include "UmacWsaWriteMib.h"
       
    26 #include "umacinternaldefinitions.h"
       
    27 
       
    28 /**
       
    29 * Mask to determine the used encryption from WHA::ReceivePacket's aFlags 
       
    30 * parameter
       
    31 */
       
    32 const TUint32 KReceivePacketEncryptionMask = 0x00038000;
       
    33 
       
    34 
       
    35 // ================= MEMBER FUNCTIONS =======================
       
    36 
       
    37 // ---------------------------------------------------------------------------
       
    38 // 
       
    39 // ---------------------------------------------------------------------------
       
    40 //
       
    41 void WlanDot11Associated::OnBeaconFrameRx( 
       
    42     WlanContextImpl& aCtxImpl,
       
    43     const TAny* /*aFrame*/,
       
    44     const TUint32 /*aLength*/,
       
    45     WHA::TRcpi /*aRcpi*/,
       
    46     TUint8* aBuffer )
       
    47     {
       
    48     // release the Rx buffer
       
    49     aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
    50     }
       
    51 
       
    52 // ---------------------------------------------------------------------------
       
    53 // 
       
    54 // ---------------------------------------------------------------------------
       
    55 //
       
    56 void WlanDot11Associated::OnProbeResponseFrameRx( 
       
    57     WlanContextImpl& aCtxImpl,
       
    58     const TAny* /*aFrame*/,
       
    59     const TUint32 /*aLength*/,
       
    60     WHA::TRcpi /*aRcpi*/,
       
    61     TUint8* aBuffer )
       
    62     {
       
    63     // release the Rx buffer
       
    64     aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
    65     }
       
    66 
       
    67 // ---------------------------------------------------------------------------
       
    68 // 
       
    69 // ---------------------------------------------------------------------------
       
    70 //
       
    71 void WlanDot11Associated::OnDeauthenticateFrameRx( 
       
    72     WlanContextImpl& aCtxImpl,
       
    73     TUint8* aBuffer )
       
    74     {
       
    75     // release the Rx buffer
       
    76     aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
    77     }
       
    78 
       
    79 // ---------------------------------------------------------------------------
       
    80 // 
       
    81 // ---------------------------------------------------------------------------
       
    82 //
       
    83 void WlanDot11Associated::OnDisassociateFrameRx( 
       
    84     WlanContextImpl& aCtxImpl,
       
    85     TUint8* aBuffer )
       
    86     {
       
    87     // release the Rx buffer
       
    88     aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
    89     }
       
    90 
       
    91 // ---------------------------------------------------------------------------
       
    92 // 
       
    93 // ---------------------------------------------------------------------------
       
    94 //
       
    95 TSnapStatus WlanDot11Associated::ValiDateSnapHeader( 
       
    96     WlanContextImpl& aCtxImpl,
       
    97     const TUint8* aStartOfSnap ) const
       
    98     {
       
    99     TSnapStatus snapStatus( ESnapUnknown );
       
   100 
       
   101     if ( !os_memcmp( 
       
   102             aStartOfSnap, 
       
   103             &KEncapsulatingRfc1042SnapHeader, 
       
   104             sizeof( KEncapsulatingRfc1042SnapHeader ) ) )
       
   105         {
       
   106         snapStatus = ESnapDot11Ok;
       
   107         }
       
   108     else if ( !os_memcmp( 
       
   109                 aStartOfSnap, 
       
   110                 &KEncapsulating802_1hSnapHeader, 
       
   111                 sizeof( KEncapsulating802_1hSnapHeader ) ) )
       
   112         {
       
   113         snapStatus = ESnapDot11Ok;
       
   114         }
       
   115     else
       
   116         {
       
   117         // unknown SNAP. Status already correct. No action needed
       
   118         }
       
   119 
       
   120     if ( snapStatus == ESnapUnknown &&
       
   121          aCtxImpl.NetworkOperationMode() == WHA::EBSS &&
       
   122          aCtxImpl.GetProprietarySnapHeader() != KUndefinedSnapHeader )
       
   123         {
       
   124         // SNAP still unknown, but we a are in a infrastructure network and
       
   125         // a proprietary SNAP header has been defined.
       
   126         // Check if the SNAP is this proprietary SNAP header
       
   127         
       
   128         if ( !os_memcmp( 
       
   129                 aStartOfSnap, 
       
   130                 &(aCtxImpl.GetProprietarySnapHeader()), 
       
   131                 sizeof( aCtxImpl.GetProprietarySnapHeader() ) ) )
       
   132             {
       
   133             snapStatus = ESnapProprietaryOk;
       
   134             }        
       
   135         }
       
   136     
       
   137     return snapStatus;
       
   138     }
       
   139 
       
   140 // ---------------------------------------------------------------------------
       
   141 // 
       
   142 // ---------------------------------------------------------------------------
       
   143 //
       
   144 inline TBool WlanDot11Associated::RxDataMpduValid(
       
   145     const TUint32 aLength,
       
   146     const SDataFrameHeader& aFrameHeader,
       
   147     TBool aQosData,
       
   148     TBool aAmsdu,
       
   149     TUint aHtControlLen,
       
   150     TUint aSecurityHeaderLen,
       
   151     TUint aSecurityTrailerLen ) const
       
   152     {
       
   153     //========================================================================
       
   154     // validate frame length
       
   155     //========================================================================
       
   156     
       
   157     const TUint KMinAcceptableRxDataMpduLen ( 
       
   158         MinAcceptableRxDataMpduLen( 
       
   159             aQosData,
       
   160             aAmsdu,
       
   161             aHtControlLen,
       
   162             aSecurityHeaderLen,
       
   163             aSecurityTrailerLen ) );
       
   164     
       
   165     if ( aLength < KMinAcceptableRxDataMpduLen )
       
   166         {
       
   167         // frame shorter than min acceptable length; reject it 
       
   168         OsTracePrint( KRxFrame | KWarningLevel, (TUint8*)
       
   169             ("UMAC: WlanDot11Associated::RxDataMpduValid: WARNING: MPDU rejected because its shorter than min acceptable length of %d"),
       
   170             KMinAcceptableRxDataMpduLen );        
       
   171 
       
   172         return EFalse;
       
   173         }
       
   174     
       
   175     //========================================================================
       
   176     // validate To DS & From DS bits
       
   177     //========================================================================
       
   178 
       
   179     if ( !DoIsValidAddressBitCombination( aFrameHeader ) )
       
   180         {
       
   181         OsTracePrint( KRxFrame, (TUint8*)
       
   182             ("UMAC: WlanDot11Associated::RxDataMpduValid: MPDU rejected because of invalid To DS and/or From DS bit values") );
       
   183 
       
   184         return EFalse;
       
   185         }
       
   186             
       
   187     return ETrue;
       
   188     }
       
   189 
       
   190 // ---------------------------------------------------------------------------
       
   191 // defines the minimum acceptable Data MPDU length as:
       
   192 // dot11 MAC header length including SNAP and possibly existing HT Control 
       
   193 // field
       
   194 // + security header length
       
   195 // + subframe header length if the QoS Data MPDU contains an A-MSDU
       
   196 // + security trailer length
       
   197 // + Ethernet type field length
       
   198 // ---------------------------------------------------------------------------
       
   199 //
       
   200 inline TUint WlanDot11Associated::MinAcceptableRxDataMpduLen(
       
   201     TBool aQosData,
       
   202     TBool aAmsdu,
       
   203     TUint aHtControlLen,
       
   204     TUint aSecurityHeaderLen,
       
   205     TUint aSecurityTrailerLen ) const
       
   206     {
       
   207     return aQosData ? 
       
   208         sizeof( SQosDataMpduHeader ) + aHtControlLen
       
   209         + aSecurityHeaderLen
       
   210         + ( aAmsdu ? sizeof( SAmsduSubframeHeader ) : 0 )
       
   211         + aSecurityTrailerLen
       
   212         + sizeof( SEthernetType )
       
   213         :         
       
   214         sizeof( SDataMpduHeader )
       
   215         + aSecurityHeaderLen
       
   216         + aSecurityTrailerLen
       
   217         + sizeof( SEthernetType );
       
   218     }
       
   219 
       
   220 // ---------------------------------------------------------------------------
       
   221 // Note that address 1 is the DA (Destination Address) both in infrastructure
       
   222 // and IBSS network Rx frames
       
   223 // ---------------------------------------------------------------------------
       
   224 //
       
   225 inline TDaType WlanDot11Associated::RxFrameDaType(
       
   226     const SDataFrameHeader& aFrameHeader ) const
       
   227     {
       
   228     if ( IsGroupBitSet( aFrameHeader.iAddress1 ) )
       
   229         {
       
   230         // a multicast
       
   231         if ( aFrameHeader.iAddress1 == KBroadcastMacAddr )
       
   232             {
       
   233             // also a brodcast
       
   234             return EBroadcastAddress;
       
   235             }
       
   236         else
       
   237             {
       
   238             // a multicast but not a broadcast
       
   239             return EMulticastAddress;
       
   240             }
       
   241         }
       
   242     else
       
   243         {
       
   244         // a unicast
       
   245         return EUnicastAddress;
       
   246         }
       
   247     }
       
   248 
       
   249 // ---------------------------------------------------------------------------
       
   250 //  
       
   251 // ---------------------------------------------------------------------------
       
   252 //
       
   253 inline TBool WlanDot11Associated::RxMsduValid(
       
   254     WlanContextImpl& aCtxImpl,
       
   255     const SDataFrameHeader& aFrameHeader,
       
   256     const SAmsduSubframeHeader* aSubFrameHeader,
       
   257     const TUint8* aStartOfSnap,
       
   258     TUint16 aEtherType,
       
   259     TBool aMulticast,
       
   260     TUint32 aFlags,
       
   261     TSnapStatus& aSnapStatus ) const
       
   262     {
       
   263     //========================================================================
       
   264     // validate SNAP header
       
   265     //========================================================================
       
   266     
       
   267     aSnapStatus = ValiDateSnapHeader( aCtxImpl, aStartOfSnap );
       
   268     
       
   269     if ( aSnapStatus == ESnapUnknown )
       
   270         {
       
   271         // SNAP header is invalid
       
   272         
       
   273         OsTracePrint( KRxFrame, (TUint8*)
       
   274             ("UMAC: WlanDot11Associated::RxMsduValid: MSDU rejected because of invalid snap:"),
       
   275             aStartOfSnap, aStartOfSnap + sizeof( SSnapHeader ) );    
       
   276 
       
   277         return EFalse;
       
   278         }
       
   279 
       
   280     // determine if SA is our MAC address
       
   281     const TBool KSaIsOurMac ( 
       
   282         DoIsRxFrameSAourAddress( aCtxImpl, aFrameHeader, aSubFrameHeader ) );           
       
   283 
       
   284     //========================================================================
       
   285     // if this is a proprietary test MSDU but not sent by us, its not valid 
       
   286     // for us
       
   287     //========================================================================
       
   288 
       
   289     if ( aEtherType == KBounceType && !KSaIsOurMac )
       
   290         {
       
   291 #ifndef NDEBUG
       
   292         OsTracePrint( KRxFrame, (TUint8*)
       
   293             ("UMAC: WlanDot11Associated::RxMsduValid: proprietary test MSDU, but not sent by us. MSDU rejected") );
       
   294 
       
   295         if ( aSubFrameHeader )
       
   296             {
       
   297             OsTracePrint( KRxFrame, (TUint8*)
       
   298                 ("UMAC: Subframe DA:"), aSubFrameHeader->iDa );                
       
   299             OsTracePrint( KRxFrame, (TUint8*)
       
   300                 ("UMAC: Subframe SA:"), aSubFrameHeader->iSa );                
       
   301             }
       
   302         else
       
   303             {
       
   304             OsTracePrint( KRxFrame, (TUint8*)
       
   305                 ("UMAC: Address1:"), aFrameHeader.iAddress1);    
       
   306             OsTracePrint( KRxFrame, (TUint8*)
       
   307                 ("UMAC: Address2:"), aFrameHeader.iAddress2);    
       
   308             OsTracePrint( KRxFrame, (TUint8*)
       
   309                 ("UMAC: Address3:"), aFrameHeader.iAddress3);
       
   310             }
       
   311 #endif        
       
   312 
       
   313         return EFalse;
       
   314         }
       
   315 
       
   316     //========================================================================
       
   317     // non-test multicast MSDUs sent by us are not relevant for us
       
   318     //========================================================================
       
   319 
       
   320     if ( // SA is our MAC address
       
   321          KSaIsOurMac
       
   322          // AND this is a multicast frame
       
   323          && aMulticast
       
   324          // AND this is not a test frame
       
   325          && aEtherType != KBounceType )
       
   326         {
       
   327         // we have received a non-test multicast frame that was sent by us.
       
   328         // Ignore it.
       
   329         
       
   330 #ifndef NDEBUG
       
   331         OsTracePrint( KRxFrame, (TUint8*)
       
   332             ("UMAC: WlanDot11Associated::RxMsduValid: MSDU rejected because its a non-test multicast MSDU sent by us"));
       
   333         
       
   334         if ( aSubFrameHeader )
       
   335             {
       
   336             OsTracePrint( KRxFrame, (TUint8*)
       
   337                 ("UMAC: Subframe DA:"), aSubFrameHeader->iDa );                
       
   338             OsTracePrint( KRxFrame, (TUint8*)
       
   339                 ("UMAC: Subframe SA:"), aSubFrameHeader->iSa );                
       
   340             }
       
   341         else
       
   342             {
       
   343             OsTracePrint( KRxFrame, (TUint8*)
       
   344                 ("UMAC: Address1:"), aFrameHeader.iAddress1);    
       
   345             OsTracePrint( KRxFrame, (TUint8*)
       
   346                 ("UMAC: Address2:"), aFrameHeader.iAddress2);    
       
   347             OsTracePrint( KRxFrame, (TUint8*)
       
   348                 ("UMAC: Address3:"), aFrameHeader.iAddress3);
       
   349             }
       
   350 #endif
       
   351 
       
   352         return EFalse;
       
   353         }
       
   354         
       
   355     // determine the encryption of the frame
       
   356     const TUint32 KEncryption ( aFlags & KReceivePacketEncryptionMask );
       
   357 
       
   358     if ( aSnapStatus != ESnapProprietaryOk )
       
   359         {
       
   360         //====================================================================
       
   361         // validate MSDU with the applicable privacy mode filter
       
   362         //====================================================================
       
   363         if ( !aCtxImpl.ExecuteActivePrivacyModeFilter(
       
   364                 aFrameHeader,
       
   365                 aCtxImpl.iEnableUserData,
       
   366                 aEtherType,
       
   367                 aCtxImpl.PairWiseKeyType() != WHA::EKeyNone,
       
   368                 ( KEncryption == WHA::KEncryptAes || 
       
   369                   KEncryption == WHA::KEncryptTkip ||
       
   370                   KEncryption == WHA::KEncryptWapi ) ) )
       
   371             {
       
   372             return EFalse;
       
   373             }
       
   374         }
       
   375 
       
   376     // this MSDU has passed all our checks, so it is valid for us
       
   377     return ETrue;
       
   378     }
       
   379 
       
   380 // ---------------------------------------------------------------------------
       
   381 //  
       
   382 // ---------------------------------------------------------------------------
       
   383 //
       
   384 inline TUint WlanDot11Associated::RxMsduEthernetPayloadLength(
       
   385     const TUint32 aMpduLength, 
       
   386     TUint aSubframeLength, 
       
   387     TBool aQosData,
       
   388     TUint aHtControlLen,
       
   389     TUint aSecurityHeaderLen,
       
   390     TUint aSecurityTrailerLen ) const
       
   391     {
       
   392     TUint length ( 0 );
       
   393     
       
   394     if ( aSubframeLength )
       
   395         {
       
   396         // this ethernet payload is carried in an A-MSDU subframe
       
   397         
       
   398         length = aSubframeLength - sizeof( SSnapHeader );
       
   399 
       
   400         OsTracePrint( KRxFrame, (TUint8*)
       
   401             ("UMAC: subframe eth payload len: %d"),
       
   402             length );                        
       
   403         }
       
   404     else
       
   405         {
       
   406         // this ethernet payload is carried in a non-A-MSDU frame
       
   407 
       
   408         if ( aQosData )
       
   409             {
       
   410             length = 
       
   411                 // total length of the Rx frame
       
   412                 aMpduLength
       
   413                 // - MAC header length including SNAP
       
   414                 - ( sizeof( SQosDataMpduHeader ) + aHtControlLen )
       
   415                 // - security header length
       
   416                 - aSecurityHeaderLen
       
   417                 // - security trailer length
       
   418                 - aSecurityTrailerLen;
       
   419                 
       
   420             OsTracePrint( KRxFrame, (TUint8*)
       
   421                 ("UMAC: qos data eth payload len: %d"),
       
   422                 length );                        
       
   423             }
       
   424         else
       
   425             {
       
   426             length =
       
   427                 // total length of the Rx frame
       
   428                 aMpduLength
       
   429                 // MAC header length including SNAP
       
   430                 - sizeof( SDataMpduHeader )
       
   431                 // - security header length
       
   432                 - aSecurityHeaderLen
       
   433                 // - security trailer length
       
   434                 - aSecurityTrailerLen;
       
   435         
       
   436             OsTracePrint( KRxFrame, (TUint8*)
       
   437                 ("UMAC: non-qos data eth payload len: %d"),
       
   438                 length );                        
       
   439             }
       
   440         }
       
   441     
       
   442     return length;
       
   443     }
       
   444 
       
   445 // ---------------------------------------------------------------------------
       
   446 //   
       
   447 // ---------------------------------------------------------------------------
       
   448 //
       
   449 inline TUint8* WlanDot11Associated::NewBufForMgmtClientRxFrame(
       
   450     WlanContextImpl& aCtxImpl,
       
   451     TBool aProprieatarySnapFrame,
       
   452     TBool aQosFrame,
       
   453     TUint aHtControlLen,
       
   454     TUint aEtherPayloadLength ) const
       
   455     {
       
   456     TUint requiredLength ( 0 );
       
   457     
       
   458     if ( aProprieatarySnapFrame )
       
   459         {
       
   460         // forwarded as a Data MPDU
       
   461         
       
   462         requiredLength = aQosFrame ? 
       
   463             sizeof( SQosDataFrameHeader ) 
       
   464             + aHtControlLen 
       
   465             + aEtherPayloadLength :
       
   466             sizeof( SDataFrameHeader ) 
       
   467             + aEtherPayloadLength;        
       
   468         }
       
   469     else
       
   470         {
       
   471         // forwarded as Ethernet frame
       
   472         
       
   473         requiredLength = 2 * sizeof( TMacAddress ) + aEtherPayloadLength;
       
   474         }
       
   475     
       
   476     // request for a new Rx buffer
       
   477     return aCtxImpl.GetRxBuffer( 
       
   478         requiredLength, 
       
   479         // tell that this is an internally triggered buffer request
       
   480         ETrue );
       
   481     }
       
   482         
       
   483 // ---------------------------------------------------------------------------
       
   484 //  
       
   485 // ---------------------------------------------------------------------------
       
   486 //
       
   487 inline TBool WlanDot11Associated::RxMsduForUser(
       
   488     TUint16 aEtherType,
       
   489     TSnapStatus aSnapstatus ) const
       
   490     {
       
   491     if ( // not an EAPOL frame AND
       
   492          aEtherType != KEapolType &&
       
   493          // not a WAI frame AND
       
   494          aEtherType != KWaiType &&
       
   495          // not a WLAN Mgmt Client test frame
       
   496          aEtherType != KBounceType &&
       
   497          // not a proprietary SNAP frame
       
   498          aSnapstatus != ESnapProprietaryOk )
       
   499         {
       
   500         // a user data / protocol stack data frame
       
   501 
       
   502         return ETrue;
       
   503         }
       
   504     else
       
   505         {
       
   506         return EFalse;
       
   507         }
       
   508     }
       
   509 
       
   510 // ---------------------------------------------------------------------------
       
   511 //  
       
   512 // ---------------------------------------------------------------------------
       
   513 //
       
   514 inline void WlanDot11Associated::UpdateDataFrameRxStatistics(
       
   515     WlanContextImpl& aCtxImpl,
       
   516     TUint16 aEtherType,
       
   517     TBool aMulticast,
       
   518     WHA::TQueueId aAccessCategory ) const
       
   519     {
       
   520     if ( aEtherType != KBounceType )
       
   521         {
       
   522         // other than WLAN Mgmt Client test data frame received
       
   523         
       
   524         if ( aMulticast )
       
   525             {
       
   526             // multicast frame
       
   527     
       
   528             OsTracePrint( KRxFrame, (TUint8*)
       
   529                 ("UMAC: inc rx mcast cnt for AC: %d"),
       
   530                 aAccessCategory );
       
   531     
       
   532             // update frame statistics
       
   533             aCtxImpl.IncrementRxMulticastDataFrameCount( aAccessCategory );            
       
   534             }
       
   535         else
       
   536             {
       
   537             // unicast frame
       
   538     
       
   539             OsTracePrint( KRxFrame, (TUint8*)
       
   540                 ("UMAC: inc rx unicast cnt for AC: %d"),
       
   541                 aAccessCategory );
       
   542     
       
   543             // update frame statistics
       
   544             aCtxImpl.IncrementRxUnicastDataFrameCount( aAccessCategory );
       
   545             }
       
   546         }
       
   547     }
       
   548 
       
   549 // ---------------------------------------------------------------------------
       
   550 // 
       
   551 // ---------------------------------------------------------------------------
       
   552 //
       
   553 void WlanDot11Associated::OnDataFrameRx(
       
   554     WlanContextImpl& aCtxImpl,
       
   555     const TAny* aFrame,
       
   556     const TUint32 aLength,
       
   557     TUint32 aFlags,
       
   558     WHA::TRcpi aRcpi,
       
   559     TUint8* aBuffer )
       
   560     {
       
   561     OsTracePrint( KRxFrame, (TUint8*)
       
   562         ("UMAC: WlanDot11Associated::OnDataFrameRx") );    
       
   563 
       
   564     SDataMpduHeader* hdr 
       
   565         = reinterpret_cast<SDataMpduHeader*>(const_cast<TAny*>(aFrame));
       
   566     SQosDataMpduHeader* qoshdr 
       
   567         = reinterpret_cast<SQosDataMpduHeader*>(const_cast<TAny*>(aFrame));
       
   568 
       
   569     // determine the length of the security header (e.g. IV etc.) ...
       
   570     const TUint KSecurityHeaderLen( DecryptHdrOffset( aCtxImpl, aFlags ) );
       
   571 
       
   572     OsTracePrint( KRxFrame, (TUint8*)("UMAC: KSecurityHeaderLen: %d"),
       
   573         KSecurityHeaderLen );    
       
   574 
       
   575     // ... and the security trailer (e.g. MIC etc.)
       
   576     const TUint KSecurityTrailerLen( DecryptTrailerOffset( aCtxImpl, aFlags ) );
       
   577 
       
   578     OsTracePrint( KRxFrame, (TUint8*)("UMAC: KSecurityTrailerLen: %d"),
       
   579         KSecurityTrailerLen );    
       
   580 
       
   581     // as the MAC header of a QoS data MPDU has an additional field
       
   582     // we need to take that into account; so make a note if we indeed have 
       
   583     // received a QoS data MPDU
       
   584     const TBool KQosData = 
       
   585         ( hdr->iHdr.iFrameControl.iType == E802Dot11FrameTypeQosData ) ? 
       
   586         ETrue : EFalse;
       
   587 
       
   588     // the MAC header of HT QoS data MPDU also has an additional field,
       
   589     // so determine if that field is present and hence has a non-zero length
       
   590     const TUint KHtControlLen ( 
       
   591         KQosData && HtcFieldPresent( aCtxImpl, aFrame, aFlags ) ? 
       
   592             KHtControlFieldLength : 0 );
       
   593 
       
   594     // determine if the MPDU contains an A-MSDU
       
   595     const TBool KAmsdu ( 
       
   596         KQosData && qoshdr->iHdr.AmsduPresent() ? ETrue : EFalse );
       
   597     
       
   598     if ( !RxDataMpduValid(
       
   599             aLength,
       
   600             hdr->iHdr,
       
   601             KQosData,
       
   602             KAmsdu,
       
   603             KHtControlLen,
       
   604             KSecurityHeaderLen,
       
   605             KSecurityTrailerLen ) )
       
   606         {
       
   607         // the overall MAC MPDU (disregarding the included MSDU(s) at this
       
   608         // point) is not valid for us. Release the Rx buffer & abort
       
   609         aCtxImpl.iUmac.MarkRxBufFree( aBuffer );                            
       
   610         return;        
       
   611         }
       
   612     
       
   613     TUint8* framePtr ( 0 );
       
   614     WHA::TQueueId accessCategory( WHA::ELegacy );
       
   615 
       
   616     // User Priority is regarded as Best Effort (i.e. Legacy, i.e. zero) unless
       
   617     // the received MPDU is a QoS Data MPDU & a different priority is 
       
   618     // specified in its MAC header
       
   619     TUint8 userPriority( 0 );
       
   620     
       
   621     if ( KQosData )
       
   622         {
       
   623         // a QoS Data MPDU
       
   624         
       
   625         // move framePtr past the MAC header
       
   626         framePtr = reinterpret_cast<TUint8 *>(
       
   627             reinterpret_cast<SQosDataFrameHeader *>( hdr ) + 1 ) 
       
   628             + KHtControlLen;        
       
   629 
       
   630         // get the User Priority
       
   631         userPriority = qoshdr->iHdr.UserPriority();
       
   632 
       
   633         // make a note of the Access Category corresponding to the
       
   634         // user priority of the MPDU (note that there's a one to one 
       
   635         // mapping between Queue id and Access Category)       
       
   636         accessCategory = Queue( userPriority );
       
   637         }
       
   638     else
       
   639         {
       
   640         // move framePtr past the MAC header
       
   641         framePtr = reinterpret_cast<TUint8 *>(
       
   642             reinterpret_cast<SDataFrameHeader *>( hdr ) + 1 );
       
   643         }
       
   644 
       
   645     // move after possibly existing security header and possibly existing
       
   646     // A-MSDU subframe header, i.e. beginning of SNAP header
       
   647     framePtr += KAmsdu ? 
       
   648                 KSecurityHeaderLen + sizeof( SAmsduSubframeHeader ) : 
       
   649                 KSecurityHeaderLen;
       
   650     TUint8* snapLocation ( framePtr );
       
   651     
       
   652     // determine the DA type
       
   653     const TDaType KDaType ( RxFrameDaType( hdr->iHdr ) );
       
   654 
       
   655     TSnapStatus snapstatus( ESnapUnknown );
       
   656     TDataBuffer* latestValidPacketForUsr ( NULL );
       
   657     TUint nbrOfpacketsForUsr ( 0 );
       
   658     TUint nbrOfpacketsForMgmtClient ( 0 );
       
   659     const TUint KMaxNbrOfPacketsForUsr ( 30 );
       
   660     const TUint KMaxNbrOfPacketsForMgmtClient ( 10 );
       
   661     const TDataBuffer* packetsForUsr[KMaxNbrOfPacketsForUsr];
       
   662     const TDataBuffer* packetsForMgmtClient[KMaxNbrOfPacketsForMgmtClient];
       
   663     // one byte past the last actual payload byte (so excluding the potentially
       
   664     // present security trailer) of the MPDU
       
   665     const TUint8* const KMpduPayloadEnd ( 
       
   666         reinterpret_cast<const TUint8*>(aFrame) 
       
   667         + aLength 
       
   668         - KSecurityTrailerLen );
       
   669     TPowerMgmtModeChange powerMgmtModeChange ( ENoChange );
       
   670     
       
   671     // handle every MSDU contained in this MPDU. If this is not an A-MSDU
       
   672     // there's only a single MSDU in it.
       
   673     do
       
   674         {
       
   675         TUint8* rxBuffer ( aBuffer );
       
   676         
       
   677         // move after SNAP header to Ethernet type field
       
   678         framePtr += sizeof( SSnapHeader );     
       
   679         const SEthernetType* const KEtherTypeLocation 
       
   680             = reinterpret_cast<const SEthernetType*>( framePtr );
       
   681     
       
   682         // determine Ethernet type
       
   683         const TUint16 KEtherType = KEtherTypeLocation->Type();
       
   684     
       
   685         OsTracePrint( KRxFrame, (TUint8*)
       
   686             ("UMAC: ether type: 0x%04x"), 
       
   687             KEtherType );
       
   688 
       
   689         // pointer to subframe heaader; or NULL if the MPDU doesn't contain
       
   690         // an A-MSDU
       
   691         const SAmsduSubframeHeader* KSubframeHdr ( KAmsdu ?  
       
   692             ( reinterpret_cast<const SAmsduSubframeHeader*>(
       
   693                     snapLocation) - 1 ) : 
       
   694             NULL );
       
   695         
       
   696         // determine if this is a multicast MSDU
       
   697         TBool KMulticastMsdu ( EFalse );
       
   698         if ( KSubframeHdr )
       
   699             {
       
   700             KMulticastMsdu = IsGroupBitSet( KSubframeHdr->iDa );
       
   701             }
       
   702         else
       
   703             {
       
   704             KMulticastMsdu = ( KDaType == EUnicastAddress ? EFalse : ETrue );
       
   705             }
       
   706 
       
   707         // determine subframe length, which can be non-zero only if the MPDU
       
   708         // contains an A-MSDU
       
   709         const TUint KSubframeLen ( KSubframeHdr ?  KSubframeHdr->Length() : 0 );
       
   710         
       
   711         if ( !RxMsduValid(
       
   712                 aCtxImpl,
       
   713                 hdr->iHdr,
       
   714                 KSubframeHdr,
       
   715                 snapLocation,
       
   716                 KEtherType,
       
   717                 KMulticastMsdu,
       
   718                 aFlags,
       
   719                 snapstatus ) )
       
   720             {
       
   721             // this MSDU is not valid/relevant for us
       
   722 
       
   723             if ( KAmsdu )
       
   724                 {
       
   725                 // move pointer to the SNAP of the possibly existing next 
       
   726                 // subframe
       
   727                 snapLocation += 
       
   728                     Align4( sizeof( SAmsduSubframeHeader ) + KSubframeLen );
       
   729                 // update frame pointer accordingly
       
   730                 framePtr = snapLocation;
       
   731 
       
   732                 continue;
       
   733                 }
       
   734             else
       
   735                 {
       
   736                 // this MPDU doesn't contain an A-MSDU, so there cannot be
       
   737                 // more than a single MSDU in it
       
   738                 break;
       
   739                 }
       
   740             }
       
   741             
       
   742         // determine if this MSDU is for user / protocol stack
       
   743         const TBool KMsduForUser ( RxMsduForUser( KEtherType, snapstatus) );
       
   744         
       
   745         if ( KMsduForUser && !aCtxImpl.iUmac.ProtocolStackSideClientReady() )
       
   746             {
       
   747             // this MSDU should be forwarded up the protocol stack but the 
       
   748             // protocol stack client is not ready. So we need to skip at
       
   749             // least this MSDU. 
       
   750             // Move pointer to the SNAP of the possibly existing next subframe
       
   751             snapLocation += 
       
   752                 Align4( sizeof( SAmsduSubframeHeader ) + KSubframeLen );            
       
   753             // update frame pointer accordingly
       
   754             framePtr = snapLocation;
       
   755 
       
   756             OsTracePrint( KRxFrame | KWarningLevel, (TUint8*)
       
   757                 ("UMAC: WARNING: protocol stack client not ready; MSDU ignored") );
       
   758 
       
   759             continue;            
       
   760             }
       
   761 
       
   762         TDataBuffer* metaHdr ( aCtxImpl.GetRxFrameMetaHeader() );        
       
   763         if ( !metaHdr )
       
   764             {
       
   765             // no memory available for Rx frame meta header. This means that
       
   766             // we are not able to forward to higher layers the current MSDU or 
       
   767             // any MSDU(s) that possibly follow it in this same MPDU
       
   768 
       
   769             OsTracePrint( KRxFrame | KWarningLevel, (TUint8*)
       
   770                 ("UMAC: WARNING: no memory for Rx frame meta hdr; MSDU ignored") );
       
   771             break;
       
   772             }        
       
   773     
       
   774         const TUint KEtherPayloadLen( RxMsduEthernetPayloadLength(
       
   775                 aLength, 
       
   776                 KSubframeLen, 
       
   777                 KQosData,
       
   778                 KHtControlLen,
       
   779                 KSecurityHeaderLen,
       
   780                 KSecurityTrailerLen ) );
       
   781     
       
   782         if ( !KMsduForUser && KAmsdu )
       
   783             {
       
   784             // an MSDU for WLAN Mgmt Client which is also a part of an 
       
   785             // A-MSDU. In this case we need to allocate a new buffer for
       
   786             // this packet and copy it there. This is necessary as an 
       
   787             // A-MSDU may contain MSDUs both for the protocol stack side 
       
   788             // and for WLAN Mgmt Client. Either one of those clients may 
       
   789             // complete the handling of its MSDUs first at which point the
       
   790             // Rx buffer(s) for its MSDU(s) is freed. So we need to make 
       
   791             // sure that a buffer is not freed while a client is still 
       
   792             // handling MSDU(s) contained in it. We do this by always 
       
   793             // copying WLAN Mgmt client MSDU(s) part of an A-MSDU to 
       
   794             // new buffers.
       
   795             
       
   796             rxBuffer = NewBufForMgmtClientRxFrame(
       
   797                 aCtxImpl,
       
   798                 snapstatus == ESnapProprietaryOk,
       
   799                 KQosData,
       
   800                 KHtControlLen,
       
   801                 snapstatus == ESnapProprietaryOk ? 
       
   802                     KSubframeLen : KEtherPayloadLen );
       
   803             
       
   804             if ( !rxBuffer )
       
   805                 {
       
   806                 // allocation failed so we need to skip at least this MSDU. 
       
   807 
       
   808                 // Move pointer to the SNAP of the possibly existing next 
       
   809                 // subframe
       
   810                 snapLocation += 
       
   811                     Align4( sizeof( SAmsduSubframeHeader ) + KSubframeLen );                // update frame pointer accordingly
       
   812                 // update frame pointer accordingly
       
   813                 framePtr = snapLocation;
       
   814 
       
   815                 // also release the meta hdr which was planned to be used for
       
   816                 // this MSDU 
       
   817                 aCtxImpl.FreeRxFrameMetaHeader( metaHdr );
       
   818 
       
   819                 OsTracePrint( KRxFrame | KWarningLevel, (TUint8*)
       
   820                     ("UMAC: WARNING: new buf alloc for mgmt client frame failed; MSDU ignored") );
       
   821                 continue;
       
   822                 }
       
   823             }
       
   824         
       
   825         // set the offset to the beginning of the Rx buffer from the beginning
       
   826         // of the meta header. Note that this may be also negative
       
   827         metaHdr->KeSetBufferOffset(
       
   828             rxBuffer
       
   829             - reinterpret_cast<TUint8*>(metaHdr) );
       
   830         
       
   831         if ( snapstatus == ESnapProprietaryOk )
       
   832             {
       
   833             HandleProprietarySnapRxFrame( 
       
   834                 *metaHdr, 
       
   835                 KQosData,
       
   836                 aFrame, 
       
   837                 KSubframeHdr,
       
   838                 aLength, 
       
   839                 KSecurityHeaderLen, 
       
   840                 KSecurityTrailerLen,
       
   841                 KHtControlLen,
       
   842                 KAmsdu ? rxBuffer : NULL );
       
   843             }
       
   844         else
       
   845             {
       
   846             DoBuildEthernetFrame( 
       
   847                 *metaHdr, 
       
   848                 *hdr, 
       
   849                 // start of ethernet payload (includes ether type field)
       
   850                 reinterpret_cast<const TUint8*>(KEtherTypeLocation), 
       
   851                 // length of ethernet payload
       
   852                 KEtherPayloadLen,
       
   853                 KAmsdu,
       
   854                 !KMsduForUser && KAmsdu ? rxBuffer : NULL );
       
   855             }
       
   856         
       
   857         // set the frame's User Priority to the Rx buffer being passed 
       
   858         // to the client
       
   859         metaHdr->SetUserPriority( userPriority );                    
       
   860         // set the RCPI
       
   861         metaHdr->KeSetRcpi( aRcpi );
       
   862     
       
   863         if ( KEtherType == KBounceType )
       
   864             {
       
   865             metaHdr->FrameType( 
       
   866                 TDataBuffer::KEthernetTestFrame );
       
   867             }
       
   868 
       
   869         if ( KMsduForUser )
       
   870             {
       
   871             // a user data / protocol stack data frame
       
   872 
       
   873             OsTracePrint( KRxFrame, (TUint8*)
       
   874                 ("UMAC: data frame rx"));    
       
   875 
       
   876             packetsForUsr[nbrOfpacketsForUsr++] = metaHdr;            
       
   877             latestValidPacketForUsr = metaHdr;
       
   878             if ( KAmsdu )
       
   879                 {
       
   880                 metaHdr->KeSetFlags( TDataBuffer::KDontReleaseBuffer );
       
   881                 }
       
   882             }
       
   883         else
       
   884             {
       
   885             // a WLAN Mgmt Client data frame
       
   886             
       
   887             OsTracePrint( KRxFrame, (TUint8*)
       
   888                 ("UMAC: mgmt client frame rx"));    
       
   889 
       
   890             packetsForMgmtClient[nbrOfpacketsForMgmtClient++] = metaHdr;
       
   891             }
       
   892 
       
   893         //  move pointer to the SNAP of the possibly existing next subframe
       
   894         snapLocation += Align4( sizeof( SAmsduSubframeHeader ) + KSubframeLen );
       
   895         // update frame pointer accordingly
       
   896         framePtr = snapLocation;
       
   897 
       
   898         UpdateDataFrameRxStatistics(
       
   899             aCtxImpl,
       
   900             KEtherType,
       
   901             KMulticastMsdu,
       
   902             accessCategory );        
       
   903 
       
   904         // inform dynamic power mode mgr about Rx data frame acceptance        
       
   905         if ( // if this is not our test frame AND 
       
   906              KEtherType != KBounceType &&
       
   907              // need to change power mgmt mode hasn't already been detected
       
   908              // based on this received (A-)MSDU
       
   909              powerMgmtModeChange == ENoChange )
       
   910             {
       
   911             powerMgmtModeChange = aCtxImpl.OnFrameRx( 
       
   912                 accessCategory, 
       
   913                 KEtherType, 
       
   914                 KEtherPayloadLen, 
       
   915                 KDaType );
       
   916             }
       
   917         
       
   918         // inform Null Send Controller about data frame Rx
       
   919         aCtxImpl.OnDataRxCompleted( 
       
   920             ( KEtherType == KEapolType || KEtherType == KWaiType ) ?
       
   921             // as EAPOL and WAI frames or not really Voice data (they
       
   922             // are just sometimes sent with Voice priority), handle them 
       
   923             // here as Best Effort (Legacy)
       
   924             WHA::ELegacy : 
       
   925             accessCategory, 
       
   926             KEtherPayloadLen );
       
   927 
       
   928           // for a non-A-MSDU this loop is executed only once
       
   929         } while ( KAmsdu && snapLocation < KMpduPayloadEnd );
       
   930 
       
   931     if ( nbrOfpacketsForUsr )
       
   932         {
       
   933         latestValidPacketForUsr->KeClearFlags( 
       
   934             TDataBuffer::KDontReleaseBuffer );
       
   935 
       
   936         // complete user data / protocol stack data frame(s)
       
   937         if ( !aCtxImpl.iUmac.ProtocolStackDataReceiveComplete( 
       
   938                 packetsForUsr[0], 
       
   939                 nbrOfpacketsForUsr ) )
       
   940             {
       
   941             // there's no protocol stack client to whom to complete Rx packets.
       
   942             // (Actually the control should never arrive here as we have 
       
   943             // checked the readiness of the protocol stack client already
       
   944             // earlier)
       
   945             nbrOfpacketsForUsr = 0;
       
   946             }
       
   947         }
       
   948 
       
   949     if ( nbrOfpacketsForMgmtClient )
       
   950         {
       
   951         // complete WLAN Mgmt Client data frame(s)
       
   952         aCtxImpl.iUmac.MgmtDataReceiveComplete( 
       
   953             packetsForMgmtClient[0], 
       
   954             nbrOfpacketsForMgmtClient );
       
   955         }
       
   956 
       
   957     if ( ( !nbrOfpacketsForUsr && !nbrOfpacketsForMgmtClient ) ||
       
   958          ( KAmsdu && !nbrOfpacketsForUsr ) )
       
   959         {
       
   960         // the contents of the original Rx buffer are not needed any more,
       
   961         // so deallocate it        
       
   962         OsTracePrint( KRxFrame, (TUint8*)
       
   963             ("UMAC: free original Rx buf"));    
       
   964         aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
   965         }
       
   966     
       
   967     // if any change is needed regarding our power mgmt mode,
       
   968     // proceed with it
       
   969     PowerMgmtModeChange( aCtxImpl, powerMgmtModeChange );    
       
   970     }
       
   971     
       
   972 // ---------------------------------------------------------------------------
       
   973 // 
       
   974 // ---------------------------------------------------------------------------
       
   975 //
       
   976 void WlanDot11Associated::OnManagementActionFrameRx(
       
   977     WlanContextImpl& aCtxImpl,
       
   978     const TAny* aFrame,
       
   979     const TUint32 aLength,
       
   980     WHA::TRcpi aRcpi,
       
   981     TUint8* aBuffer ) const
       
   982     {
       
   983     OsTracePrint(  KRxFrame, (TUint8*)
       
   984         ("UMAC: WlanDot11Associated::OnManagementActionFrameRx"));    
       
   985 
       
   986     TDataBuffer* metaHdr ( aCtxImpl.GetRxFrameMetaHeader() );
       
   987 
       
   988     if ( metaHdr )
       
   989         {
       
   990         // set length and type
       
   991         metaHdr->KeSetLength( aLength );
       
   992         metaHdr->FrameType( TDataBuffer::KDot11Frame );
       
   993         // set RCPI
       
   994         metaHdr->KeSetRcpi( aRcpi );
       
   995         
       
   996         // set the offset to the beginning of the Rx buffer from the beginning
       
   997         // of the meta header. Note that this may be also negative
       
   998         metaHdr->KeSetBufferOffset(
       
   999             aBuffer
       
  1000             - reinterpret_cast<TUint8*>(metaHdr) );
       
  1001         
       
  1002         // set the offset to the beginning of the actual frame within the
       
  1003         // Rx buffer
       
  1004         metaHdr->KeSetOffsetToFrameBeginning( 
       
  1005             reinterpret_cast<const TUint8*>(aFrame)   // frame beginning
       
  1006             - aBuffer );                              // buffer beginning
       
  1007         
       
  1008         // complete
       
  1009         const TDataBuffer* KMetaHdr ( metaHdr );
       
  1010         aCtxImpl.iUmac.MgmtDataReceiveComplete( KMetaHdr, 1 );
       
  1011         }
       
  1012     else
       
  1013         {
       
  1014         // no memory available for the meta header. In this case we have no
       
  1015         // other choice than to discard the received frame. 
       
  1016         aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
  1017         OsTracePrint( KWarningLevel | KRxFrame, (TUint8*)
       
  1018             ("UMAC: WlanDot11Associated::OnManagementActionFrameRx: WARNING: no memory for meta hdr => abort rx") );            
       
  1019         }
       
  1020     }
       
  1021         
       
  1022 // ---------------------------------------------------------------------------
       
  1023 // 
       
  1024 // ---------------------------------------------------------------------------
       
  1025 //
       
  1026 TAny* WlanDot11Associated::RequestForBuffer( 
       
  1027     WlanContextImpl& aCtxImpl,
       
  1028     TUint16 aLength )
       
  1029     {
       
  1030     return aCtxImpl.GetRxBuffer( aLength );
       
  1031     }
       
  1032 
       
  1033 // ---------------------------------------------------------------------------
       
  1034 // 
       
  1035 // ---------------------------------------------------------------------------
       
  1036 //
       
  1037 void WlanDot11Associated::ReceivePacket( 
       
  1038     WlanContextImpl& aCtxImpl, 
       
  1039     WHA::TStatus aStatus,
       
  1040     const void* aFrame,
       
  1041     TUint16 aLength,
       
  1042     WHA::TRate /*aRate*/,
       
  1043     WHA::TRcpi aRcpi,
       
  1044     WHA::TChannelNumber /*aChannel*/,
       
  1045     TUint8* aBuffer,
       
  1046     TUint32 aFlags )
       
  1047     {
       
  1048     SDataMpduHeader* hdr( 
       
  1049         reinterpret_cast<SDataMpduHeader*>(const_cast<TAny*>(aFrame)) );
       
  1050 
       
  1051     if ( aStatus == WHA::KSuccess )
       
  1052         {
       
  1053         // packet reception success lets see what type of frame we have
       
  1054         OsTracePrint( KRxFrame, 
       
  1055             (TUint8*)
       
  1056             ("UMAC: WlanDot11Associated::ReceivePacket:frame receive success, frame type: 0x%02x"), 
       
  1057             hdr->iHdr.iFrameControl.iType );
       
  1058 
       
  1059         if ( ( hdr->iHdr.iFrameControl.iType == E802Dot11FrameTypeData )
       
  1060              || ( hdr->iHdr.iFrameControl.iType == E802Dot11FrameTypeQosData ) )
       
  1061             {
       
  1062             OnDataFrameRx( aCtxImpl, aFrame, aLength, aFlags, aRcpi, aBuffer );
       
  1063             
       
  1064             if ( aCtxImpl.InsertNewRcpiIntoPredictor( os_systemTime(), aRcpi ) )
       
  1065                 {
       
  1066                 // indicate WLAN signal loss prediction to WLAN Mgmt Client
       
  1067                 OnInDicationEvent( aCtxImpl, ESignalLossPrediction );
       
  1068                 }
       
  1069             }        
       
  1070         else if ( hdr->iHdr.iFrameControl.iType 
       
  1071             == E802Dot11FrameTypeManagementAction )
       
  1072             {
       
  1073             OnManagementActionFrameRx( 
       
  1074                 aCtxImpl, 
       
  1075                 aFrame, 
       
  1076                 aLength, 
       
  1077                 aRcpi, 
       
  1078                 aBuffer );
       
  1079 
       
  1080             if ( aCtxImpl.InsertNewRcpiIntoPredictor( os_systemTime(), aRcpi ) )
       
  1081                 {
       
  1082                 // indicate WLAN signal loss prediction to WLAN Mgmt Client
       
  1083                 OnInDicationEvent( aCtxImpl, ESignalLossPrediction );
       
  1084                 }
       
  1085             }
       
  1086         else if ( hdr->iHdr.iFrameControl.iType 
       
  1087             == E802Dot11FrameTypeDeauthentication )
       
  1088             {
       
  1089             OnDeauthenticateFrameRx( aCtxImpl, aBuffer );
       
  1090             }
       
  1091         else if ( hdr->iHdr.iFrameControl.iType 
       
  1092             == E802Dot11FrameTypeDisassociation )
       
  1093             {
       
  1094             OnDisassociateFrameRx( aCtxImpl, aBuffer );
       
  1095             }
       
  1096         else if ( hdr->iHdr.iFrameControl.iType 
       
  1097             == E802Dot11FrameTypeBeacon )
       
  1098             {
       
  1099             OnBeaconFrameRx( aCtxImpl, aFrame, aLength, aRcpi, aBuffer );
       
  1100             }
       
  1101         else if ( hdr->iHdr.iFrameControl.iType 
       
  1102             == E802Dot11FrameTypeProbeResp )
       
  1103             {
       
  1104             OnProbeResponseFrameRx( aCtxImpl, aFrame, aLength, aRcpi, aBuffer );
       
  1105             }
       
  1106         else
       
  1107             {
       
  1108             OsTracePrint( KRxFrame | KWarningLevel, (TUint8*)
       
  1109                 ("UMAC: WlanDot11Associated::ReceivePacket: unsupported frame type: 0x%02x"), 
       
  1110                 hdr->iHdr.iFrameControl.iType );            
       
  1111 
       
  1112             // release the Rx buffer
       
  1113             aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
  1114             }
       
  1115         }
       
  1116     else if ( aStatus == WHA::KDecryptFailure )
       
  1117         {
       
  1118         // decryption error
       
  1119         OsTracePrint( KRxFrame | KWarningLevel, (TUint8*)
       
  1120             ("UMAC: WlanDot11Associated::ReceivePacket: decrypt error for frame:"), hdr->iHdr );    
       
  1121 
       
  1122         OnInDicationEvent( aCtxImpl, EWepDecryptFailure );
       
  1123 
       
  1124         // release the Rx buffer
       
  1125         aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
  1126         }
       
  1127     else if ( aStatus == WHA::KMicFailure )
       
  1128         {
       
  1129         // MIC failed
       
  1130         OsTracePrint( KRxFrame | KWarningLevel, (TUint8*)
       
  1131             ("UMAC: WlanDot11Associated::ReceivePacket: MIC error for frame:"), hdr->iHdr );    
       
  1132 
       
  1133         // address 1 is always the DA in our case
       
  1134         OnInDicationEvent( aCtxImpl, 
       
  1135             (IsGroupBitSet( hdr->iHdr.iAddress1 )) 
       
  1136             ? EGroupKeyMicFailure : EPairwiseKeyMicFailure 
       
  1137             );
       
  1138 
       
  1139         // release the Rx buffer
       
  1140         aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
  1141         }    
       
  1142     else
       
  1143         {
       
  1144         // packet rececption failed 
       
  1145         OsTracePrint( KRxFrame | KWarningLevel, (TUint8*)
       
  1146             ("UMAC: WlanDot11Associated::ReceivePacket: frame receive failure"));
       
  1147 
       
  1148         // release the Rx buffer
       
  1149         aCtxImpl.iUmac.MarkRxBufFree( aBuffer );
       
  1150         }
       
  1151     }
       
  1152 
       
  1153 // ---------------------------------------------------------------------------
       
  1154 // 
       
  1155 // ---------------------------------------------------------------------------
       
  1156 //
       
  1157 TBool WlanDot11Associated::EncryptTxFrames( 
       
  1158     WlanContextImpl& aCtxImpl,
       
  1159     const TDataBuffer& aDataBuffer ) const
       
  1160     {
       
  1161     TBool encrypt ( EFalse );
       
  1162 
       
  1163     if ( aDataBuffer.KeFlags() & TDataBuffer::KTxFrameMustNotBeEncrypted )
       
  1164         {
       
  1165         // our client has instructed us not the encrypt this frame under
       
  1166         // any circumstances. EFalse will be returned. 
       
  1167         // No further action needed
       
  1168         }
       
  1169     else
       
  1170         {
       
  1171         const WHA::TKeyType pairwiseKey ( aCtxImpl.PairWiseKeyType() );
       
  1172         const WHA::TKeyType groupKey ( aCtxImpl.GroupKeyType() );
       
  1173     
       
  1174         if ( pairwiseKey != WHA::EKeyNone )
       
  1175             {
       
  1176             // pairwise key set => use encryption
       
  1177             encrypt = ETrue;
       
  1178             }
       
  1179         else
       
  1180             {
       
  1181             // pairwise key not set
       
  1182             
       
  1183             if ( groupKey == WHA::EWepGroupKey )
       
  1184                 {
       
  1185                 // wep group key set => use encryption
       
  1186                 encrypt = ETrue;
       
  1187                 }        
       
  1188             }
       
  1189         }
       
  1190         
       
  1191     return encrypt;
       
  1192     }
       
  1193 
       
  1194 // ---------------------------------------------------------------------------
       
  1195 // 
       
  1196 // ---------------------------------------------------------------------------
       
  1197 //
       
  1198 TUint WlanDot11Associated::DecryptHdrOffset( 
       
  1199     WlanContextImpl& aCtxImpl, 
       
  1200     TUint32 aFlags ) const
       
  1201     {
       
  1202     TUint offset( 0 );
       
  1203 
       
  1204     const TUint32 encryption ( aFlags & KReceivePacketEncryptionMask );
       
  1205 
       
  1206     if ( aCtxImpl.WHASettings().iCapability & WHA::SSettings::KNoSecHdrAndTrailer )
       
  1207         {
       
  1208         // no security header is present on this sw layer. It is removed
       
  1209         // on lower layers; when necessary.
       
  1210         // We will return zero, so no further actions
       
  1211         }
       
  1212     else
       
  1213         {
       
  1214         // IV and/or Ext IV or CCMP header is present
       
  1215         // on this sw layer; when applicable
       
  1216         
       
  1217         if ( encryption == WHA::KEncryptAes )
       
  1218             {
       
  1219             offset = KCcmpHeaderLength;
       
  1220             }
       
  1221         else if ( encryption == WHA::KEncryptTkip )
       
  1222             {
       
  1223             offset = KWepIVLength + KWepExtendedIVLength;  
       
  1224             }
       
  1225         else if ( encryption == WHA::KEncryptWep )
       
  1226             {
       
  1227             offset = KWepIVLength;
       
  1228             }
       
  1229         else if ( encryption == WHA::KEncryptWapi )
       
  1230             {
       
  1231             offset = KWapiHeaderLength;
       
  1232             }
       
  1233         else
       
  1234             {
       
  1235             // frame not encrypted; returns zero
       
  1236             }        
       
  1237         }
       
  1238 
       
  1239     return offset;
       
  1240     }
       
  1241 
       
  1242 // ---------------------------------------------------------------------------
       
  1243 // 
       
  1244 // ---------------------------------------------------------------------------
       
  1245 //
       
  1246 TUint WlanDot11Associated::DecryptTrailerOffset( 
       
  1247     WlanContextImpl& aCtxImpl, 
       
  1248     TUint32 aFlags ) const
       
  1249     {
       
  1250     TUint offset( 0 );
       
  1251     
       
  1252     const TUint32 encryption ( aFlags & KReceivePacketEncryptionMask );
       
  1253 
       
  1254     if ( aCtxImpl.WHASettings().iCapability & WHA::SSettings::KNoSecHdrAndTrailer )
       
  1255         {
       
  1256         // no security trailer is present on this sw layer. It is removed
       
  1257         // on lower layers; when necessary.
       
  1258         // We will return zero, so no further actions
       
  1259         }
       
  1260     else
       
  1261         {
       
  1262         // ICV and/or MIC field is present on this sw layer; when applicable
       
  1263     
       
  1264         if ( encryption == WHA::KEncryptAes )
       
  1265             {
       
  1266             offset = KMicLength;
       
  1267             }
       
  1268         else if ( encryption == WHA::KEncryptTkip )
       
  1269             {
       
  1270             offset = KMicLength + KWEPICVLength;
       
  1271             }
       
  1272         else if ( encryption == WHA::KEncryptWep )
       
  1273             {
       
  1274             offset = KWEPICVLength;
       
  1275             }
       
  1276         else if ( encryption == WHA::KEncryptWapi )
       
  1277             {
       
  1278             offset = KWapiMicLength;
       
  1279             }
       
  1280         else
       
  1281             {
       
  1282             // frame not encrypted; returns zero
       
  1283             }        
       
  1284         }
       
  1285 
       
  1286     return offset;
       
  1287     }
       
  1288 
       
  1289 // ---------------------------------------------------------------------------
       
  1290 // 
       
  1291 // ---------------------------------------------------------------------------
       
  1292 //
       
  1293 TUint WlanDot11Associated::ComputeEncryptionOffsetAmount(
       
  1294     const WlanContextImpl& aCtxImpl,
       
  1295     const TDataBuffer& aDataBuffer ) const
       
  1296     {
       
  1297     TUint offset( 0 );
       
  1298 
       
  1299     if ( // our client has instructed us not the encrypt this frame under
       
  1300          // any circumstances OR
       
  1301          ( aDataBuffer.KeFlags() & TDataBuffer::KTxFrameMustNotBeEncrypted ) ||
       
  1302          // no space is reserved for security header on this sw layer. It is
       
  1303          // done on lower layers; when necessary.
       
  1304          ( aCtxImpl.WHASettings().iCapability & 
       
  1305            WHA::SSettings::KNoSecHdrAndTrailer ) )
       
  1306         {
       
  1307         // We will return zero, so no further actions
       
  1308         }
       
  1309     else
       
  1310         {
       
  1311         // encryption is allowed if relevant and
       
  1312         // space is reserved for IV and/or Ext IV or CCMP header
       
  1313         // on this sw layer; when necessary
       
  1314 
       
  1315         const WHA::TKeyType groupKey( aCtxImpl.GroupKeyType() );
       
  1316         const WHA::TKeyType pairwiseKey( aCtxImpl.PairWiseKeyType() );
       
  1317 
       
  1318         if ( pairwiseKey == WHA::EAesPairWiseKey )
       
  1319             {
       
  1320             offset = KCcmpHeaderLength;
       
  1321             }
       
  1322         else if ( pairwiseKey == WHA::ETkipPairWiseKey )
       
  1323             {
       
  1324             offset = KWepIVLength + KWepExtendedIVLength;
       
  1325             }
       
  1326         else if ( pairwiseKey == WHA::EWepPairWiseKey )
       
  1327             {
       
  1328             offset = KWepIVLength;
       
  1329             }
       
  1330         else if ( pairwiseKey == WHA::EWapiPairWiseKey )
       
  1331             {
       
  1332             offset = KWapiHeaderLength;
       
  1333             }
       
  1334         else
       
  1335             {
       
  1336             // don't care of anything else
       
  1337             }
       
  1338 
       
  1339         if ( !offset )
       
  1340             {
       
  1341             // no encryption used based on pairwise key presence
       
  1342             // check for WEP groupkey presence
       
  1343             if ( groupKey == WHA::EWepGroupKey )
       
  1344                 {
       
  1345                 offset = KWepIVLength;
       
  1346                 }
       
  1347             else
       
  1348                 {
       
  1349                 // don't care of anything else as group key encyption is not 
       
  1350                 // supported for the other key types. For them we always have 
       
  1351                 // a pairwise key
       
  1352                 }
       
  1353             }        
       
  1354         }
       
  1355 
       
  1356     return offset;
       
  1357     }
       
  1358 
       
  1359 // ---------------------------------------------------------------------------
       
  1360 // 
       
  1361 // ---------------------------------------------------------------------------
       
  1362 //
       
  1363 TUint WlanDot11Associated::EncryptTrailerLength(
       
  1364     WlanContextImpl& aCtxImpl,
       
  1365     const TDataBuffer& aDataBuffer ) const
       
  1366     {
       
  1367     TUint length( 0 );
       
  1368 
       
  1369     if ( // our client has instructed us not the encrypt this frame under
       
  1370          // any circumstances OR
       
  1371          ( aDataBuffer.KeFlags() & TDataBuffer::KTxFrameMustNotBeEncrypted ) ||
       
  1372          // no space is reserved for security header on this sw layer. It is
       
  1373          // done on lower layers; when necessary.
       
  1374          ( aCtxImpl.WHASettings().iCapability & 
       
  1375            WHA::SSettings::KNoSecHdrAndTrailer ) )
       
  1376         {
       
  1377         // We will return zero, so no further actions
       
  1378         }
       
  1379     else
       
  1380         {
       
  1381         // encryption is allowed if relevant and
       
  1382         // space is reserved for ICV and/or MIC
       
  1383         // on this sw layer; when necessary
       
  1384 
       
  1385         const WHA::TKeyType groupKey( aCtxImpl.GroupKeyType() );
       
  1386         const WHA::TKeyType pairwiseKey( aCtxImpl.PairWiseKeyType() );    
       
  1387 
       
  1388         if ( pairwiseKey == WHA::EAesPairWiseKey )
       
  1389             {
       
  1390             length = KMicLength;
       
  1391             }
       
  1392         else if ( pairwiseKey == WHA::ETkipPairWiseKey )    
       
  1393             {
       
  1394             length = KMicLength + KWEPICVLength;
       
  1395             }
       
  1396         else if ( pairwiseKey == WHA::EWepPairWiseKey )
       
  1397             {
       
  1398             length = KWEPICVLength;
       
  1399             }
       
  1400         else if ( pairwiseKey == WHA::EWapiPairWiseKey )
       
  1401             {
       
  1402             length = KWapiMicLength;
       
  1403             }
       
  1404         else
       
  1405             {
       
  1406             // don't care of anything else
       
  1407             }
       
  1408 
       
  1409         if ( !length )
       
  1410             {
       
  1411             // no pairwise key present
       
  1412             // check for groupkey
       
  1413             if ( groupKey == WHA::EWepGroupKey )
       
  1414                 {
       
  1415                 length = KWEPICVLength;
       
  1416                 }
       
  1417             else
       
  1418                 {
       
  1419                 // don't care of anything else as group key encyption is not 
       
  1420                 // supported for the other key types. For them we always have 
       
  1421                 // a pairwise key
       
  1422                 }
       
  1423             }        
       
  1424         }
       
  1425 
       
  1426     return length;
       
  1427     }
       
  1428 
       
  1429 // ---------------------------------------------------------------------------
       
  1430 // 
       
  1431 // ---------------------------------------------------------------------------
       
  1432 //
       
  1433 TUint WlanDot11Associated::ComputeQosOffsetAmount(
       
  1434     WlanContextImpl& aCtxImpl ) const
       
  1435     {
       
  1436     const TUint KNoQosHeader( 0 );
       
  1437     
       
  1438     if ( aCtxImpl.QosEnabled() )        
       
  1439         {
       
  1440         return sizeof( T802Dot11QosControl );
       
  1441         }
       
  1442     else
       
  1443         {
       
  1444         return KNoQosHeader;
       
  1445         }    
       
  1446     }
       
  1447 
       
  1448 // ---------------------------------------------------------------------------
       
  1449 // 
       
  1450 // ---------------------------------------------------------------------------
       
  1451 //
       
  1452 void WlanDot11Associated::EncapsulateEthernetFrame(
       
  1453     WlanContextImpl& aCtxImpl,
       
  1454     TWlanUserTxDataCntx& aDataCntx,
       
  1455     TDataBuffer& aDataBuffer,
       
  1456     TUint16& aEtherType ) const
       
  1457     {
       
  1458     TUint8* etherFrameBeginning ( aDataBuffer.GetBuffer() );
       
  1459 
       
  1460     OsTracePrint( KWsaTxDetails, (TUint8*)
       
  1461         ("UMAC: WlanDot11Associated::EncapsulateEthernetFrame: supplied ether frame start address: 0x%08x"),
       
  1462         reinterpret_cast<TUint32>(etherFrameBeginning) );
       
  1463 
       
  1464     // start of dot11 frame
       
  1465     SDataFrameHeader* dot11_dataframe_hdr ( NULL );
       
  1466 
       
  1467     // start of ethernet frame
       
  1468     const SEthernetHeader* ether_hdr 
       
  1469         = reinterpret_cast<const SEthernetHeader*>(etherFrameBeginning);
       
  1470 
       
  1471     // determine Ethernet type
       
  1472     aEtherType = ether_hdr->Type();
       
  1473 
       
  1474     OsTracePrint( KWsaTxDetails, (TUint8*)
       
  1475         ("UMAC: ether type: 0x%04x"),
       
  1476         aEtherType );    
       
  1477 
       
  1478     // compute space required for encryption header
       
  1479     // after dot11 radio header and before data payload
       
  1480     const TUint encryption_offset = ( 
       
  1481         ComputeEncryptionOffsetAmount( aCtxImpl, aDataBuffer ) );
       
  1482 
       
  1483     OsTracePrint( KWsaTxDetails, (TUint8*)
       
  1484         ("UMAC: encryption_offset: %d"),
       
  1485         encryption_offset );    
       
  1486 
       
  1487     const TUint32 ether_offset = (KMacAddressLength << 1);
       
  1488     
       
  1489     // take a backup copy of the destination and source addresses from the
       
  1490     // ethernet frame as they will get overwritten
       
  1491     
       
  1492     TMacAddress da;
       
  1493     os_memcpy( 
       
  1494         reinterpret_cast<TUint8*>(&da), 
       
  1495         etherFrameBeginning, 
       
  1496         sizeof( TMacAddress ) );
       
  1497     TMacAddress sa;
       
  1498     os_memcpy( 
       
  1499         reinterpret_cast<TUint8*>(&sa), 
       
  1500         etherFrameBeginning + sizeof( TMacAddress ), 
       
  1501         sizeof( TMacAddress ) );
       
  1502 
       
  1503     // compute space possibly required at the end of the dot11 mac
       
  1504     // header for the QoS control field, which is required for QoS data frames
       
  1505     // This will be needed (i.e. the qosOffset will be > 0) if QoS is enabled
       
  1506     const TUint qosOffset = ComputeQosOffsetAmount( aCtxImpl );
       
  1507     // the mac header of HT QoS data frames also has an additional field,
       
  1508     // so determine if that field needs to be present and hence has a non-zero
       
  1509     // length
       
  1510     const TUint KHtControlOffset ( aCtxImpl.HtSupportedByNw() ? 
       
  1511             KHtControlFieldLength : 0 );
       
  1512     
       
  1513     if ( qosOffset )
       
  1514         {
       
  1515         // a QoS data frame
       
  1516         
       
  1517         OsTracePrint( KWsaTxDetails | KQos, (TUint8*)
       
  1518             ("UMAC: qos data frame"));    
       
  1519 
       
  1520         SQosDataFrameHeader* dot11QosDataFrameHdr = 
       
  1521             reinterpret_cast<SQosDataFrameHeader*>(
       
  1522                 etherFrameBeginning 
       
  1523                 + ether_offset
       
  1524                 - sizeof( KEncapsulatingRfc1042SnapHeader )
       
  1525                 - encryption_offset
       
  1526                 - KHtControlOffset
       
  1527                 - sizeof( SQosDataFrameHeader ) );
       
  1528 
       
  1529         // construct the MAC header
       
  1530         new (dot11QosDataFrameHdr) SQosDataFrameHeader;
       
  1531         
       
  1532         // set the frame type
       
  1533         dot11QosDataFrameHdr->iHdr.iFrameControl.iType = E802Dot11FrameTypeQosData;
       
  1534         
       
  1535         // reset the QoS control field
       
  1536         // => ack policy == acknowledge && priority == best effort
       
  1537         dot11QosDataFrameHdr->ResetQosControl();
       
  1538         
       
  1539         // set the user priority
       
  1540         dot11QosDataFrameHdr->SetUserPriority( aDataBuffer.UserPriority() );
       
  1541 
       
  1542         dot11_dataframe_hdr = reinterpret_cast<SDataFrameHeader*>(
       
  1543             dot11QosDataFrameHdr);
       
  1544 
       
  1545         if ( KHtControlOffset )
       
  1546             {
       
  1547             // HT control field is present => order bit needs to be set
       
  1548             dot11QosDataFrameHdr->iHdr.SetOrderBit();
       
  1549 
       
  1550             // clear the HT Control field, too
       
  1551             reinterpret_cast<SHtQosDataFrameHeader*>(
       
  1552                 dot11QosDataFrameHdr)->ResetHtControl();
       
  1553             }
       
  1554         else
       
  1555             {
       
  1556             // HT control field is not present => order bit needs to be cleared
       
  1557             dot11QosDataFrameHdr->iHdr.ClearOrderBit();
       
  1558             }        
       
  1559         }
       
  1560     else
       
  1561         {
       
  1562         // a non-QoS data frame
       
  1563 
       
  1564         OsTracePrint( KWsaTxDetails, (TUint8*)
       
  1565             ("UMAC: non-qos data frame"));    
       
  1566 
       
  1567         dot11_dataframe_hdr = reinterpret_cast<SDataFrameHeader*>(
       
  1568             etherFrameBeginning 
       
  1569             + ether_offset
       
  1570             - sizeof( KEncapsulatingRfc1042SnapHeader )
       
  1571             - encryption_offset
       
  1572             - sizeof( SDataFrameHeader ) );
       
  1573 
       
  1574         // construct the MAC header. In this case this also sets the frame type
       
  1575         // correctly
       
  1576         new (dot11_dataframe_hdr) SDataFrameHeader;
       
  1577         }
       
  1578 
       
  1579     // set the source address
       
  1580     dot11_dataframe_hdr->iAddress2 = sa;
       
  1581 
       
  1582     // set the destination address
       
  1583     DoSetTxMpduDaAddress( *dot11_dataframe_hdr, da );
       
  1584     
       
  1585     // set the To DS bit
       
  1586     if ( aCtxImpl.NetworkOperationMode() == WHA::EBSS )
       
  1587         {
       
  1588         dot11_dataframe_hdr->SetToDsBit();        
       
  1589         // set the BSS ID
       
  1590         dot11_dataframe_hdr->iAddress1 = aCtxImpl.GetBssId();
       
  1591         }
       
  1592     else
       
  1593         {
       
  1594         dot11_dataframe_hdr->ClearToDsBit();
       
  1595         // set the BSS ID
       
  1596         dot11_dataframe_hdr->iAddress3 = aCtxImpl.GetBssId();
       
  1597         }
       
  1598         
       
  1599     // determine if the frame needs to be encrypted
       
  1600     if ( EncryptTxFrames( aCtxImpl, aDataBuffer ) )
       
  1601         {
       
  1602         dot11_dataframe_hdr->SetWepBit();
       
  1603         }
       
  1604     else
       
  1605         {
       
  1606         dot11_dataframe_hdr->ClearWepBit();
       
  1607         }
       
  1608         
       
  1609     // set the snap header to correct location. 
       
  1610     os_memcpy( 
       
  1611         reinterpret_cast<TUint8*>(dot11_dataframe_hdr)
       
  1612         + sizeof( SDataFrameHeader )
       
  1613         + qosOffset
       
  1614         + KHtControlOffset
       
  1615         // space occupied by encryption header(s)
       
  1616         + encryption_offset,  
       
  1617         &KEncapsulatingRfc1042SnapHeader,
       
  1618         sizeof( KEncapsulatingRfc1042SnapHeader ) );        
       
  1619 
       
  1620     // clear the area reserved for IV etc, when necessary
       
  1621     if ( encryption_offset )
       
  1622         {
       
  1623         os_memset( 
       
  1624             reinterpret_cast<TUint8*>(dot11_dataframe_hdr) 
       
  1625                 + sizeof( SDataFrameHeader ) 
       
  1626                 + qosOffset
       
  1627                 + KHtControlOffset,
       
  1628             0,
       
  1629             encryption_offset );           
       
  1630         }
       
  1631 
       
  1632     // compute padding required for encryption trailer (ICV, MIC etc)
       
  1633     const TUint encryptTrailerLength = (
       
  1634         EncryptTrailerLength( aCtxImpl, aDataBuffer ) );
       
  1635     
       
  1636     // clear the area reserved for encryption trailer, when necessary
       
  1637     if ( encryptTrailerLength )
       
  1638         {
       
  1639         os_memset( 
       
  1640             reinterpret_cast<TUint8*>(dot11_dataframe_hdr) 
       
  1641             + sizeof( SDataFrameHeader )
       
  1642             + qosOffset
       
  1643             + KHtControlOffset
       
  1644             + encryption_offset
       
  1645             + sizeof( SSnapHeader )  
       
  1646             + aDataBuffer.GetLength() - ether_offset,
       
  1647             0,
       
  1648             encryptTrailerLength );                   
       
  1649         }
       
  1650     
       
  1651     // calculate frame length 
       
  1652     const TUint length_of_frame = 
       
  1653         // MAC header length
       
  1654         sizeof( SDataFrameHeader )
       
  1655         // length of possibly existing QoS control field 
       
  1656         + qosOffset
       
  1657         // length of possibly existing HT control field
       
  1658         + KHtControlOffset
       
  1659         // SNAP header length
       
  1660         + sizeof( SSnapHeader ) 
       
  1661         // length of ethernet payload (including ether type)
       
  1662         + aDataBuffer.GetLength() - ether_offset
       
  1663         // encryption header length
       
  1664         + encryption_offset
       
  1665         // encryption trailer length
       
  1666         + encryptTrailerLength;
       
  1667 
       
  1668     // we now have a dot11 frame ready to be sent
       
  1669     aDataCntx.Dot11FrameReady( 
       
  1670         reinterpret_cast<TUint8*>(dot11_dataframe_hdr),
       
  1671         length_of_frame );
       
  1672 
       
  1673     OsTracePrint( KWsaTxDetails, (TUint8*)
       
  1674         ("UMAC: length_of_frame (excl. fcs): %d"),
       
  1675         length_of_frame );
       
  1676     OsTracePrint( KWsaTxDetails, (TUint8*)
       
  1677         ("UMAC: frame start address: 0x%08x"),
       
  1678         reinterpret_cast<TUint32>(dot11_dataframe_hdr) );
       
  1679     }
       
  1680 
       
  1681 // ---------------------------------------------------------------------------
       
  1682 // 
       
  1683 // ---------------------------------------------------------------------------
       
  1684 //
       
  1685 void WlanDot11Associated::EncapsulateSnapFrame(
       
  1686     WlanContextImpl& aCtxImpl,
       
  1687     TWlanUserTxDataCntx& aDataCntx,
       
  1688     TDataBuffer& aDataBuffer,
       
  1689     TBool aEncrypt,
       
  1690     TUint aEncryptionOffset,
       
  1691     TUint aEncryptTrailerLength,
       
  1692     TUint aQosOffset,
       
  1693     TUint aHtControlOffset ) const
       
  1694     {
       
  1695     // extract start of frame. The frame starts with a SNAP header
       
  1696     TUint8* snapFrameBeginning ( aDataBuffer.GetBuffer() );
       
  1697 
       
  1698     // start of dot11 frame
       
  1699     SDataFrameHeader* dot11_dataframe_hdr( NULL );
       
  1700     
       
  1701     if ( aQosOffset )
       
  1702         {
       
  1703         OsTracePrint( KWsaTxDetails | KQos, (TUint8*)
       
  1704             ("UMAC: qos data frame"));    
       
  1705 
       
  1706         SQosDataFrameHeader* dot11QosDataFrameHdr( 
       
  1707             reinterpret_cast<SQosDataFrameHeader*>(
       
  1708                 snapFrameBeginning 
       
  1709                 - aEncryptionOffset
       
  1710                 - aHtControlOffset
       
  1711                 - sizeof( SQosDataFrameHeader )) );
       
  1712 
       
  1713         // construct the MAC header
       
  1714         new (dot11QosDataFrameHdr) SQosDataFrameHeader;
       
  1715         
       
  1716         // set the frame type
       
  1717         dot11QosDataFrameHdr->iHdr.iFrameControl.iType = E802Dot11FrameTypeQosData;
       
  1718         
       
  1719         // reset the QoS control field
       
  1720         // => ack policy == acknowledge && priority == best effort
       
  1721         dot11QosDataFrameHdr->ResetQosControl();        
       
  1722 
       
  1723         // set the user priority
       
  1724         dot11QosDataFrameHdr->SetUserPriority( aDataBuffer.UserPriority() );
       
  1725 
       
  1726         dot11_dataframe_hdr = reinterpret_cast<SDataFrameHeader*>(
       
  1727             dot11QosDataFrameHdr);
       
  1728 
       
  1729         if ( aHtControlOffset )
       
  1730             {
       
  1731             // HT control field is present => order bit needs to be set
       
  1732             dot11QosDataFrameHdr->iHdr.SetOrderBit();
       
  1733             // clear the HT Control field, too
       
  1734             reinterpret_cast<SHtQosDataFrameHeader*>(
       
  1735                 dot11QosDataFrameHdr)->ResetHtControl();
       
  1736             }
       
  1737         else
       
  1738             {
       
  1739             // HT control field is not present => order bit needs to be cleared
       
  1740             dot11QosDataFrameHdr->iHdr.ClearOrderBit();
       
  1741             }        
       
  1742         }
       
  1743     else
       
  1744         {
       
  1745         OsTracePrint( KWsaTxDetails | KQos, (TUint8*)
       
  1746             ("UMAC: non-qos data frame"));    
       
  1747 
       
  1748         dot11_dataframe_hdr = reinterpret_cast<SDataFrameHeader*>(
       
  1749             snapFrameBeginning 
       
  1750             - aEncryptionOffset
       
  1751             - sizeof( SDataFrameHeader ) );
       
  1752 
       
  1753         // construct the MAC header. In this case this also sets the frame type
       
  1754         // correctly
       
  1755         new (dot11_dataframe_hdr) SDataFrameHeader;
       
  1756         }
       
  1757 
       
  1758     // set the source address
       
  1759     dot11_dataframe_hdr->iAddress2 = aCtxImpl.iWlanMib.dot11StationId;
       
  1760 
       
  1761     // set the destination address
       
  1762     DoSetTxMpduDaAddress( *dot11_dataframe_hdr, 
       
  1763         aDataBuffer.KeDestinationAddress() );
       
  1764     
       
  1765     // set the To DS bit
       
  1766     if ( aCtxImpl.NetworkOperationMode() == WHA::EBSS )
       
  1767         {
       
  1768         dot11_dataframe_hdr->SetToDsBit();        
       
  1769         // set the BSS ID
       
  1770         dot11_dataframe_hdr->iAddress1 = aCtxImpl.GetBssId();
       
  1771         }
       
  1772     else
       
  1773         {
       
  1774         dot11_dataframe_hdr->ClearToDsBit();
       
  1775         // set the BSS ID
       
  1776         dot11_dataframe_hdr->iAddress3 = aCtxImpl.GetBssId();
       
  1777         }
       
  1778         
       
  1779     // determine if the frame needs to be encrypted
       
  1780     if ( aEncrypt )
       
  1781         {
       
  1782         dot11_dataframe_hdr->SetWepBit();
       
  1783         }
       
  1784     else
       
  1785         {
       
  1786         dot11_dataframe_hdr->ClearWepBit();
       
  1787         }
       
  1788 
       
  1789     // clear the area reserved for IV etc, when necessary
       
  1790     if ( aEncryptionOffset )
       
  1791         {
       
  1792         os_memset( 
       
  1793             reinterpret_cast<TUint8*>(dot11_dataframe_hdr) 
       
  1794                 + sizeof( SDataFrameHeader ) 
       
  1795                 + aQosOffset
       
  1796                 + aHtControlOffset,
       
  1797             0,
       
  1798             aEncryptionOffset );           
       
  1799         }
       
  1800     
       
  1801     // clear the area reserved for encryption trailer, when necessary
       
  1802     if ( aEncryptTrailerLength )
       
  1803         {
       
  1804         os_memset( 
       
  1805             reinterpret_cast<TUint8*>(dot11_dataframe_hdr) 
       
  1806             + sizeof( SDataFrameHeader )
       
  1807             + aQosOffset
       
  1808             + aHtControlOffset
       
  1809             + aEncryptionOffset
       
  1810             + aDataBuffer.GetLength(),
       
  1811             0,
       
  1812             aEncryptTrailerLength );                   
       
  1813         }
       
  1814 
       
  1815     // calculate frame length
       
  1816     const TUint length_of_frame = 
       
  1817         // MAC header length
       
  1818         sizeof( SDataFrameHeader ) +
       
  1819         // length of possibly existing QoS control field 
       
  1820         aQosOffset + 
       
  1821         // length of possibly existing HT control field
       
  1822         aHtControlOffset +
       
  1823         // payload (including SNAP header)
       
  1824         aDataBuffer.GetLength()
       
  1825         // encryption header length
       
  1826         + aEncryptionOffset
       
  1827         // encryption trailer length
       
  1828         + aEncryptTrailerLength;
       
  1829 
       
  1830     // we now have a dot11 frame ready to be sent
       
  1831     aDataCntx.Dot11FrameReady( 
       
  1832         reinterpret_cast<TUint8*>(dot11_dataframe_hdr),
       
  1833         length_of_frame );
       
  1834 
       
  1835     OsTracePrint( KWsaTxDetails, (TUint8*)
       
  1836         ("UMAC: length_of_frame: %d"),
       
  1837         length_of_frame );
       
  1838     OsTracePrint( KWsaTxDetails, (TUint8*)
       
  1839         ("UMAC: frame start address: 0x%08x"),
       
  1840         reinterpret_cast<TUint32>(dot11_dataframe_hdr) );
       
  1841     // trace the dot11 frame header
       
  1842     OsTracePrint( KWsaTxDetails, (TUint8*)
       
  1843         ("UMAC: Encapsulated prorietary SNAP Tx frame:"), 
       
  1844         *(reinterpret_cast<Sdot11MacHeader*>(dot11_dataframe_hdr))); 
       
  1845     }
       
  1846 
       
  1847 // ---------------------------------------------------------------------------
       
  1848 // 
       
  1849 // ---------------------------------------------------------------------------
       
  1850 //
       
  1851 void WlanDot11Associated::SetDot11FrameToTxBuffer(
       
  1852     const WlanContextImpl& aCtxImpl,
       
  1853     TWlanUserTxDataCntx& aDataCntx,
       
  1854     TDataBuffer& aDataBuffer ) const
       
  1855     {
       
  1856     OsTracePrint( KWsaTxDetails, (TUint8*)
       
  1857         ("UMAC: WlanDot11Associated::SetDot11FrameToTxBuffer") );    
       
  1858 
       
  1859     if ( aCtxImpl.HtSupportedByNw() && aCtxImpl.QosEnabled() )
       
  1860         {
       
  1861         // in this case we need to insert the HT Control field to the
       
  1862         // otherwise ready 802.11 MAC frame
       
  1863 
       
  1864         const TUint KOrigLengthOfFrame = aDataBuffer.GetLength();
       
  1865         const TUint KMgmtFrameMacHdrLen = sizeof( SManagementFrameHeader );
       
  1866         TUint8* KFrameStart = aDataBuffer.GetBuffer();
       
  1867 
       
  1868         os_memcpy( 
       
  1869             KFrameStart + 
       
  1870             KMgmtFrameMacHdrLen +
       
  1871             KHtControlFieldLength,
       
  1872             KFrameStart + 
       
  1873             KMgmtFrameMacHdrLen,
       
  1874             KOrigLengthOfFrame - KMgmtFrameMacHdrLen );
       
  1875 
       
  1876         // clear the added HT Control field
       
  1877         reinterpret_cast<SHtManagementFrameHeader*>( 
       
  1878             KFrameStart)->ResetHtControl();
       
  1879         // update frame length
       
  1880         aDataBuffer.KeSetLength( KOrigLengthOfFrame + KHtControlFieldLength );
       
  1881         // as the HT control field is present the order bit needs to be set
       
  1882         reinterpret_cast<SHtManagementFrameHeader*>( 
       
  1883             KFrameStart)->iMgmtFrameHdr.SetOrderBit();        
       
  1884         }
       
  1885     
       
  1886     // we now have a dot11 frame ready to be sent
       
  1887     aDataCntx.Dot11FrameReady( 
       
  1888         aDataBuffer.GetBuffer(), 
       
  1889         aDataBuffer.GetLength() );
       
  1890     }
       
  1891 
       
  1892 // ---------------------------------------------------------------------------
       
  1893 // 
       
  1894 // ---------------------------------------------------------------------------
       
  1895 //
       
  1896 void WlanDot11Associated::EncapsulateFrame(
       
  1897     WlanContextImpl& aCtxImpl,
       
  1898     TWlanUserTxDataCntx& aDataCntx,
       
  1899     TDataBuffer& aDataBuffer,
       
  1900     TUint16& aEtherType )
       
  1901     {
       
  1902     const TDataBuffer::TFrameType KFrameType( aDataBuffer.FrameType() );
       
  1903     
       
  1904     OsTracePrint( KWsaTx, (TUint8*)
       
  1905         ("UMAC: WlanDot11Associated::EncapsulateFrame: frame type: %d"),
       
  1906         KFrameType );
       
  1907     
       
  1908     if ( KFrameType == TDataBuffer::KEthernetFrame || 
       
  1909          KFrameType == TDataBuffer::KEthernetTestFrame )
       
  1910         {
       
  1911         // ethernet II frame in the buffer for tx
       
  1912 
       
  1913         EncapsulateEthernetFrame( 
       
  1914             aCtxImpl, 
       
  1915             aDataCntx, 
       
  1916             aDataBuffer, 
       
  1917             aEtherType );
       
  1918         }
       
  1919     else if ( KFrameType == TDataBuffer::KSnapFrame )
       
  1920         {
       
  1921         // frame beginning with a SNAP header in the buffer for tx
       
  1922 
       
  1923         EncapsulateSnapFrame( 
       
  1924             aCtxImpl, 
       
  1925             aDataCntx, 
       
  1926             aDataBuffer,
       
  1927             EncryptTxFrames( aCtxImpl, aDataBuffer ),
       
  1928             ComputeEncryptionOffsetAmount( aCtxImpl, aDataBuffer ),
       
  1929             EncryptTrailerLength( aCtxImpl, aDataBuffer ),
       
  1930             ComputeQosOffsetAmount( aCtxImpl ),
       
  1931             aCtxImpl.HtSupportedByNw() ? 
       
  1932                 KHtControlFieldLength : 
       
  1933                 0 );
       
  1934         }
       
  1935     else if ( KFrameType == TDataBuffer::KDot11Frame )
       
  1936         {
       
  1937         // ready made 802.11 frame in the buffer for tx
       
  1938 
       
  1939         SetDot11FrameToTxBuffer( aCtxImpl, aDataCntx, aDataBuffer );
       
  1940         }
       
  1941     else
       
  1942         {
       
  1943         // not supported
       
  1944         OsTracePrint( KErrorLevel, (TUint8*)("UMAC: frame_type: %d"),
       
  1945             KFrameType );
       
  1946         OsAssert( (TUint8*)("UMAC: panic"),(TUint8*)(WLAN_FILE), __LINE__ );                
       
  1947         }
       
  1948     }
       
  1949 
       
  1950 // ---------------------------------------------------------------------------
       
  1951 // 
       
  1952 // ---------------------------------------------------------------------------
       
  1953 //
       
  1954 TBool WlanDot11Associated::TxData( 
       
  1955     WlanContextImpl& aCtxImpl,
       
  1956     TDataBuffer& aDataBuffer,
       
  1957     TBool aMore )
       
  1958     {
       
  1959     TWlanUserTxDataCntx& data_cntx( aCtxImpl.GetTxDataCntx() );
       
  1960     
       
  1961     TBool stateChange( EFalse );
       
  1962 
       
  1963     if ( (aCtxImpl.ProtocolStackTxDataAllowed()) )
       
  1964         {
       
  1965         // protocol stack tx data allowed
       
  1966         // now construct a dot11 frame from databuffer to storage
       
  1967 
       
  1968         TUint16 etherType( 0 ); // initial value: not relevant
       
  1969         
       
  1970         // construct the frame
       
  1971         EncapsulateFrame( aCtxImpl, data_cntx, aDataBuffer, etherType );
       
  1972 
       
  1973         // dot11 frame ready to be sent so push it to the packet sceduler
       
  1974 
       
  1975         // start of dot11 frame to send
       
  1976         const TUint8* start_of_frame( 
       
  1977             data_cntx.StartOfFrame() );
       
  1978 
       
  1979         // select correct tx queue
       
  1980         const WHA::TQueueId queue_id( 
       
  1981             QueueId( aCtxImpl, start_of_frame ) );
       
  1982 
       
  1983         // push the frame to packet scheduler for transmission
       
  1984         aCtxImpl.PushPacketToPacketScheduler(
       
  1985             start_of_frame,
       
  1986             data_cntx.LengthOfFrame(),
       
  1987             queue_id,
       
  1988             E802Dot11FrameTypeData,
       
  1989             &aDataBuffer,
       
  1990             aMore,
       
  1991             OutgoingMulticastDataFrame( 
       
  1992                 reinterpret_cast<const SDataFrameHeader*>( start_of_frame ) ) );
       
  1993             // now just wait for the scheduler to call completion methods
       
  1994             
       
  1995         // check if we need to change power mgmt mode because of frame Tx
       
  1996         const TPowerMgmtModeChange KPowerMgmtModeChange ( 
       
  1997             aCtxImpl.OnFrameTx( queue_id, etherType ) );
       
  1998         
       
  1999         // if any change change is needed regarding our power mgmt mode,
       
  2000         // proceed with it
       
  2001         stateChange = PowerMgmtModeChange( aCtxImpl, KPowerMgmtModeChange );        
       
  2002         }
       
  2003     else
       
  2004         {
       
  2005         // protocol stack tx data not allowed
       
  2006 
       
  2007 #ifndef NDEBUG
       
  2008         // programming error
       
  2009         OsTracePrint( KErrorLevel, (TUint8*)
       
  2010             ("UMAC: Tx attempted when it's not allowed") );
       
  2011         OsAssert( (TUint8*)("UMAC: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
  2012 #else
       
  2013         aCtxImpl.iUmac.OnTxProtocolStackDataComplete( 
       
  2014             KErrNone,
       
  2015             &aDataBuffer );        
       
  2016 #endif        
       
  2017         }
       
  2018 
       
  2019     return stateChange;        
       
  2020     }
       
  2021 
       
  2022 // ---------------------------------------------------------------------------
       
  2023 // 
       
  2024 // ---------------------------------------------------------------------------
       
  2025 //
       
  2026 void WlanDot11Associated::OnPacketSendComplete(
       
  2027     WlanContextImpl& aCtxImpl, 
       
  2028     WHA::TStatus aStatus,
       
  2029     TUint32 aPacketId,
       
  2030     WHA::TRate aRate,
       
  2031     TUint32 /*aPacketQueueDelay*/,
       
  2032     TUint32 aMediaDelay,
       
  2033     TUint aTotalTxDelay,
       
  2034     TUint8 aAckFailures,
       
  2035     WHA::TQueueId aQueueId,
       
  2036     WHA::TRate aRequestedRate,
       
  2037     TBool aMulticastData )
       
  2038     {
       
  2039     if ( aPacketId == E802Dot11FrameTypeData ||
       
  2040          aPacketId == E802Dot11FrameTypeDataEapol )
       
  2041         {
       
  2042         // update data frame statistics
       
  2043         UpdateTxDataFrameStatistics( 
       
  2044             aCtxImpl,
       
  2045             aQueueId, 
       
  2046             aStatus, 
       
  2047             aMulticastData, 
       
  2048             aAckFailures,
       
  2049             aMediaDelay,
       
  2050             aTotalTxDelay );
       
  2051         }
       
  2052     else if ( aPacketId == E802Dot11FrameTypeQosDataNull )        
       
  2053         {
       
  2054         // inform Null Data frame sending controller of QoS Null data Tx 
       
  2055         // completion; successful or not
       
  2056         aCtxImpl.OnQosNullDataTxCompleted();
       
  2057         }        
       
  2058     else if ( aPacketId == E802Dot11FrameTypeDataNull )        
       
  2059         {
       
  2060         // inform Null Data frame sending controller of Null data Tx 
       
  2061         // completion; successful or not
       
  2062         aCtxImpl.OnNullDataTxCompleted();
       
  2063         }        
       
  2064 
       
  2065     if ( aStatus == WHA::KSuccess )
       
  2066         {
       
  2067         aCtxImpl.OnTxCompleted( aRate, ETrue, aQueueId, aRequestedRate );
       
  2068     
       
  2069         aCtxImpl.ResetFailedTxPacketCount();
       
  2070         DoRegainedBSSIndication( aCtxImpl );
       
  2071 
       
  2072         if ( aPacketId == E802Dot11FrameTypeData ||
       
  2073              aPacketId == E802Dot11FrameTypeDataEapol ||
       
  2074              aPacketId == E802Dot11FrameTypeTestFrame )
       
  2075             {
       
  2076             // inform Null Data frame sending controller of successful
       
  2077             // data frame Tx completion
       
  2078             aCtxImpl.OnDataTxCompleted( 
       
  2079                 aPacketId == E802Dot11FrameTypeDataEapol ?
       
  2080                 // as EAPOL and WAI frames or not really Voice data (we just
       
  2081                 // send them with Voice priority in WMM nw), handle them
       
  2082                 // here as Best Effort (Legacy)
       
  2083                 WHA::ELegacy : 
       
  2084                 aQueueId );
       
  2085             }
       
  2086         }
       
  2087     else if ( aStatus == WHA::KErrorLifetimeExceeded && !aAckFailures )
       
  2088         {
       
  2089         // the packet was discarded by WLAN PDD without any Tx attempts
       
  2090         // So this is not a Tx failure and we don't need to take
       
  2091         // any further actions
       
  2092         OsTracePrint( KWsaTxDetails, (TUint8*)
       
  2093             ("UMAC: WlanDot11Associated::OnPacketSendComplete: packet expired in PDD without any Tx attempts)"));
       
  2094         }
       
  2095     else
       
  2096         {
       
  2097         // an actual Tx failure has occurred
       
  2098         
       
  2099         aCtxImpl.OnTxCompleted( aRate, EFalse, aQueueId, aRequestedRate );
       
  2100     
       
  2101         aCtxImpl.IncrementFailedTxPacketCount();
       
  2102 
       
  2103         // if we have failed to send more than threshold number of 
       
  2104         // consecutive packets, send Consecutive Tx Failures indication to 
       
  2105         // WLAN Mgmt Client - unless already sent
       
  2106         if ( aCtxImpl.FailedTxPacketCount() > 
       
  2107              aCtxImpl.iWlanMib.iFailedTxPacketCountThreshold )
       
  2108             {
       
  2109             DoConsecutiveTxFailuresIndication( aCtxImpl );
       
  2110             aCtxImpl.ResetFailedTxPacketCount();
       
  2111             }        
       
  2112         }
       
  2113     
       
  2114     aCtxImpl.iUmac.OnTxDataSent();
       
  2115     }
       
  2116 
       
  2117 // ---------------------------------------------------------------------------
       
  2118 // 
       
  2119 // ---------------------------------------------------------------------------
       
  2120 //
       
  2121 void WlanDot11Associated::DoConsecutiveBeaconsLostIndication( 
       
  2122     WlanContextImpl& aCtxImpl )
       
  2123     {
       
  2124     if ( aCtxImpl.OnConsecutiveBeaconsLost() )
       
  2125         {
       
  2126         OnInDicationEvent( aCtxImpl, EConsecutiveBeaconsLost );
       
  2127         }
       
  2128     }
       
  2129 
       
  2130 // -----------------------------------------------------------------------------
       
  2131 // 
       
  2132 // -----------------------------------------------------------------------------
       
  2133 //
       
  2134 void WlanDot11Associated::DoConsecutiveTxFailuresIndication( 
       
  2135     WlanContextImpl& aCtxImpl )
       
  2136     {
       
  2137     if ( aCtxImpl.OnConsecutiveTxFailures() )
       
  2138         {
       
  2139         OnInDicationEvent( aCtxImpl, EConsecutiveTxFailures );
       
  2140         }
       
  2141     }
       
  2142 
       
  2143 // ---------------------------------------------------------------------------
       
  2144 // 
       
  2145 // ---------------------------------------------------------------------------
       
  2146 //
       
  2147 void WlanDot11Associated::DoRegainedBSSIndication( 
       
  2148     WlanContextImpl& aCtxImpl )
       
  2149     {
       
  2150     if ( aCtxImpl.OnBssRegained() )
       
  2151         {
       
  2152         OnInDicationEvent( aCtxImpl, EBSSRegained );
       
  2153         }
       
  2154     }
       
  2155 
       
  2156 // ---------------------------------------------------------------------------
       
  2157 // 
       
  2158 // ---------------------------------------------------------------------------
       
  2159 //
       
  2160 TBool WlanDot11Associated::AddMulticastAddr(
       
  2161     WlanContextImpl& aCtxImpl,
       
  2162     const TMacAddress& aMacAddr )
       
  2163     {
       
  2164     TBool stateTransitionOccurred( EFalse );
       
  2165     
       
  2166     OsTracePrint( 
       
  2167         KWlmCmdDetails, 
       
  2168         (TUint8*)
       
  2169         ("UMAC: WlanDot11Associated::AddMulticastAddr(): addr to be added:"),
       
  2170         aMacAddr);
       
  2171 
       
  2172     if ( aCtxImpl.MulticastFilteringDisAllowed() )
       
  2173         {
       
  2174         OsTracePrint( 
       
  2175             KWlmCmdDetails, 
       
  2176             (TUint8*)
       
  2177             ("UMAC: WlanDot11Associated::AddMulticastAddr(): Multicast filtering disallowed"));
       
  2178             
       
  2179         OnOidComplete( aCtxImpl, KErrGeneral );        
       
  2180         }
       
  2181     else
       
  2182         {        
       
  2183         if ( aCtxImpl.WHASettings().iNumOfGroupTableEntrys > 
       
  2184              aCtxImpl.MulticastAddressCount() )
       
  2185             {
       
  2186             // wha layer is able to take in an address
       
  2187             
       
  2188             // 1st try to add the address to our own internal bookkeeping
       
  2189             WlanContextImpl::TGroupAddStatus addStatus = 
       
  2190                 aCtxImpl.AddMulticastAddress( aMacAddr );
       
  2191 
       
  2192             switch ( addStatus )
       
  2193                 {
       
  2194                 case WlanContextImpl::EOk:
       
  2195                     OsTracePrint( 
       
  2196                         KWlmCmdDetails, 
       
  2197                         (TUint8*)
       
  2198                         ("UMAC: WlanDot11Associated::AddMulticastAddr(): Address will be added to the MIB"));
       
  2199                     // the address needed to be added and adding went ok.
       
  2200                     // Now update the group addresses MIB
       
  2201                     stateTransitionOccurred = SetGroupAddressesTableMib( aCtxImpl ); 
       
  2202                     break;
       
  2203                 case WlanContextImpl::EAlreadyExists: 
       
  2204                     OsTracePrint( 
       
  2205                         KWlmCmdDetails, 
       
  2206                         (TUint8*)
       
  2207                         ("UMAC: WlanDot11Associated::AddMulticastAddr(): Address already exists"));
       
  2208                     // the specified address already exists so there's no need
       
  2209                     // to update the group addresses MIB
       
  2210                     // just complete the request with OK status
       
  2211                     OnOidComplete( aCtxImpl );
       
  2212                     stateTransitionOccurred = EFalse;           
       
  2213                     break;
       
  2214                 case WlanContextImpl::EFull:
       
  2215                     OsTracePrint( 
       
  2216                         KWlmCmdDetails, 
       
  2217                         (TUint8*)
       
  2218                         ("UMAC: WlanDot11Associated::AddMulticastAddr(): Internal address table full; disallow multicast filtering"));
       
  2219                     // we are not able to take in any more addresses.
       
  2220                     // We will totally disable the multicast filtering
       
  2221                     // and we won't allow it to be enabled any more during 
       
  2222                     // the current nw connection
       
  2223                     //
       
  2224                     aCtxImpl.ResetMulticastAddresses();               
       
  2225                     aCtxImpl.MulticastFilteringDisAllowed( ETrue );
       
  2226                     stateTransitionOccurred = 
       
  2227                         SetGroupAddressesTableMib( aCtxImpl );
       
  2228                     break;
       
  2229                 default:
       
  2230                     // programming error
       
  2231                     OsTracePrint( KErrorLevel, (TUint8*)
       
  2232                         ("UMAC: addStatus: %d"), addStatus );
       
  2233                     OsAssert( (TUint8*)("UMAC: panic"), 
       
  2234                         (TUint8*)(WLAN_FILE), __LINE__ );
       
  2235                 }
       
  2236             }
       
  2237         else
       
  2238             {
       
  2239             OsTracePrint( 
       
  2240                 KWlmCmdDetails, 
       
  2241                 (TUint8*)
       
  2242                 ("UMAC: WlanDot11Associated::AddMulticastAddr(): WHA not able to accept address; disallow multicast filtering"));
       
  2243             // wha layer is not able to take in an address. Either this is one 
       
  2244             // address too many, or it doesn't support even a single address.
       
  2245             // In either case we will totally disable the multicast filtering
       
  2246             // and we won't allow it to be enabled any more during the current 
       
  2247             // nw connection
       
  2248             aCtxImpl.ResetMulticastAddresses();               
       
  2249             aCtxImpl.MulticastFilteringDisAllowed( ETrue );
       
  2250             stateTransitionOccurred = SetGroupAddressesTableMib( aCtxImpl );
       
  2251             }
       
  2252         }
       
  2253 
       
  2254     // signal caller whether a state transition occurred or not
       
  2255     return stateTransitionOccurred;
       
  2256     }
       
  2257 
       
  2258 // ---------------------------------------------------------------------------
       
  2259 // 
       
  2260 // ---------------------------------------------------------------------------
       
  2261 //
       
  2262 TBool WlanDot11Associated::RemoveMulticastAddr(
       
  2263     WlanContextImpl& aCtxImpl,
       
  2264     TBool aRemoveAll,
       
  2265     const TMacAddress& aMacAddr )
       
  2266     {
       
  2267     TBool stateTransitionOccurred( EFalse );
       
  2268     
       
  2269     OsTracePrint( 
       
  2270         KWlmCmdDetails, 
       
  2271         (TUint8*)
       
  2272         ("UMAC: WlanDot11Associated::RemoveMulticastAddr(): addr to be removed:"),
       
  2273         aMacAddr);
       
  2274 
       
  2275     if ( aCtxImpl.MulticastFilteringDisAllowed() )
       
  2276         {
       
  2277         OsTracePrint( 
       
  2278             KWlmCmdDetails, 
       
  2279             (TUint8*)
       
  2280             ("UMAC: WlanDot11Associated::RemoveMulticastAddr(): Multicast filtering disallowed"));
       
  2281         // filtering is not allowed currently so there can't be any addresses
       
  2282         // to remove. Just complete the request with OK status            
       
  2283         OnOidComplete( aCtxImpl );        
       
  2284         }
       
  2285     else
       
  2286         {
       
  2287         if ( aRemoveAll )        
       
  2288             {
       
  2289             OsTracePrint( 
       
  2290                 KWlmCmdDetails, 
       
  2291                 (TUint8*)
       
  2292                 ("UMAC: WlanDot11Associated::RemoveMulticastAddr(): remove all"));
       
  2293             // remove all addresses; naturally will also disable filtering
       
  2294             aCtxImpl.ResetMulticastAddresses();
       
  2295             stateTransitionOccurred = SetGroupAddressesTableMib( aCtxImpl );            
       
  2296             }
       
  2297         else
       
  2298             {            
       
  2299             // 1st remove the specified address from our own internal 
       
  2300             // bookkeeping, if it exists
       
  2301             if ( aCtxImpl.RemoveMulticastAddress( aMacAddr ) )
       
  2302                 {
       
  2303                 OsTracePrint( 
       
  2304                     KWlmCmdDetails, 
       
  2305                     (TUint8*)
       
  2306                     ("UMAC: WlanDot11Associated::RemoveMulticastAddr(): removing the specified address"));
       
  2307                 // it existed, so update the group addresses MIB, too
       
  2308                 stateTransitionOccurred = SetGroupAddressesTableMib( aCtxImpl );                 
       
  2309                 }
       
  2310             else
       
  2311                 {
       
  2312                 OsTracePrint( 
       
  2313                     KWlmCmdDetails, 
       
  2314                     (TUint8*)
       
  2315                     ("UMAC: WlanDot11Associated::RemoveMulticastAddr(): specified address doesn't exist, nothing to do"));
       
  2316                 // it did't exist, so there's nothing to remove
       
  2317                 // Just complete the request with OK status            
       
  2318                 OnOidComplete( aCtxImpl );                    
       
  2319                 }
       
  2320             }
       
  2321         }
       
  2322 
       
  2323     // signal caller whether a state transition occurred or not
       
  2324     return stateTransitionOccurred;
       
  2325     }
       
  2326 
       
  2327 // ---------------------------------------------------------------------------
       
  2328 // 
       
  2329 // ---------------------------------------------------------------------------
       
  2330 //
       
  2331 TBool WlanDot11Associated::AddBroadcastWepKey(
       
  2332     WlanContextImpl& aCtxImpl,
       
  2333     TUint32 aKeyIndex,             
       
  2334     TBool aUseAsDefaulKey,                
       
  2335     TUint32 aKeyLength,                      
       
  2336     const TUint8 aKey[KMaxWEPKeyLength],
       
  2337     const TMacAddress& aMac )
       
  2338     {
       
  2339     return OnAddBroadcastWepKey( aCtxImpl, aKeyIndex, aUseAsDefaulKey, 
       
  2340         EFalse, // do NOT set as PTK
       
  2341         aKeyLength, aKey, aMac );
       
  2342     }
       
  2343 
       
  2344 // -----------------------------------------------------------------------------
       
  2345 // 
       
  2346 // -----------------------------------------------------------------------------
       
  2347 //
       
  2348 TBool WlanDot11Associated::ConfigureTxQueueIfNecessary( 
       
  2349     WlanContextImpl& aCtxImpl,
       
  2350     TQueueId aQueueId,
       
  2351     TUint16 aMediumTime,
       
  2352     TUint32 aMaxTxMSDULifetime )
       
  2353     {
       
  2354     // this cast is safe as the types are effectively the same
       
  2355     const WHA::TQueueId whaQueueId = static_cast<WHA::TQueueId>(aQueueId);
       
  2356     
       
  2357     if ( aMediumTime != aCtxImpl.iWlanMib.iMediumTime[whaQueueId] ||
       
  2358          aMaxTxMSDULifetime != 
       
  2359             aCtxImpl.iWlanMib.dot11MaxTransmitMSDULifetime[whaQueueId] )
       
  2360         {
       
  2361         // at least one of the parameters for this queue is changed => a
       
  2362         // reconfiguration is needed
       
  2363         
       
  2364         // update the queue parameters. These values will be used in the
       
  2365         // queue reconfiguration
       
  2366 
       
  2367         aCtxImpl.iWlanMib.iMediumTime[aQueueId] = aMediumTime;
       
  2368         aCtxImpl.iWlanMib.dot11MaxTransmitMSDULifetime[whaQueueId] = 
       
  2369             aMaxTxMSDULifetime;
       
  2370 
       
  2371         OsTracePrint( KUmacDetails, (TUint8*)
       
  2372             ("UMAC: WlanDot11Associated::ConfigureTxQueueIfNecessary: reconfiguring the queue is necessary") );
       
  2373 
       
  2374         // reconfigure the queue. Also request the WLAN mgmt client request
       
  2375         // to be completed
       
  2376         return ConfigureTxQueue( aCtxImpl, whaQueueId, ETrue );
       
  2377         }
       
  2378     else
       
  2379         {
       
  2380         // the provided queue parameters have not changed, so no need to
       
  2381         // reconfigure the queue
       
  2382         
       
  2383         OsTracePrint( KUmacDetails, (TUint8*)
       
  2384             ("UMAC: WlanDot11Associated::ConfigureTxQueueIfNecessary: no queue reconfigure is necessary") );
       
  2385 
       
  2386         // complete the WLAN Mgmt Client request
       
  2387         OnOidComplete( aCtxImpl, KErrNone );
       
  2388 
       
  2389         // signal caller that no state transition occurred
       
  2390         return EFalse;
       
  2391         }
       
  2392     }
       
  2393  
       
  2394 // ---------------------------------------------------------------------------
       
  2395 // 
       
  2396 // ---------------------------------------------------------------------------
       
  2397 //
       
  2398 TBool WlanDot11Associated::SetGroupAddressesTableMib(
       
  2399     WlanContextImpl& aCtxImpl )
       
  2400     {
       
  2401     const TMacAddress* multicastAddresses( NULL );
       
  2402     const TUint32 nbrOfAddrs( 
       
  2403         aCtxImpl.GetMulticastAddresses( multicastAddresses ) );
       
  2404 
       
  2405     TUint32 mibLength(  
       
  2406         // mib header length
       
  2407         WHA::Sdot11GroupAddressesTable::KHeaderSize
       
  2408         // + mib data length
       
  2409         + ( sizeof( TMacAddress ) * nbrOfAddrs ) );
       
  2410 
       
  2411     // align length of MIB to 4-byte boundary
       
  2412     mibLength = Align4( mibLength );
       
  2413     
       
  2414     OsTracePrint( 
       
  2415         KWlmCmdDetails, 
       
  2416         (TUint8*)
       
  2417         ("UMAC: WlanDot11Associated::SetGroupAddressesTableMib(): mibLength: %d"), 
       
  2418         mibLength );        
       
  2419 
       
  2420     // allocate memory for the mib to write
       
  2421     WHA::Sdot11GroupAddressesTable* mib 
       
  2422         = static_cast<WHA::Sdot11GroupAddressesTable*>
       
  2423         (os_alloc( mibLength )); 
       
  2424 
       
  2425     if ( !mib )
       
  2426         {
       
  2427         // allocation failed
       
  2428         // simulate macnotresponding error
       
  2429         OsTracePrint( KWarningLevel, (TUint8*)
       
  2430             ("UMAC: WlanDot11Associated::SetGroupAddressesTableMib(): memory allocating failed") );
       
  2431         return DoErrorIndication( aCtxImpl, WHA::KErrorMacNotResponding );
       
  2432         }
       
  2433     
       
  2434     if ( nbrOfAddrs )
       
  2435         {
       
  2436         // at least one address exists, so enable multicast address filtering
       
  2437         mib->iEnable = ETrue;
       
  2438         }
       
  2439     else
       
  2440         {
       
  2441         // no addresses, so disable filtering
       
  2442         mib->iEnable = EFalse;
       
  2443         OsTracePrint( KWlmCmdDetails, (TUint8*)
       
  2444             ("UMAC: WlanDot11Associated::SetGroupAddressesTableMib(): no addresses; disable filtering") );
       
  2445         }
       
  2446 
       
  2447     mib->iNumOfAddrs = nbrOfAddrs;
       
  2448     
       
  2449     // copy the multicast addresses after the mib header
       
  2450     os_memcpy( mib->iAddrData,
       
  2451                reinterpret_cast<TUint8*>(const_cast<TMacAddress*>(
       
  2452                     multicastAddresses)),
       
  2453                ( sizeof( TMacAddress ) * nbrOfAddrs ) );
       
  2454         
       
  2455     WlanWsaWriteMib& wha_cmd = aCtxImpl.WsaWriteMib();
       
  2456         
       
  2457     wha_cmd.Set( 
       
  2458         aCtxImpl, 
       
  2459         WHA::KMibDot11GroupAddressesTable, 
       
  2460         mibLength, 
       
  2461         mib );
       
  2462         
       
  2463     // change global state: entry procedure triggers action
       
  2464     ChangeState( aCtxImpl, 
       
  2465         *this,              // prev state
       
  2466         wha_cmd,            // next state
       
  2467         // the ACT
       
  2468         KCompleteManagementRequest
       
  2469         );   
       
  2470 
       
  2471     os_free( mib ); // release the allocated memory
       
  2472 
       
  2473     // signal caller that a state transition occurred
       
  2474     return ETrue;
       
  2475     }         
       
  2476 
       
  2477 // ---------------------------------------------------------------------------
       
  2478 // 
       
  2479 // ---------------------------------------------------------------------------
       
  2480 //
       
  2481 TBool WlanDot11Associated::PowerMgmtModeChange(
       
  2482     WlanContextImpl& aCtxImpl,
       
  2483     TPowerMgmtModeChange aPowerMgmtModeChange )
       
  2484     {
       
  2485     TBool stateChange ( EFalse );
       
  2486     
       
  2487     if ( aPowerMgmtModeChange != ENoChange )
       
  2488         {
       
  2489         // power mgmt mode change needed
       
  2490         
       
  2491         if ( aPowerMgmtModeChange == EToActive )
       
  2492             {
       
  2493             aCtxImpl.DesiredDot11PwrMgmtMode( WHA::KPsDisable );                
       
  2494             }
       
  2495         else if ( aPowerMgmtModeChange == EToLightPs )
       
  2496             {
       
  2497             aCtxImpl.DesiredDot11PwrMgmtMode( WHA::KPsEnable );
       
  2498             aCtxImpl.SetDesiredPsModeConfig( 
       
  2499                 aCtxImpl.ClientLightPsModeConfig() );                
       
  2500             }
       
  2501         else // aPowerMgmtModeChange == EToDeepPs
       
  2502             {
       
  2503             aCtxImpl.DesiredDot11PwrMgmtMode( WHA::KPsEnable );
       
  2504             aCtxImpl.SetDesiredPsModeConfig( 
       
  2505                 aCtxImpl.ClientDeepPsModeConfig() );                
       
  2506             }
       
  2507         
       
  2508         if ( !(aCtxImpl.WsaCmdActive()) )
       
  2509             {
       
  2510             // proceed with the power mgmt mode change
       
  2511             stateChange = ChangePowerMgmtMode( aCtxImpl );
       
  2512             }
       
  2513         else
       
  2514             {
       
  2515             // WHA command is in progress so we must defer this access
       
  2516             aCtxImpl.RegisterEvent( KPowerMgmtTransition );
       
  2517 
       
  2518             OsTracePrint( KEventDispatcher | KPwrStateTransition, 
       
  2519                 (TUint8*)("UMAC: WlanDot11Associated::PowerMgmtModeChange: power mgmt mode change event registered"));                
       
  2520             }
       
  2521         }
       
  2522     
       
  2523     return stateChange;
       
  2524     }
       
  2525 
       
  2526 // ---------------------------------------------------------------------------
       
  2527 // 
       
  2528 // ---------------------------------------------------------------------------
       
  2529 //
       
  2530 void WlanDot11Associated::HandleProprietarySnapRxFrame( 
       
  2531     TDataBuffer& aBuffer,
       
  2532     TBool aQosData, 
       
  2533     const TAny* const aFrame, 
       
  2534     const SAmsduSubframeHeader* aSubFrameHeader,
       
  2535     TUint aLength,
       
  2536     TUint aDecryptHeaderLen,
       
  2537     TUint aDecryptTrailerLen,
       
  2538     TUint aHtControlLen,
       
  2539     TUint8* aCopyBuffer ) const
       
  2540     {
       
  2541     OsTracePrint( KRxFrame, (TUint8*)
       
  2542         ("UMAC: WlanDot11Associated::HandleProprietarySnapRxFrame"));
       
  2543 
       
  2544     // prepare received frame with proprietary SNAP header for wlan mgmt client
       
  2545     // Remove the possibly existing security header & trailer before
       
  2546     // passing the frame up
       
  2547     
       
  2548     const TUint8* frameBeginning = reinterpret_cast<const TUint8*>(aFrame);
       
  2549     const TUint KMacHdrLen( aQosData ? 
       
  2550         sizeof( SQosDataFrameHeader ) + aHtControlLen : 
       
  2551         sizeof( SDataFrameHeader ) );
       
  2552     // subframe header length is non-zero only if the frame is part of an 
       
  2553     // A-MSDU, i.e. if aCopyBuffer is not NULL
       
  2554     const TUint KSubframeHdrLen ( 
       
  2555         aCopyBuffer ? sizeof( SAmsduSubframeHeader ) : 0 );    
       
  2556     // determine subframe length
       
  2557     const TUint KSubframeLen ( 
       
  2558         aSubFrameHeader ? aSubFrameHeader->Length() : 0 );    
       
  2559 
       
  2560     if ( aCopyBuffer )
       
  2561         {
       
  2562         // the frame needs to be copied to the copy buffer, which means
       
  2563         // that it is part of an A-MSDU
       
  2564 
       
  2565         // 1st copy the MAC header
       
  2566         os_memcpy( aCopyBuffer, frameBeginning, KMacHdrLen );
       
  2567                 
       
  2568         // then copy the subframe body following the subframe header
       
  2569         os_memcpy( 
       
  2570             aCopyBuffer 
       
  2571             + KMacHdrLen, 
       
  2572             reinterpret_cast<const TUint8*>(aSubFrameHeader) + KSubframeHdrLen,
       
  2573             KSubframeLen );
       
  2574 
       
  2575         // update to point to the new location
       
  2576         frameBeginning = aCopyBuffer;
       
  2577         }
       
  2578     else
       
  2579         {
       
  2580         // no copying to the copy buffer is required
       
  2581         
       
  2582         if ( aDecryptHeaderLen )
       
  2583             {
       
  2584             // decrypt header exists. Shift the MAC header so that it
       
  2585             // overwrites the decrypt header, thus removing it
       
  2586             
       
  2587             TUint8* dest( const_cast<TUint8*>(frameBeginning) 
       
  2588                           + aDecryptHeaderLen );
       
  2589     
       
  2590             TUint copyBlockSize( aQosData ? 
       
  2591                 sizeof( SQosDataFrameHeader ) + aHtControlLen : 
       
  2592                 sizeof( SDataFrameHeader ) );
       
  2593     
       
  2594             os_memcpy( dest, frameBeginning, copyBlockSize );
       
  2595 
       
  2596             // update to point to the new location
       
  2597             frameBeginning = dest;            
       
  2598             }
       
  2599         }
       
  2600 
       
  2601 #ifndef NDEBUG
       
  2602     OsTracePrint( KRxFrame, (TUint8*)
       
  2603         ("UMAC: WlanDot11Associated::HandleProprietarySnapRxFrame: MPDU header:"), 
       
  2604         *(reinterpret_cast<const Sdot11MacHeader*>(
       
  2605             frameBeginning)));
       
  2606 #endif
       
  2607 
       
  2608     // set the frame length
       
  2609     if ( aCopyBuffer )
       
  2610         {
       
  2611         aBuffer.KeSetLength( KMacHdrLen + KSubframeLen );        
       
  2612         }
       
  2613     else
       
  2614         {
       
  2615         aBuffer.KeSetLength( 
       
  2616             aLength - aDecryptHeaderLen - aDecryptTrailerLen );
       
  2617         }
       
  2618     // set the frame type
       
  2619     aBuffer.FrameType( TDataBuffer::KDot11Frame );
       
  2620     // set the offset to the beginning of the actual frame within the
       
  2621     // Rx buffer
       
  2622     aBuffer.KeSetOffsetToFrameBeginning(
       
  2623         frameBeginning                  // frame beginning
       
  2624         - aBuffer.KeGetBufferStart() ); // buffer beginning
       
  2625     }
       
  2626 
       
  2627 // ---------------------------------------------------------------------------
       
  2628 // 
       
  2629 // ---------------------------------------------------------------------------
       
  2630 //
       
  2631 TBool WlanDot11Associated::ConfigureTxRatePolicies( 
       
  2632     WlanContextImpl& aCtxImpl,
       
  2633     const TTxRatePolicy& aRatePolicy,
       
  2634     const TQueue2RateClass& aQueue2RateClass,
       
  2635     const TInitialMaxTxRate4RateClass& aInitialMaxTxRate4RateClass,
       
  2636     const TTxAutoRatePolicy& aAutoRatePolicy,
       
  2637     const THtMcsPolicy& aHtMcsPolicy )
       
  2638     {
       
  2639     OsTracePrint( KTxRateAdapt, (TUint8*)
       
  2640         ("UMAC: WlanDot11Associated::ConfigureTxRatePolicies"));
       
  2641 
       
  2642     TBool stateChange( EFalse );
       
  2643 
       
  2644     if ( aCtxImpl.ProtocolStackTxDataAllowed() )
       
  2645         {
       
  2646         // store the provided information ...
       
  2647         StoreTxRatePolicyInfo( 
       
  2648             aCtxImpl,
       
  2649             aRatePolicy,
       
  2650             aQueue2RateClass,
       
  2651             aInitialMaxTxRate4RateClass,
       
  2652             aAutoRatePolicy,
       
  2653             aHtMcsPolicy );
       
  2654 
       
  2655         // ... take it into use; and specify that the mgmt client request needs
       
  2656         // to be completed when doing it
       
  2657         stateChange = WlanDot11State::ConfigureTxRatePolicies( aCtxImpl, 
       
  2658                                                                ETrue );
       
  2659         if ( !stateChange )
       
  2660             {
       
  2661             // a fatal error occurred. Simulate MAC Not Responding error
       
  2662             // Note that the Mgmt Client request will be completed when 
       
  2663             // entering the dot11error state
       
  2664             stateChange = DoErrorIndication( 
       
  2665                 aCtxImpl, 
       
  2666                 WHA::KErrorMacNotResponding );            
       
  2667             }
       
  2668         }
       
  2669     else
       
  2670         {
       
  2671         // as user data is not allowed currently, it means that WLAN Mgmt client
       
  2672         // will request us to connect to a new nw shortly and this policy is for
       
  2673         // that new nw. So we shouldn't take the new rate policy into use yet, 
       
  2674         // as we don't know which rates the new nw will be supporting. We just 
       
  2675         // store the provided information for later use
       
  2676         stateChange = WlanDot11State::ConfigureTxRatePolicies( 
       
  2677             aCtxImpl,
       
  2678             aRatePolicy,
       
  2679             aQueue2RateClass,
       
  2680             aInitialMaxTxRate4RateClass,
       
  2681             aAutoRatePolicy,
       
  2682             aHtMcsPolicy );
       
  2683         }
       
  2684         
       
  2685     return stateChange;
       
  2686     }
       
  2687 
       
  2688 // -----------------------------------------------------------------------------
       
  2689 // 
       
  2690 // -----------------------------------------------------------------------------
       
  2691 //
       
  2692 TBool WlanDot11Associated::ConfigurePwrModeMgmtTrafficOverride( 
       
  2693     WlanContextImpl& aCtxImpl,
       
  2694     TBool aStayInPsDespiteUapsdVoiceTraffic,
       
  2695     TBool aStayInPsDespiteUapsdVideoTraffic,
       
  2696     TBool aStayInPsDespiteUapsdBestEffortTraffic, 
       
  2697     TBool aStayInPsDespiteUapsdBackgroundTraffic,
       
  2698     TBool aStayInPsDespiteLegacyVoiceTraffic,
       
  2699     TBool aStayInPsDespiteLegacyVideoTraffic,
       
  2700     TBool aStayInPsDespiteLegacyBestEffortTraffic,
       
  2701     TBool aStayInPsDespiteLegacyBackgroundTraffic )
       
  2702     {
       
  2703     OsTracePrint( KUmacDetails, (TUint8*)
       
  2704         ("UMAC: WlanDot11Associated::ConfigurePwrModeMgmtTrafficOverride"));
       
  2705 
       
  2706     aCtxImpl.ConfigurePwrModeMgmtTrafficOverride( 
       
  2707         aStayInPsDespiteUapsdVoiceTraffic,
       
  2708         aStayInPsDespiteUapsdVideoTraffic,
       
  2709         aStayInPsDespiteUapsdBestEffortTraffic, 
       
  2710         aStayInPsDespiteUapsdBackgroundTraffic,
       
  2711         aStayInPsDespiteLegacyVoiceTraffic,
       
  2712         aStayInPsDespiteLegacyVideoTraffic,
       
  2713         aStayInPsDespiteLegacyBestEffortTraffic,
       
  2714         aStayInPsDespiteLegacyBackgroundTraffic );
       
  2715 
       
  2716     // as we are already connected and aware of the network capabilities, we 
       
  2717     // also need to freeze the dynamic power mode mgmt traffic 
       
  2718     // override/ignoration settings so that they become immediately effective
       
  2719     aCtxImpl.FreezePwrModeMgmtTrafficOverride();
       
  2720 
       
  2721     OnOidComplete( aCtxImpl, KErrNone );
       
  2722 
       
  2723     // signal caller that no state transition occurred
       
  2724     return EFalse;    
       
  2725     }