wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_handle_frame.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:  Statemachine for handling a frame received from drivers
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "core_operation_handle_frame.h"
       
    20 #include "core_operation_ibss_merge.h"
       
    21 #include "core_operation_handle_delete_ts.h"
       
    22 #include "core_operation_update_power_mode.h"
       
    23 #include "core_operation_handle_measurement_request.h"
       
    24 #include "core_operation_handle_neighbor_response.h"
       
    25 #include "core_frame_radio_measurement_action.h"
       
    26 #include "core_frame_action_wmm.h"
       
    27 #include "core_frame_wmm_ie_tspec.h"
       
    28 #include "core_frame_action_rm.h"
       
    29 #include "core_frame_action_nr.h"
       
    30 #include "core_frame_tim_ie.h"
       
    31 #include "core_frame_dot11.h"
       
    32 #include "core_server.h"
       
    33 #include "core_tools.h"
       
    34 #include "am_debug.h"
       
    35 
       
    36 // ======== MEMBER FUNCTIONS ========
       
    37 
       
    38 // ---------------------------------------------------------------------------
       
    39 // ---------------------------------------------------------------------------
       
    40 //
       
    41 core_operation_handle_frame_c::core_operation_handle_frame_c(
       
    42     u32_t request_id,
       
    43     core_server_c* server,
       
    44     abs_core_driverif_c* drivers,
       
    45     abs_core_server_callback_c* adaptation,
       
    46     core_frame_type_e frame_type,
       
    47     u16_t data_length,
       
    48     const u8_t* data ) :
       
    49     core_operation_base_c( core_operation_handle_frame, request_id, server, drivers, adaptation, 
       
    50         core_base_flag_drivers_needed | core_base_flag_connection_needed ),
       
    51     type_m( frame_type ),
       
    52     data_length_m( data_length ),
       
    53     data_m( NULL ),
       
    54     frame_m( NULL )
       
    55     {
       
    56     DEBUG( "core_operation_handle_frame_c::core_operation_handle_frame_c()" );
       
    57 
       
    58     data_m = new u8_t[data_length_m];
       
    59     if ( data_m )
       
    60         {
       
    61         core_tools_c::copy(
       
    62             data_m,
       
    63             data,
       
    64             data_length );
       
    65         }    
       
    66     }
       
    67 
       
    68 // ---------------------------------------------------------------------------
       
    69 // ---------------------------------------------------------------------------
       
    70 //
       
    71 core_operation_handle_frame_c::~core_operation_handle_frame_c()
       
    72     {
       
    73     DEBUG( "core_operation_handle_frame_c::~core_operation_handle_frame_c()" );
       
    74 
       
    75     delete frame_m;
       
    76     frame_m = NULL;
       
    77     delete[] data_m;
       
    78     data_m = NULL;
       
    79     }
       
    80     
       
    81 // ---------------------------------------------------------------------------
       
    82 // ---------------------------------------------------------------------------
       
    83 //
       
    84 core_error_e core_operation_handle_frame_c::next_state()
       
    85     {
       
    86     DEBUG( "core_operation_handle_frame_c::next_state()" );
       
    87     
       
    88     switch ( operation_state_m )
       
    89         {
       
    90         case core_state_init:
       
    91             {
       
    92             if ( !data_m )
       
    93                 {
       
    94                 DEBUG( "core_operation_handle_frame_c::next_state() - no frame, aborting" );
       
    95                 failure_reason_m = core_error_no_memory;
       
    96 
       
    97                 return cancel();
       
    98                 }            
       
    99 
       
   100             if ( !server_m->get_core_settings().is_connected() )
       
   101                 {
       
   102                 DEBUG( "core_operation_handle_frame_c::next_state() - not connected, discarding frame" );
       
   103                 
       
   104                 return core_error_ok;
       
   105                 }
       
   106 
       
   107             switch ( type_m )
       
   108                 {
       
   109                 case core_frame_type_dot11:
       
   110                     {
       
   111                     DEBUG( "core_operation_handle_frame_c::next_state() - core_frame_type_dot11" );
       
   112                     frame_m = core_frame_dot11_c::instance(
       
   113                         data_length_m,
       
   114                         data_m,
       
   115                         false_t );
       
   116                     if ( !frame_m )
       
   117                         {
       
   118                         DEBUG( "core_operation_handle_frame_c::next_state() - unable to create parser" );
       
   119                         failure_reason_m = core_error_general;
       
   120 
       
   121                         return cancel();                        
       
   122                         }
       
   123 
       
   124 #ifdef _DEBUG                        
       
   125                     DEBUG1( "core_operation_handle_frame_c::next_state() - frame control: %04X",
       
   126                         frame_m->frame_control() );        
       
   127                     if ( frame_m->frame_control() & core_frame_dot11_c::core_dot11_frame_control_to_ds_mask )
       
   128                         {
       
   129                         DEBUG( "core_operation_handle_frame_c::next_state() - frame control ToDS: enabled" );
       
   130                         }
       
   131                     else
       
   132                         {
       
   133                         DEBUG( "core_operation_handle_frame_c::next_state() - frame control ToDS: disabled" );
       
   134                         }             
       
   135                     if ( frame_m->frame_control() & core_frame_dot11_c::core_dot11_frame_control_from_ds_mask )
       
   136                         {
       
   137                         DEBUG( "core_operation_handle_frame_c::next_state() - frame control FromDS: enabled" );
       
   138                         }
       
   139                     else
       
   140                         {
       
   141                         DEBUG( "core_operation_handle_frame_c::next_state() - frame control FromDS: disabled" );
       
   142                         }            
       
   143                     DEBUG1( "core_operation_handle_frame_c::next_state() - duration: %04X",
       
   144                         frame_m->duration() );
       
   145         
       
   146                     core_mac_address_s mac( ZERO_MAC_ADDR );
       
   147                     mac = frame_m->destination();            
       
   148                     DEBUG6( "core_operation_handle_frame_c::next_state() - destination: %02X:%02X:%02X:%02X:%02X:%02X",
       
   149                         mac.addr[0], mac.addr[1], mac.addr[2],
       
   150                         mac.addr[3], mac.addr[4], mac.addr[5] );
       
   151             
       
   152                     mac = frame_m->source();            
       
   153                     DEBUG6( "core_operation_handle_frame_c::next_state() - source: %02X:%02X:%02X:%02X:%02X:%02X",
       
   154                         mac.addr[0], mac.addr[1], mac.addr[2],
       
   155                         mac.addr[3], mac.addr[4], mac.addr[5] );
       
   156 
       
   157                     mac = frame_m->bssid();            
       
   158                     DEBUG6( "core_operation_handle_frame_c::next_state() - bssid: %02X:%02X:%02X:%02X:%02X:%02X",
       
   159                         mac.addr[0], mac.addr[1], mac.addr[2],
       
   160                         mac.addr[3], mac.addr[4], mac.addr[5] );                    
       
   161 #endif // _DEBUG
       
   162 
       
   163                     if ( frame_m->type() == core_frame_dot11_c::core_dot11_type_beacon &&
       
   164                          server_m->get_core_settings().is_connected() )
       
   165                         {
       
   166                         if ( server_m->get_connection_data()->iap_data().operating_mode() == core_operating_mode_ibss )
       
   167                             {
       
   168                             operation_state_m = core_state_done;
       
   169 
       
   170                             DEBUG( "core_operation_handle_frame_c::next_state() - beacon received in IBSS mode" );
       
   171 
       
   172                             /**
       
   173                              * Beacons received in IBSS mode are an indication that a merge
       
   174                              * is needed.
       
   175                              */
       
   176                             core_operation_base_c* operation = new core_operation_ibss_merge_c(
       
   177                                 request_id_m,
       
   178                                 server_m,
       
   179                                 drivers_m,
       
   180                                 adaptation_m,
       
   181                                 frame_m );
       
   182 
       
   183                             return run_sub_operation( operation );
       
   184                             }
       
   185                         else
       
   186                             {
       
   187                             DEBUG( "core_operation_handle_frame_c::next_state() - beacon received in infrastructure mode" );
       
   188 
       
   189                             /**
       
   190                              * Beacons received in infrastructure mode happen after an association.
       
   191                              *
       
   192                              * They are used to update the current AP data since beacons contain
       
   193                              * fields not present in probe responses.
       
   194                              */
       
   195                             if ( server_m->get_connection_data() &&
       
   196                                  server_m->get_connection_data()->current_ap_data() &&
       
   197                                  server_m->get_connection_data()->current_ap_data()->bssid() == frame_m->bssid() )
       
   198                                 {
       
   199                                 core_frame_beacon_c* beacon = core_frame_beacon_c::instance(
       
   200                                     *frame_m );
       
   201                                 if ( beacon )
       
   202                                     {
       
   203                                     for( core_frame_dot11_ie_c* ie = beacon->first_ie(); ie; ie = beacon->next_ie() )
       
   204                                         {
       
   205                                         if ( ie->element_id() == core_frame_dot11_ie_c::core_frame_dot11_ie_element_id_tim )
       
   206                                             {
       
   207                                             core_frame_tim_ie_c* tim_ie = core_frame_tim_ie_c::instance( *ie );
       
   208                                             if ( tim_ie &&
       
   209                                                  tim_ie->dtim_period() )
       
   210                                                 {
       
   211                                                 DEBUG1( "core_operation_handle_frame_c::next_state() - updating AP DTIM period to %u",
       
   212                                                     tim_ie->dtim_period() );
       
   213 
       
   214                                                 server_m->get_connection_data()->current_ap_data()->set_dtim_period(
       
   215                                                     tim_ie->dtim_period() );
       
   216 
       
   217                                                 /**
       
   218                                                  * Schedule a power mode update since we may have to adjust the wakeup interval
       
   219                                                  * if DTIM skipping is used.
       
   220                                                  * 
       
   221                                                  * We should avoid changing power mode if DHCP timer is active.
       
   222                                                  */
       
   223                                                 if( !server_m->is_dhcp_timer_active() )
       
   224                                                     {
       
   225                                                     DEBUG( "core_operation_handle_frame_c::next_state() - scheduling a power save update" );
       
   226 
       
   227                                                     core_operation_base_c* operation = new core_operation_update_power_mode_c(
       
   228                                                         request_id_m,
       
   229                                                         server_m,
       
   230                                                         drivers_m,
       
   231                                                         adaptation_m );
       
   232     
       
   233                                                     server_m->queue_int_operation( operation );
       
   234                                                     }
       
   235                                                 else
       
   236                                                     {
       
   237                                                     DEBUG( "core_operation_handle_frame_c::next_state() - DHCP timer active, no power mode update" );
       
   238                                                     }
       
   239                                                 }
       
   240 
       
   241                                             delete tim_ie;
       
   242                                             tim_ie = NULL;
       
   243                                             }
       
   244 
       
   245                                         delete ie;
       
   246                                         ie = NULL;
       
   247                                         }
       
   248 
       
   249                                     delete beacon;
       
   250                                     beacon = NULL;
       
   251                                     }
       
   252                                 }
       
   253                             }
       
   254                         }
       
   255                     else if ( frame_m->type() == core_frame_dot11_c::core_dot11_type_action )
       
   256                         {
       
   257                         core_frame_action_c* action = core_frame_action_c::instance(
       
   258                             *frame_m );
       
   259                         if ( action )
       
   260                             {
       
   261                             DEBUG( "core_operation_handle_frame_c::next_state() - 802.11 action frame found" );
       
   262                             DEBUG1( "core_operation_handle_frame_c::next_state() - 802.11 action category: 0x%02X",
       
   263                                 action->category() );
       
   264                             if ( action->category() == core_frame_action_c::core_dot11_action_category_wmm_qos )
       
   265                                 {
       
   266                                 core_frame_action_wmm_c* wmm_action = core_frame_action_wmm_c::instance( *action );
       
   267                                 if ( wmm_action )
       
   268                                     {
       
   269                                     DEBUG( "core_operation_handle_frame_c::next_state() - 802.11 WMM action frame found" );
       
   270                                     DEBUG1( "core_operation_handle_frame_c::next_state() - 802.11 WMM action type: 0x%02X",
       
   271                                         wmm_action->action_type() );
       
   272                                     DEBUG1( "core_operation_handle_frame_c::next_state() - 802.11 WMM action dialog token: 0x%02X",
       
   273                                         wmm_action->dialog_token() );
       
   274                                     DEBUG1( "core_operation_handle_frame_c::next_state() - 802.11 WMM action status: 0x%02X",
       
   275                                         wmm_action->status() );
       
   276 
       
   277                                     if ( wmm_action->action_type() == core_frame_action_wmm_c::core_dot11_action_wmm_type_delts )
       
   278                                         {
       
   279                                         for( core_frame_dot11_ie_c* ie = wmm_action->first_ie(); ie; ie = wmm_action->next_ie() )
       
   280                                             {
       
   281                                             DEBUG1( "core_operation_handle_frame_c::next_state() - 802.11 WMM action IE ID: 0x%02X",
       
   282                                                 ie->element_id() );
       
   283                                             DEBUG1( "core_operation_handle_frame_c::next_state() - 802.11 WMM action IE length: 0x%02X",
       
   284                                                 ie->length() );
       
   285 
       
   286                                             if ( ie->element_id() == core_frame_dot11_ie_c::core_frame_dot11_ie_element_id_wmm_tspec )
       
   287                                                 {
       
   288                                                 core_frame_wmm_ie_tspec_c* tspec_ie = core_frame_wmm_ie_tspec_c::instance( *ie );
       
   289                                                 if ( tspec_ie )
       
   290                                                     {
       
   291                                                     core_operation_base_c* operation = new core_operation_handle_delete_ts_c(
       
   292                                                         request_id_m,
       
   293                                                         server_m,
       
   294                                                         drivers_m,
       
   295                                                         adaptation_m,   
       
   296                                                         tspec_ie->tid() );
       
   297 
       
   298                                                     server_m->queue_int_operation( operation );
       
   299 
       
   300                                                     delete tspec_ie;
       
   301                                                     tspec_ie = NULL;
       
   302                                                     }
       
   303                                                 }
       
   304 
       
   305                                             delete ie;
       
   306                                             ie = NULL;
       
   307                                             }
       
   308                                         }
       
   309 
       
   310                                     delete wmm_action;
       
   311                                     wmm_action = NULL;
       
   312                                     }
       
   313                                 }
       
   314                             else if ( action->category() == core_frame_action_c::core_dot11_action_category_rm )
       
   315                                 {
       
   316                                 core_frame_radio_measurement_action_c* radio_measurement_action = core_frame_radio_measurement_action_c::instance( *action, true_t );
       
   317                                 if ( radio_measurement_action )
       
   318                                     {
       
   319                                     DEBUG( "core_operation_handle_frame_c::next_state() - 802.11 RM action frame found" );
       
   320                                     DEBUG1( "core_operation_handle_frame_c::next_state() - 802.11 RM action type: 0x%02X",
       
   321                                         radio_measurement_action->action_type() );
       
   322 
       
   323                                     if ( radio_measurement_action->action_type() == core_frame_radio_measurement_action_c::core_dot11_action_rm_type_meas_req )
       
   324                                         {
       
   325                                         DEBUG( "core_operation_handle_frame_c::next_state() - Measurement Request received -> create operation to handle it" );
       
   326 
       
   327                                         // copy received frame to a new memory location, rm_action will have the ownership of the new data
       
   328                                         core_frame_action_rm_c* rm_action = core_frame_action_rm_c::instance( *action, true_t );
       
   329                                         if ( rm_action )
       
   330                                             {
       
   331                                             // operation will deallocate rm_action when finished
       
   332                                             core_operation_base_c* operation = new core_operation_handle_measurement_request_c(
       
   333                                                 request_id_m,
       
   334                                                 server_m,
       
   335                                                 drivers_m,
       
   336                                                 adaptation_m,   
       
   337                                                 rm_action );
       
   338     
       
   339                                             server_m->queue_int_operation( operation );
       
   340                                             }
       
   341                                         }
       
   342                                     else if ( radio_measurement_action->action_type() == core_frame_radio_measurement_action_c::core_dot11_action_rm_type_neighbor_resp )
       
   343                                         {
       
   344                                         DEBUG( "core_operation_handle_frame_c::next_state() - Neighbor Report Response received -> create operation to handle it" );
       
   345 
       
   346                                         // copy received frame to a new memory location, nr_action will have the ownership of the new data
       
   347                                         core_frame_action_nr_c* nr_action = core_frame_action_nr_c::instance( *action, true_t );
       
   348                                         if ( nr_action )
       
   349                                             {
       
   350                                             // operation will deallocate nr_action when finished
       
   351                                             core_operation_base_c* operation = new core_operation_handle_neighbor_response_c(
       
   352                                                 request_id_m,
       
   353                                                 server_m,
       
   354                                                 drivers_m,
       
   355                                                 adaptation_m,   
       
   356                                                 nr_action );
       
   357     
       
   358                                             server_m->queue_int_operation( operation );
       
   359                                             }
       
   360                                         }
       
   361                                     else
       
   362                                         {
       
   363                                         DEBUG( "core_operation_handle_frame_c::next_state() - 802.11 RM action type not supported, ignoring..." );
       
   364                                         }
       
   365 
       
   366                                     delete radio_measurement_action;
       
   367                                     radio_measurement_action = NULL;
       
   368                                     }
       
   369                                 }
       
   370 
       
   371                             delete action;
       
   372                             action = NULL;
       
   373                             }
       
   374                         }
       
   375                     else
       
   376                         {
       
   377                         DEBUG( "core_operation_handle_frame_c::next_state() - unknown frame, discarding" );
       
   378                         }
       
   379 
       
   380                     return core_error_ok;
       
   381                     }
       
   382                 case core_frame_type_snap:
       
   383                     {
       
   384                     DEBUG( "core_operation_handle_frame_c::next_state() - core_frame_type_snap, discarding" );
       
   385                     
       
   386                     return core_error_ok;
       
   387                     }
       
   388                 default:
       
   389                     {
       
   390                     DEBUG( "core_operation_handle_frame_c::next_state() - unknown frame type, discarding" );
       
   391                     
       
   392                     return core_error_ok;
       
   393                     }
       
   394                 }            
       
   395             }
       
   396         case core_state_done:
       
   397             {
       
   398             DEBUG( "core_operation_handle_frame_c::next_state() - frame processing done" );
       
   399             
       
   400             return core_error_ok;
       
   401             }            
       
   402         default:
       
   403             {
       
   404             ASSERT( false_t );
       
   405             }
       
   406         }
       
   407 
       
   408     return core_error_request_pending;
       
   409     }