wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_sub_operation_create_ts.cpp
changeset 0 c40eb8fe8501
child 6 e0f767079796
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 creating a traffic stream.
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 12 %
       
    20 */
       
    21 
       
    22 #include "core_sub_operation_create_ts.h"
       
    23 #include "core_server.h"
       
    24 #include "core_frame_wmm_ie.h"
       
    25 #include "core_frame_wmm_ie_tspec.h"
       
    26 #include "core_frame_action_wmm.h"
       
    27 #include "core_tools.h"
       
    28 #include "core_tools_parser.h"
       
    29 #include "am_debug.h"
       
    30 
       
    31 const u32_t CORE_AP_RESP_WAITING_TIME = 1000000;
       
    32 
       
    33 // ======== MEMBER FUNCTIONS ========
       
    34 
       
    35 // ---------------------------------------------------------------------------
       
    36 // ---------------------------------------------------------------------------
       
    37 //
       
    38 core_sub_operation_create_ts_c::core_sub_operation_create_ts_c(
       
    39     u32_t request_id,
       
    40     core_server_c* server,
       
    41     abs_core_driverif_c* drivers,
       
    42     abs_core_server_callback_c* adaptation,
       
    43     const core_ap_data_c& ap_data,
       
    44     u8_t tid,
       
    45     u8_t user_priority,
       
    46     core_traffic_stream_params_s& tspec,
       
    47     core_traffic_stream_status_e& stream_status ) :
       
    48     core_operation_base_c( core_operation_unspecified, request_id, server, drivers, adaptation,
       
    49         core_base_flag_none ),
       
    50     current_ap_m( ap_data ),
       
    51     tid_m( tid ),
       
    52     user_priority_m( user_priority ),
       
    53     tspec_m( tspec ),
       
    54     stream_status_m( stream_status )
       
    55     {
       
    56     DEBUG( "core_sub_operation_create_ts_c::core_sub_operation_create_ts_c()" );
       
    57 
       
    58     stream_status_m = core_traffic_stream_status_inactive_other;
       
    59     }
       
    60 
       
    61 // ---------------------------------------------------------------------------
       
    62 // ---------------------------------------------------------------------------
       
    63 //
       
    64 core_sub_operation_create_ts_c::~core_sub_operation_create_ts_c()
       
    65     {
       
    66     DEBUG( "core_sub_operation_create_ts_c::~core_sub_operation_create_ts_c()" );
       
    67 
       
    68     server_m->unregister_frame_handler( this );
       
    69     }
       
    70 
       
    71 // ---------------------------------------------------------------------------
       
    72 // ---------------------------------------------------------------------------
       
    73 //
       
    74 core_error_e core_sub_operation_create_ts_c::next_state()
       
    75     {
       
    76     DEBUG( "core_sub_operation_create_ts_c::next_state()" );
       
    77     
       
    78     switch ( operation_state_m )
       
    79         {
       
    80         case core_state_init:
       
    81             {
       
    82             bool_t is_uapsd( true_t );
       
    83             if ( !current_ap_m.is_uapsd_supported() ||
       
    84                  !server_m->get_core_settings().is_uapsd_enable_for_access_class(
       
    85                     core_tools_c::convert_user_priority_to_ac( user_priority_m ) ) )
       
    86                 {
       
    87                 is_uapsd = false_t;
       
    88                 }
       
    89             DEBUG1( "core_sub_operation_create_ts_c::next_state() - U-APSD %u", is_uapsd );
       
    90 
       
    91             core_frame_wmm_ie_tspec_c* tspec_ie = core_frame_wmm_ie_tspec_c::instance(
       
    92                 tid_m,
       
    93                 user_priority_m,
       
    94                 is_uapsd,
       
    95                 tspec_m.is_periodic_traffic,
       
    96                 tspec_m.direction,
       
    97                 tspec_m.nominal_msdu_size,
       
    98                 tspec_m.maximum_msdu_size,
       
    99                 tspec_m.minimum_service_interval,
       
   100                 tspec_m.maximum_service_interval,
       
   101                 tspec_m.inactivity_interval,
       
   102                 tspec_m.suspension_interval,
       
   103                 tspec_m.service_start_time,
       
   104                 tspec_m.minimum_data_rate,
       
   105                 tspec_m.mean_data_rate,
       
   106                 tspec_m.peak_data_rate,
       
   107                 tspec_m.maximum_burst_size,
       
   108                 tspec_m.delay_bound,
       
   109                 tspec_m.minimum_phy_rate,
       
   110                 tspec_m.surplus_bandwidth_allowance,
       
   111                 tspec_m.medium_time );
       
   112             if ( !tspec_ie )
       
   113                 {
       
   114                 DEBUG( "core_sub_operation_create_ts_c::next_state() - unable to allocate a WMM TSPEC IE" );
       
   115                 return core_error_no_memory;
       
   116                 }
       
   117 
       
   118             DEBUG( "core_sub_operation_create_ts_c::next_state() - TSPEC IE:" );
       
   119             DEBUG_BUFFER( tspec_ie->data_length(), tspec_ie->data() );
       
   120 
       
   121             const core_mac_address_s dest(
       
   122                 current_ap_m.bssid() );
       
   123             const core_mac_address_s src(
       
   124                 server_m->own_mac_addr() );
       
   125 
       
   126             core_frame_action_wmm_c* frame = core_frame_action_wmm_c::instance(
       
   127                 0,                  // Duration
       
   128                 dest,               // Destination
       
   129                 src,                // Source
       
   130                 dest,               // BSSID
       
   131                 0,                  // Sequence Control
       
   132                 core_frame_action_wmm_c::core_dot11_action_wmm_type_addts_req, // Action Type
       
   133                 255,                // Dialog Token
       
   134                 core_frame_action_wmm_c::core_dot11_action_wmm_status_admission_accepted, // Status
       
   135                 tspec_ie );
       
   136 
       
   137             delete tspec_ie;
       
   138             tspec_ie = NULL;        
       
   139 
       
   140             if ( !frame )
       
   141                 {
       
   142                 DEBUG( "core_sub_operation_create_ts_c::next_state() - unable to allocate an action frame" );
       
   143                 return core_error_no_memory;
       
   144                 }
       
   145 
       
   146             /**
       
   147              * Handle the WPX-specific features in traffic stream creation.
       
   148              */
       
   149             server_m->get_wpx_adaptation_instance().handle_ts_create_request(
       
   150                 current_ap_m,
       
   151                 frame,
       
   152                 tid_m,
       
   153                 tspec_m );
       
   154 
       
   155             DEBUG( "core_sub_operation_create_ts_c::next_state() - ADDTS REQ:" );
       
   156             DEBUG_BUFFER( frame->data_length(), frame->data() );
       
   157 
       
   158             operation_state_m = core_state_request_sent;            
       
   159 
       
   160             server_m->register_frame_handler( this );
       
   161             
       
   162             server_m->send_management_frame(
       
   163                 core_frame_type_dot11,
       
   164                 frame->data_length(),
       
   165                 frame->data(),
       
   166                 dest );
       
   167 
       
   168             delete frame;
       
   169             frame = NULL;
       
   170 
       
   171             /**
       
   172              * Schedule a timeout if no response is received.
       
   173              */
       
   174             server_m->schedule_operation_timer(
       
   175                 CORE_AP_RESP_WAITING_TIME ); 
       
   176 
       
   177             break;
       
   178             }
       
   179         case core_state_request_sent:
       
   180             {
       
   181             server_m->unregister_frame_handler( this );
       
   182 
       
   183             DEBUG( "core_sub_operation_create_ts_c::next_state() - timer has expired, no response from AP received" );
       
   184 
       
   185             return core_error_general;
       
   186             }
       
   187         case core_state_invalid_parameters:
       
   188             {
       
   189             DEBUG( "core_sub_operation_create_ts_c::next_state() - AP has downgraded our parameters, retrying" );
       
   190 
       
   191             return goto_state( core_state_init );
       
   192             }
       
   193         case core_state_failure:
       
   194             {
       
   195             server_m->unregister_frame_handler( this );
       
   196 
       
   197             DEBUG( "core_sub_operation_create_ts_c::next_state() - AP has rejected our traffic stream request" );
       
   198 
       
   199             return core_error_general;
       
   200             }
       
   201         case core_state_success:
       
   202             {
       
   203             server_m->unregister_frame_handler( this );
       
   204 
       
   205             DEBUG( "core_sub_operation_create_ts_c::next_state() - traffic stream created successfully" );
       
   206 
       
   207             DEBUG_RATES( "core_sub_operation_create_ts_c::next_state() - nominal PHY rate: ",
       
   208                 tspec_m.nominal_phy_rate );
       
   209             DEBUG_RATES( "core_sub_operation_create_ts_c::next_state() - override tx rates: ",
       
   210                 tspec_m.override_rates );
       
   211 
       
   212             return core_error_ok;
       
   213             }
       
   214         default:
       
   215             {
       
   216             ASSERT( false_t );
       
   217             }
       
   218         }
       
   219 
       
   220     return core_error_request_pending;
       
   221     }
       
   222 
       
   223 // ---------------------------------------------------------------------------
       
   224 // ---------------------------------------------------------------------------
       
   225 //    
       
   226 bool_t core_sub_operation_create_ts_c::receive_frame(
       
   227     const core_frame_dot11_c* frame,
       
   228     u8_t /* rcpi */ )
       
   229     {
       
   230     DEBUG( "core_sub_operation_create_ts_c::receive_frame()" );
       
   231 
       
   232     if ( frame->type() != core_frame_dot11_c::core_dot11_type_action )
       
   233         {
       
   234         DEBUG( "core_sub_operation_create_ts_c::receive_frame() - not an action frame" );
       
   235         return false_t;
       
   236         }
       
   237 
       
   238     core_frame_action_c* action = core_frame_action_c::instance(
       
   239         *frame );
       
   240     if ( action )
       
   241         {
       
   242         DEBUG( "core_sub_operation_create_ts_c::receive_frame() - 802.11 action frame found" );
       
   243         DEBUG1( "core_sub_operation_create_ts_c::receive_frame() - 802.11 action category: 0x%02X",
       
   244             action->category() );
       
   245         if ( action->category() == core_frame_action_c::core_dot11_action_category_wmm_qos )
       
   246             {
       
   247             core_frame_action_wmm_c* wmm_action = core_frame_action_wmm_c::instance( *action );
       
   248             if ( wmm_action )
       
   249                 {
       
   250                 DEBUG( "core_sub_operation_create_ts_c::receive_frame() - 802.11 WMM action frame found" );
       
   251                 DEBUG1( "core_sub_operation_create_ts_c::receive_frame() - 802.11 WMM action type: 0x%02X",
       
   252                     wmm_action->action_type() );
       
   253                 DEBUG1( "core_sub_operation_create_ts_c::receive_frame() - 802.11 WMM action dialog token: 0x%02X",
       
   254                     wmm_action->dialog_token() );
       
   255                 DEBUG1( "core_sub_operation_create_ts_c::receive_frame() - 802.11 WMM action status: 0x%02X",
       
   256                     wmm_action->status() );
       
   257 
       
   258                 /**
       
   259                  * Get traffic stream parameters from the response.
       
   260                  */
       
   261                 bool_t ret = core_tools_parser_c::get_wmm_traffic_stream_params(
       
   262                     *wmm_action,
       
   263                     tid_m,
       
   264                     tspec_m );
       
   265                 if ( !ret )
       
   266                     {
       
   267                     DEBUG1( "core_sub_operation_create_ts_c::receive_frame() - TSPEC with TID %u not found, ignoring frame",
       
   268                         tid_m );
       
   269 
       
   270                     delete wmm_action;
       
   271                     wmm_action = NULL;
       
   272 
       
   273                     delete action;
       
   274                     action = NULL;
       
   275 
       
   276                     return true_t;
       
   277                     }
       
   278 
       
   279                 server_m->get_wpx_adaptation_instance().get_wpx_traffic_stream_params(
       
   280                     wmm_action,
       
   281                     tid_m,
       
   282                     tspec_m );
       
   283 
       
   284                 server_m->cancel_operation_timer();
       
   285 
       
   286                 if ( wmm_action->status() == core_frame_action_wmm_c::core_dot11_action_wmm_status_admission_accepted )
       
   287                     {
       
   288                     stream_status_m = core_traffic_stream_status_active;
       
   289 
       
   290                     server_m->get_wpx_adaptation_instance().handle_ts_create_success(
       
   291                         wmm_action,
       
   292                         tid_m,
       
   293                         user_priority_m );
       
   294 
       
   295                     asynch_goto( core_state_success, CORE_TIMER_IMMEDIATELY );
       
   296                     }
       
   297                 else if ( wmm_action->status() == core_frame_action_wmm_c::core_dot11_action_wmm_status_invalid_parameters )
       
   298                     {
       
   299                     asynch_goto( core_state_invalid_parameters, CORE_TIMER_IMMEDIATELY );
       
   300                     }
       
   301                 else
       
   302                     {
       
   303                     stream_status_m = server_m->get_wpx_adaptation_instance().get_wpx_traffic_stream_status(
       
   304                         wmm_action->status() );
       
   305 
       
   306                     asynch_goto( core_state_failure, CORE_TIMER_IMMEDIATELY );
       
   307                     }
       
   308 
       
   309                 delete wmm_action;
       
   310                 }
       
   311             }
       
   312 
       
   313         delete action;
       
   314         action = NULL;
       
   315         }
       
   316         
       
   317     return true_t;
       
   318     }
       
   319