wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_frame_dot11.cpp
changeset 0 c40eb8fe8501
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:  Class for parsing 802.11 frames
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "core_frame_dot11.h"
       
    20 #include "core_frame_dot11_ie.h"
       
    21 #include "core_tools.h"
       
    22 #include "am_debug.h"
       
    23 
       
    24 const u16_t CORE_DOT11_LENGTH = 24;
       
    25 const u16_t CORE_DOT11_QOS_CONTROL_LENGTH = 2;
       
    26 const u16_t CORE_DOT11_HT_CONTROL_LENGTH = 4;
       
    27 const u16_t CORE_DOT11_FRAME_CONTROL_INDEX = 0;
       
    28 const u16_t CORE_DOT11_DURATION_INDEX = 2;
       
    29 const u16_t CORE_DOT11_ADDRESS1_INDEX = 4;
       
    30 const u16_t CORE_DOT11_ADDRESS2_INDEX = 10;
       
    31 const u16_t CORE_DOT11_ADDRESS3_INDEX = 16;
       
    32 const u16_t CORE_DOT11_NO_IE_OFFSET = 0;
       
    33 const u16_t CORE_DOT11_FRAME_CONTROL_DEFAULT = 0x0000;
       
    34 
       
    35 /** Defining this enables IE iterator related traces. */
       
    36 //#define WLAN_CORE_DEEP_DEBUG 1
       
    37 
       
    38 // ---------------------------------------------------------------------------
       
    39 // ---------------------------------------------------------------------------
       
    40 //
       
    41 core_frame_dot11_c* core_frame_dot11_c::instance(
       
    42     u16_t data_length,
       
    43     const u8_t* data,
       
    44     bool_t is_copied )
       
    45     {
       
    46     DEBUG( "core_frame_dot11_c::instance()" );
       
    47     DEBUG1( "core_frame_dot11_c::instance() - is_copied %u",
       
    48         is_copied );   
       
    49     
       
    50     if( data_length < CORE_DOT11_LENGTH )
       
    51         {
       
    52         DEBUG( "core_frame_dot11_c::instance() - not a valid 802.11 frame, frame is too short" );
       
    53         
       
    54         return NULL;
       
    55         }
       
    56 
       
    57     u8_t* buffer = const_cast<u8_t*>( data );
       
    58     u16_t buffer_length( 0 );
       
    59 
       
    60     if( is_copied )
       
    61         {
       
    62         buffer_length = data_length;
       
    63         buffer = new u8_t[buffer_length];
       
    64         
       
    65         if( !buffer )
       
    66             {
       
    67             DEBUG( "core_frame_dot11_c::instance() - not able to allocate buffer for copying" );
       
    68         
       
    69             return NULL;            
       
    70             }
       
    71 
       
    72         core_tools_c::copy(
       
    73             buffer,
       
    74             data,
       
    75             buffer_length );
       
    76         }
       
    77 
       
    78     core_frame_dot11_c* instance = new core_frame_dot11_c(
       
    79         data_length,
       
    80         buffer,
       
    81         buffer_length );
       
    82     if( !instance )
       
    83         {
       
    84         DEBUG( "core_frame_dot11_c::instance() - unable to create an instance" );
       
    85         if( is_copied )
       
    86             {
       
    87             delete[] buffer;
       
    88             }
       
    89 
       
    90         return NULL;
       
    91         }
       
    92 
       
    93     u16_t required_length( CORE_DOT11_LENGTH );
       
    94     if( instance->is_qos_m )
       
    95         {
       
    96         required_length += CORE_DOT11_QOS_CONTROL_LENGTH;
       
    97 
       
    98         DEBUG( "core_frame_dot11_c::instance() - this frame includes QoS Control field" );
       
    99         }
       
   100 
       
   101     if( instance->is_ht_m )
       
   102         {
       
   103         required_length += CORE_DOT11_HT_CONTROL_LENGTH;
       
   104 
       
   105         DEBUG( "core_frame_dot11_c::instance() - this frame includes HT Control field" );
       
   106         }
       
   107 
       
   108     if( data_length < required_length )
       
   109         {
       
   110         DEBUG( "core_frame_dot11_c::instance() - not a valid 802.11 frame, frame is too short" );
       
   111         delete instance;
       
   112 
       
   113         return NULL;
       
   114         }
       
   115 
       
   116     return instance;
       
   117     }
       
   118 
       
   119 // ---------------------------------------------------------------------------
       
   120 // ---------------------------------------------------------------------------
       
   121 //      
       
   122 core_frame_dot11_c::~core_frame_dot11_c()
       
   123     {
       
   124     DEBUG( "core_frame_dot11_c::~core_frame_dot11_c" );
       
   125 
       
   126     /** 
       
   127      * If maximum frame length has been defined, we have allocated
       
   128      * the frame buffer ourselves.
       
   129      */
       
   130     if( max_data_length_m )
       
   131         {
       
   132         delete[] data_m;
       
   133         }
       
   134     data_m = NULL;
       
   135     current_ie_m = NULL;
       
   136     }
       
   137 
       
   138 // ---------------------------------------------------------------------------
       
   139 // ---------------------------------------------------------------------------
       
   140 //
       
   141 u16_t core_frame_dot11_c::frame_control() const
       
   142     {
       
   143     return core_tools_c::get_u16( data_m, CORE_DOT11_FRAME_CONTROL_INDEX );
       
   144     }
       
   145 
       
   146 // ---------------------------------------------------------------------------
       
   147 // ---------------------------------------------------------------------------
       
   148 //
       
   149 core_frame_dot11_c::core_dot11_type_e core_frame_dot11_c::type() const
       
   150     {
       
   151     return static_cast<core_frame_dot11_c::core_dot11_type_e>(
       
   152         frame_control() & core_dot11_frame_control_type_subtype_mask );
       
   153     }
       
   154 
       
   155 // ---------------------------------------------------------------------------
       
   156 // ---------------------------------------------------------------------------
       
   157 //    
       
   158 u16_t core_frame_dot11_c::duration() const
       
   159     {
       
   160     return core_tools_c::get_u16( data_m, CORE_DOT11_DURATION_INDEX );
       
   161     }
       
   162 
       
   163 // ---------------------------------------------------------------------------
       
   164 // ---------------------------------------------------------------------------
       
   165 //
       
   166 core_mac_address_s core_frame_dot11_c::destination() const
       
   167     {
       
   168     u16_t index( 0 );
       
   169 
       
   170     if( frame_control() & core_dot11_frame_control_to_ds_mask )
       
   171         {
       
   172         if( frame_control() & core_dot11_frame_control_from_ds_mask )
       
   173             {
       
   174             index = CORE_DOT11_ADDRESS3_INDEX;
       
   175             }
       
   176         else
       
   177             {
       
   178             index = CORE_DOT11_ADDRESS3_INDEX;
       
   179             }
       
   180         }
       
   181     else
       
   182         {
       
   183         if( frame_control() & core_dot11_frame_control_from_ds_mask )
       
   184             {
       
   185             index = CORE_DOT11_ADDRESS1_INDEX;
       
   186             }
       
   187         else
       
   188             {
       
   189             index = CORE_DOT11_ADDRESS1_INDEX;
       
   190             }
       
   191         }
       
   192         
       
   193     return mac_address( index );
       
   194     }
       
   195 
       
   196 // ---------------------------------------------------------------------------
       
   197 // ---------------------------------------------------------------------------
       
   198 //
       
   199 core_mac_address_s core_frame_dot11_c::source() const
       
   200     {
       
   201     u16_t index( 0 );
       
   202 
       
   203     if( frame_control() & core_dot11_frame_control_to_ds_mask )
       
   204         {
       
   205         if( frame_control() & core_dot11_frame_control_from_ds_mask )
       
   206             {
       
   207             return ZERO_MAC_ADDR;
       
   208             }
       
   209         else
       
   210             {
       
   211             index = CORE_DOT11_ADDRESS2_INDEX;
       
   212             }
       
   213         }
       
   214     else
       
   215         {
       
   216         if( frame_control() & core_dot11_frame_control_from_ds_mask )
       
   217             {
       
   218             index = CORE_DOT11_ADDRESS3_INDEX;
       
   219             }
       
   220         else
       
   221             {
       
   222             index = CORE_DOT11_ADDRESS2_INDEX;
       
   223             }
       
   224         }
       
   225         
       
   226     return mac_address( index );      
       
   227     }
       
   228 
       
   229 // ---------------------------------------------------------------------------
       
   230 // ---------------------------------------------------------------------------
       
   231 //
       
   232 void core_frame_dot11_c::set_destination( const core_mac_address_s& da )
       
   233     {
       
   234     core_mac_address_s destination = da;
       
   235     core_tools_c::copy(
       
   236         &data_m[CORE_DOT11_ADDRESS2_INDEX],
       
   237         &destination,
       
   238         MAC_ADDR_LEN );
       
   239     }
       
   240 
       
   241 // ---------------------------------------------------------------------------
       
   242 // ---------------------------------------------------------------------------
       
   243 //
       
   244 void core_frame_dot11_c::set_source( const core_mac_address_s& sa )
       
   245     {
       
   246     core_mac_address_s source = sa;
       
   247     core_tools_c::copy(
       
   248         &data_m[CORE_DOT11_ADDRESS1_INDEX],
       
   249         &source,
       
   250         MAC_ADDR_LEN );
       
   251     }
       
   252 
       
   253 // ---------------------------------------------------------------------------
       
   254 // ---------------------------------------------------------------------------
       
   255 //
       
   256 core_mac_address_s core_frame_dot11_c::bssid() const
       
   257     {
       
   258     u16_t index( 0 );
       
   259 
       
   260     if( frame_control() & core_dot11_frame_control_to_ds_mask )
       
   261         {
       
   262         if( frame_control() & core_dot11_frame_control_from_ds_mask )
       
   263             {
       
   264             return ZERO_MAC_ADDR;
       
   265             }
       
   266         else
       
   267             {
       
   268             index = CORE_DOT11_ADDRESS1_INDEX;
       
   269             }
       
   270         }
       
   271     else
       
   272         {
       
   273         if( frame_control() & core_dot11_frame_control_from_ds_mask )
       
   274             {
       
   275             index = CORE_DOT11_ADDRESS2_INDEX;
       
   276             }
       
   277         else
       
   278             {
       
   279             index = CORE_DOT11_ADDRESS3_INDEX;
       
   280             }
       
   281         }
       
   282 
       
   283     return mac_address( index );       
       
   284     }
       
   285 
       
   286 // ---------------------------------------------------------------------------
       
   287 // ---------------------------------------------------------------------------
       
   288 //
       
   289 core_mac_address_s core_frame_dot11_c::mac_address(
       
   290     u16_t index ) const
       
   291     {
       
   292     core_mac_address_s mac( ZERO_MAC_ADDR );
       
   293     
       
   294     core_tools_c::copy(
       
   295         &mac.addr[0],
       
   296         &data_m[index],
       
   297         MAC_ADDR_LEN );
       
   298 
       
   299     return mac;
       
   300     }
       
   301 
       
   302 // ---------------------------------------------------------------------------
       
   303 // ---------------------------------------------------------------------------
       
   304 //
       
   305 u16_t core_frame_dot11_c::data_length() const
       
   306     {
       
   307     return data_length_m;
       
   308     }
       
   309 
       
   310 // ---------------------------------------------------------------------------
       
   311 // ---------------------------------------------------------------------------
       
   312 //   
       
   313 const u8_t* core_frame_dot11_c::data() const
       
   314     {
       
   315     return data_m;
       
   316     }
       
   317 
       
   318 // ---------------------------------------------------------------------------
       
   319 // ---------------------------------------------------------------------------
       
   320 //
       
   321 u16_t core_frame_dot11_c::payload_data_length() const
       
   322     {
       
   323     u16_t length( data_length_m - CORE_DOT11_LENGTH );
       
   324     if( is_qos_m )
       
   325         {
       
   326         length -= CORE_DOT11_QOS_CONTROL_LENGTH;
       
   327         }
       
   328     if( is_ht_m )
       
   329         {
       
   330         length -= CORE_DOT11_HT_CONTROL_LENGTH;
       
   331         }
       
   332 
       
   333     return length;       
       
   334     }
       
   335 
       
   336 // ---------------------------------------------------------------------------
       
   337 // ---------------------------------------------------------------------------
       
   338 //
       
   339 const u8_t* core_frame_dot11_c::payload_data() const
       
   340     {
       
   341     u8_t* data( data_m + CORE_DOT11_LENGTH );
       
   342     if( is_qos_m )
       
   343         {
       
   344         data += CORE_DOT11_QOS_CONTROL_LENGTH;
       
   345         }
       
   346     if( is_ht_m )
       
   347         {
       
   348         data += CORE_DOT11_HT_CONTROL_LENGTH;
       
   349         }
       
   350 
       
   351     return data;       
       
   352     }
       
   353 
       
   354 // ---------------------------------------------------------------------------
       
   355 // ---------------------------------------------------------------------------
       
   356 //  
       
   357 core_frame_dot11_ie_c* core_frame_dot11_c::first_ie()
       
   358     {
       
   359     u16_t offset = first_ie_offset();
       
   360     if( !offset )
       
   361         {
       
   362         DEBUG( "core_frame_dot11_c::instance() - the frame has no IEs" );
       
   363         return NULL;
       
   364         }
       
   365 
       
   366     current_ie_m = payload_data() + offset;
       
   367     current_ie_max_length_m = payload_data_length() - offset;
       
   368 
       
   369     return next_ie();
       
   370     }
       
   371 
       
   372 // ---------------------------------------------------------------------------
       
   373 // ---------------------------------------------------------------------------
       
   374 //
       
   375 core_frame_dot11_ie_c* core_frame_dot11_c::next_ie()
       
   376     {
       
   377 #ifdef WLAN_CORE_DEEP_DEBUG
       
   378     DEBUG1( "core_frame_dot11_c::next_ie() - real frame length: %u",
       
   379         data_length_m );  
       
   380     DEBUG1( "core_frame_dot11_c::next_ie() - data_m is at %08X",
       
   381         data_m );
       
   382     DEBUG1( "core_frame_dot11_c::next_ie() - current_ie_m is at %08X",
       
   383         current_ie_m );
       
   384     DEBUG1( "core_frame_dot11_c::next_ie() - data end is at %08X",
       
   385         data_m + data_length_m );
       
   386     DEBUG1( "core_frame_dot11_c::next_ie() - maximum IE length is %u",
       
   387         current_ie_max_length_m );
       
   388 #endif // WLAN_CORE_DEEP_DEBUG
       
   389 
       
   390     if( !current_ie_max_length_m )
       
   391         {
       
   392         return NULL;
       
   393         }
       
   394 
       
   395     core_frame_dot11_ie_c* instance =
       
   396         core_frame_dot11_ie_c::instance( current_ie_max_length_m, current_ie_m );
       
   397     if( !instance )
       
   398         {
       
   399         DEBUG( "core_frame_dot11_c::instance() - unable to create IE parser" );
       
   400         
       
   401         return NULL;
       
   402         }
       
   403 
       
   404     current_ie_m += instance->data_length();
       
   405 
       
   406 #ifdef WLAN_CORE_DEEP_DEBUG
       
   407     DEBUG1( "core_frame_dot11_c::next_ie() - IE ID is %u",
       
   408         instance->element_id() );
       
   409     DEBUG1( "core_frame_dot11_c::next_ie() - IE length is %u",
       
   410         instance->length() );
       
   411     DEBUG1( "core_frame_dot11_c::next_ie() - IE data length is %u",
       
   412         instance->data_length() );  
       
   413 #endif // WLAN_CORE_DEEP_DEBUG
       
   414 
       
   415     ASSERT( current_ie_m <= data_m + data_length_m );
       
   416     current_ie_max_length_m -= instance->data_length();
       
   417 
       
   418     return instance;
       
   419     }
       
   420 
       
   421 // ---------------------------------------------------------------------------
       
   422 // ---------------------------------------------------------------------------
       
   423 //
       
   424 void core_frame_dot11_c::append_ie(
       
   425     const core_frame_dot11_ie_c* ie )
       
   426     {
       
   427     if( !ie )
       
   428         {
       
   429         return;
       
   430         }
       
   431 
       
   432 #ifdef WLAN_CORE_DEEP_DEBUG  
       
   433     DEBUG1( "core_frame_dot11_c::append_ie() - real frame length: %u",
       
   434         data_length_m );
       
   435     DEBUG1( "core_frame_dot11_c::append_ie() - maximum frame length: %u",
       
   436         max_data_length_m );
       
   437     DEBUG1( "core_frame_dot11_c::append_ie() - ie length: %u",
       
   438         ie->data_length() );
       
   439 #endif // WLAN_CORE_DEEP_DEBUG
       
   440 
       
   441     if( data_length_m + ie->data_length() <= max_data_length_m )
       
   442         {
       
   443         core_tools_c::copy(
       
   444             &data_m[data_length_m],
       
   445             ie->data(),
       
   446             ie->data_length() );
       
   447         data_length_m += ie->data_length();
       
   448         }
       
   449     }
       
   450 
       
   451 // ---------------------------------------------------------------------------
       
   452 // ---------------------------------------------------------------------------
       
   453 //
       
   454 u16_t core_frame_dot11_c::first_ie_offset() const
       
   455     {
       
   456     /**
       
   457      * By default the frame doesn't have any IEs.
       
   458      */   
       
   459     return CORE_DOT11_NO_IE_OFFSET;
       
   460     }
       
   461 
       
   462 // ---------------------------------------------------------------------------
       
   463 // ---------------------------------------------------------------------------
       
   464 //  
       
   465 u16_t core_frame_dot11_c::first_fixed_element_offset() const
       
   466     {
       
   467     u16_t offset = CORE_DOT11_LENGTH;
       
   468 
       
   469     if( is_qos_m )
       
   470         {
       
   471         offset += CORE_DOT11_QOS_CONTROL_LENGTH;
       
   472         }
       
   473     if( is_ht_m )
       
   474         {
       
   475         offset += CORE_DOT11_HT_CONTROL_LENGTH;
       
   476         }
       
   477 
       
   478     return offset;       
       
   479     }
       
   480 
       
   481 // ---------------------------------------------------------------------------
       
   482 // ---------------------------------------------------------------------------
       
   483 //
       
   484 void core_frame_dot11_c::generate(
       
   485     u8_t type,
       
   486     u16_t duration,
       
   487     const core_mac_address_s& destination,
       
   488     const core_mac_address_s& source,
       
   489     const core_mac_address_s& bssid,
       
   490     u16_t sequence_control )
       
   491     {
       
   492     ASSERT( !data_length_m );
       
   493     ASSERT( max_data_length_m );   
       
   494 
       
   495     // Frame Control
       
   496     u16_t temp16( CORE_DOT11_FRAME_CONTROL_DEFAULT );
       
   497     temp16 |= type;
       
   498 
       
   499     // Data frames sent by a station must have the ToDS bit set.
       
   500     if( ( type & core_dot11_frame_control_type_mask ) == core_dot11_frame_control_type_data )
       
   501         {
       
   502         temp16 |= core_dot11_frame_control_to_ds_mask;
       
   503         }
       
   504 
       
   505     core_tools_c::copy(
       
   506         &data_m[data_length_m],
       
   507         reinterpret_cast<u8_t*>(&temp16),
       
   508         sizeof( temp16 ) );
       
   509     data_length_m += sizeof( temp16 );    
       
   510 
       
   511     // Duration
       
   512     temp16 = duration;
       
   513     core_tools_c::copy(
       
   514         &data_m[data_length_m],
       
   515         reinterpret_cast<u8_t*>(&temp16),
       
   516         sizeof( temp16 ) );
       
   517     data_length_m += sizeof( temp16 );    
       
   518     
       
   519     // BSSID
       
   520     core_tools_c::copy(
       
   521         &data_m[data_length_m],
       
   522         &bssid.addr[0],
       
   523         MAC_ADDR_LEN );
       
   524     data_length_m += MAC_ADDR_LEN;    
       
   525     
       
   526     // Source MAC
       
   527     core_tools_c::copy(
       
   528         &data_m[data_length_m],
       
   529         &source.addr[0],
       
   530         MAC_ADDR_LEN );
       
   531     data_length_m += MAC_ADDR_LEN;    
       
   532 
       
   533     // Destination MAC
       
   534     core_tools_c::copy(
       
   535         &data_m[data_length_m],
       
   536         &destination.addr[0],
       
   537         MAC_ADDR_LEN );
       
   538     data_length_m += MAC_ADDR_LEN;        
       
   539 
       
   540     // Sequence Control
       
   541     temp16 = sequence_control;
       
   542     core_tools_c::copy(
       
   543         &data_m[data_length_m],
       
   544         reinterpret_cast<u8_t*>(&temp16),
       
   545         sizeof( temp16 ) );
       
   546     data_length_m += sizeof( temp16 );
       
   547     }
       
   548 
       
   549 // ---------------------------------------------------------------------------
       
   550 // ---------------------------------------------------------------------------
       
   551 //
       
   552 core_frame_dot11_c::core_frame_dot11_c(
       
   553     u16_t data_length,
       
   554     const u8_t* data,
       
   555     u16_t max_data_length ) :
       
   556     data_length_m( data_length ),
       
   557     data_m( NULL ),
       
   558     max_data_length_m( max_data_length ),
       
   559     is_qos_m( false_t ),
       
   560     is_ht_m( false_t ),
       
   561     current_ie_m( NULL ),
       
   562     current_ie_max_length_m( 0 )
       
   563     {
       
   564     DEBUG( "core_frame_dot11_c::core_frame_dot11_c" );
       
   565 
       
   566     /**
       
   567      * The reason the const is discarded is that the same pointer
       
   568      * is used when we have allocated the frame buffer ourselves.
       
   569      */
       
   570     data_m = const_cast<u8_t*>( data );
       
   571 
       
   572     core_dot11_frame_control_type_e type_field =
       
   573         static_cast<core_frame_dot11_c::core_dot11_frame_control_type_e>(
       
   574             frame_control() & core_dot11_frame_control_type_mask );
       
   575 
       
   576     if( type_field == core_dot11_frame_control_type_data &&
       
   577         frame_control() & core_dot11_frame_control_subtype_qos_mask )
       
   578         {
       
   579         is_qos_m = true_t;
       
   580         }
       
   581 
       
   582     if( ( type_field == core_dot11_frame_control_type_management ||
       
   583           is_qos_m ) &&
       
   584         frame_control() & core_dot11_frame_control_order_mask )
       
   585         {
       
   586         is_ht_m = true_t;
       
   587         }
       
   588     }