wlan_bearer/wlanengine/wlan_common/wlanengine_common_3.1/src/core_operation_delete_ts.cpp
changeset 0 c40eb8fe8501
child 21 af3fb27c7511
equal deleted inserted replaced
-1:000000000000 0:c40eb8fe8501
       
     1 /*
       
     2 * Copyright (c) 2006-2010 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 deleting a traffic stream.
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 8 %
       
    20 */
       
    21 
       
    22 #include "core_operation_delete_ts.h"
       
    23 #include "core_traffic_stream.h"
       
    24 #include "core_frame_wmm_ie_tspec.h"
       
    25 #include "core_frame_action_wmm.h"
       
    26 #include "core_server.h"
       
    27 #include "core_tools.h"
       
    28 #include "core_traffic_stream_list_iter.h"
       
    29 #include "core_virtual_traffic_stream_list_iter.h"
       
    30 #include "am_debug.h"
       
    31 
       
    32 // ======== MEMBER FUNCTIONS ========
       
    33 
       
    34 // ---------------------------------------------------------------------------
       
    35 // ---------------------------------------------------------------------------
       
    36 //
       
    37 core_operation_delete_ts_c::core_operation_delete_ts_c(
       
    38     u32_t request_id,
       
    39     core_server_c* server,
       
    40     abs_core_driverif_c* drivers,
       
    41     abs_core_server_callback_c* adaptation,
       
    42     u32_t stream_id ) :
       
    43     core_operation_base_c( core_operation_delete_ts, request_id, server, drivers, adaptation,
       
    44         core_base_flag_none ),
       
    45     id_m( stream_id )
       
    46     {
       
    47     DEBUG( "core_operation_delete_ts_c::core_operation_delete_ts_c()" );
       
    48     }
       
    49 
       
    50 // ---------------------------------------------------------------------------
       
    51 // ---------------------------------------------------------------------------
       
    52 //
       
    53 core_operation_delete_ts_c::~core_operation_delete_ts_c()
       
    54     {
       
    55     DEBUG( "core_operation_delete_ts_c::~core_operation_delete_ts_c()" );
       
    56     }
       
    57 
       
    58 // ---------------------------------------------------------------------------
       
    59 // ---------------------------------------------------------------------------
       
    60 //
       
    61 core_error_e core_operation_delete_ts_c::next_state()
       
    62     {
       
    63     DEBUG( "core_operation_delete_ts_c::next_state()" );
       
    64 
       
    65     switch ( operation_state_m )
       
    66         {              
       
    67         case core_state_init:
       
    68             {
       
    69             operation_state_m = core_base_state_parameters_set;
       
    70             
       
    71             if( !server_m->get_core_settings().is_connected() )
       
    72                 {
       
    73                 DEBUG( "core_operation_delete_ts_c::next_state() - not connected, nothing to do" );
       
    74 
       
    75                 return core_error_general;
       
    76                 }
       
    77 
       
    78             core_traffic_stream_list_c& ts_list(
       
    79                 server_m->get_connection_data()->traffic_stream_list() );
       
    80             core_virtual_traffic_stream_list_c& virtual_ts_list(
       
    81                 server_m->get_connection_data()->virtual_traffic_stream_list() );
       
    82             core_traffic_stream_list_iter_c ts_iter( ts_list );
       
    83             core_virtual_traffic_stream_list_iter_c virtual_ts_iter( virtual_ts_list );
       
    84 
       
    85             DEBUG( "core_operation_delete_ts_c::next_state() - current traffic streams:" );
       
    86             virtual_ts_list.print_contents();
       
    87             ts_list.print_contents();
       
    88             
       
    89             /**
       
    90              * Find the virtual traffic stream to be deleted.
       
    91              */
       
    92             core_virtual_traffic_stream_c* virtual_stream = NULL;
       
    93             core_virtual_traffic_stream_c* virtual_iter = virtual_ts_iter.first();
       
    94             while( virtual_iter )
       
    95                 {
       
    96                 if( virtual_iter->id() == id_m )
       
    97                     {
       
    98                     virtual_stream = virtual_iter;
       
    99                     virtual_iter = NULL;
       
   100                     }
       
   101                 else
       
   102                     {
       
   103                     virtual_iter = virtual_ts_iter.next();
       
   104                     }
       
   105                 }
       
   106 
       
   107             if( !virtual_stream )
       
   108                 {
       
   109                 DEBUG1( "core_operation_delete_ts_c::next_state() - no virtual traffic stream with ID %u found",
       
   110                     id_m );
       
   111 
       
   112                 return core_error_not_found;
       
   113                 }
       
   114 
       
   115             u8_t tid = virtual_stream->tid();
       
   116             
       
   117             DEBUG3( "core_operation_delete_ts_c::next_state() - virtual traffic stream with ID %u found, TID: %u, UP: %u",
       
   118                 id_m, tid, virtual_stream->user_priority() );
       
   119 
       
   120             /**
       
   121              * Delete the virtual traffic stream.
       
   122              */
       
   123             virtual_ts_iter.remove();
       
   124             
       
   125             /**
       
   126              * Locate the actual traffic stream based on the TID.
       
   127              */
       
   128             core_traffic_stream_c* stream = NULL;            
       
   129             core_traffic_stream_c* iter = ts_iter.first();
       
   130             while( iter )
       
   131                 {
       
   132                 if( iter->tid() == tid )
       
   133                     {
       
   134                     stream = iter;
       
   135 
       
   136                     iter = NULL;
       
   137                     }
       
   138                 else
       
   139                     {
       
   140                     iter = ts_iter.next();
       
   141                     }
       
   142                 }
       
   143 
       
   144             if( !stream )
       
   145                 {
       
   146                 DEBUG1( "core_operation_delete_ts_c::next_state() - no traffic stream with TID %u found",
       
   147                     id_m );
       
   148 
       
   149                 /**
       
   150                  * This is not an error since the virtual traffic streams can
       
   151                  * exist eventhough the AP doesn't require admission control.
       
   152                  */
       
   153 
       
   154                 return core_error_ok;
       
   155                 }
       
   156 
       
   157             stream->dec_reference_count();
       
   158             if( stream->reference_count() )
       
   159                 {
       
   160                 DEBUG1( "core_operation_delete_ts_c::next_state() - traffic stream reference count is %u, not deleting",
       
   161                     stream->reference_count() );
       
   162                 
       
   163                 /**
       
   164                  * If there are still other virtual traffic streams referencing
       
   165                  * this traffic stream, do not delete it. 
       
   166                  */
       
   167 
       
   168                 return core_error_ok;
       
   169                 }
       
   170 
       
   171             u8_t user_priority = stream->user_priority();
       
   172             core_traffic_stream_direction_e direction = stream->direction();
       
   173             bool_t is_uapsd( true_t );
       
   174             if( !server_m->get_connection_data()->current_ap_data()->is_uapsd_supported() ||
       
   175                 !server_m->get_core_settings().is_uapsd_enable_for_access_class(
       
   176                     core_tools_c::convert_user_priority_to_ac( user_priority ) ) )
       
   177                 {
       
   178                 is_uapsd = false_t;
       
   179                 }
       
   180             DEBUG1( "core_operation_delete_ts_c::next_state() - U-APSD %u",
       
   181                 is_uapsd );
       
   182 
       
   183             core_frame_wmm_ie_tspec_c* tspec_ie = core_frame_wmm_ie_tspec_c::instance(
       
   184                 stream->tid(),
       
   185                 user_priority,
       
   186                 is_uapsd,
       
   187                 stream->is_periodic_traffic(),
       
   188                 stream->direction(),
       
   189                 stream->nominal_msdu_size(),
       
   190                 stream->maximum_msdu_size(),
       
   191                 stream->minimum_service_interval(),
       
   192                 stream->maximum_service_interval(),
       
   193                 stream->inactivity_interval(),
       
   194                 stream->suspension_interval(),
       
   195                 stream->service_start_time(),
       
   196                 stream->minimum_data_rate(),
       
   197                 stream->mean_data_rate(),
       
   198                 stream->peak_data_rate(),
       
   199                 stream->maximum_burst_size(),
       
   200                 stream->delay_bound(),
       
   201                 stream->minimum_phy_rate(),
       
   202                 stream->surplus_bandwidth_allowance(),
       
   203                 stream->medium_time() );
       
   204             if( !tspec_ie )
       
   205                 {
       
   206                 DEBUG( "core_operation_delete_ts_c::next_state() - unable to allocate a WMM TSPEC IE" );
       
   207                 return core_error_no_memory;
       
   208                 }
       
   209 
       
   210             DEBUG( "core_operation_delete_ts_c::next_state() - TSPEC IE:" );
       
   211             DEBUG_BUFFER( tspec_ie->data_length(), tspec_ie->data() );
       
   212 
       
   213             const core_mac_address_s dest(
       
   214                 server_m->get_connection_data()->current_ap_data()->bssid() );
       
   215             const core_mac_address_s src(
       
   216                 server_m->own_mac_addr() );
       
   217 
       
   218             core_frame_action_wmm_c* frame = core_frame_action_wmm_c::instance(
       
   219                 0,                  // Duration
       
   220                 dest,               // Destination
       
   221                 src,                // Source
       
   222                 dest,               // BSSID
       
   223                 0,                  // Sequence Control
       
   224                 core_frame_action_wmm_c::core_dot11_action_wmm_type_delts, // Action Type
       
   225                 0,                  // Dialog Token
       
   226                 core_frame_action_wmm_c::core_dot11_action_wmm_status_admission_accepted, // Status Code
       
   227                 tspec_ie );
       
   228 
       
   229             delete tspec_ie;
       
   230             tspec_ie = NULL;
       
   231 
       
   232             if( !frame )
       
   233                 {
       
   234                 DEBUG( "core_operation_delete_ts_c::next_state() - unable to allocate an action frame" );
       
   235                 return core_error_no_memory;
       
   236                 }
       
   237 
       
   238             DEBUG( "core_operation_delete_ts_c::next_state() - DELTS REQ:" );
       
   239             DEBUG_BUFFER( frame->data_length(), frame->data() );
       
   240 
       
   241             server_m->send_management_frame(
       
   242                 core_frame_type_dot11,
       
   243                 frame->data_length(),
       
   244                 frame->data(),
       
   245                 dest );
       
   246 
       
   247             delete frame;
       
   248             frame = NULL;
       
   249 
       
   250             DEBUG( "core_operation_delete_ts_c::next_state() - DELTS request sent" );
       
   251 
       
   252             server_m->get_wpx_adaptation_instance().handle_ts_delete(
       
   253                 tid, user_priority );
       
   254 
       
   255             /**
       
   256              * If there no more manual virtual traffic streams in this AC,
       
   257              * switch the traffic mode back to automatic.
       
   258              */
       
   259             if( virtual_ts_list.traffic_mode_by_ac( stream->access_class() ) == core_access_class_traffic_mode_automatic )
       
   260                 {
       
   261                 server_m->get_connection_data()->set_ac_traffic_mode(
       
   262                     stream->access_class(),
       
   263                     core_access_class_traffic_mode_automatic );
       
   264 
       
   265                 DEBUG( "core_operation_delete_ts_c::next_state() - traffic mode set to automatic for this AC, notifying clients" );
       
   266 
       
   267                 u8_t buf[5];
       
   268                 buf[0] = static_cast<u8_t>( 
       
   269                     stream->access_class() );
       
   270                 buf[1] = static_cast<u8_t>(
       
   271                     core_access_class_traffic_mode_automatic );
       
   272                 adaptation_m->notify(
       
   273                     core_notification_ac_traffic_mode_changed,
       
   274                     sizeof( buf ),
       
   275                     buf );                
       
   276                 }
       
   277 
       
   278             /**
       
   279              * Delete the actual traffic stream.
       
   280              */
       
   281             ts_iter.remove();
       
   282 
       
   283             if( direction == core_traffic_stream_direction_uplink ||
       
   284                 direction == core_traffic_stream_direction_bidirectional )
       
   285                 {
       
   286                 server_m->get_connection_data()->set_ac_traffic_status(
       
   287                     core_tools_c::convert_user_priority_to_ac( user_priority ),
       
   288                     core_access_class_traffic_status_not_admitted );
       
   289 
       
   290                 /**
       
   291                  * Send an indication to notify clients that this access class
       
   292                  * is no longer admitted.
       
   293                  * 
       
   294                  * We don't have to the check the ACM bits since the traffic
       
   295                  * stream wouldn't exist if the AP didn't require admission
       
   296                  * control.  
       
   297                  */
       
   298                 DEBUG( "core_operation_delete_ts_c::next_state() - traffic no longer admitted on this AC, notifying clients" );
       
   299 
       
   300                 u8_t buf[5];
       
   301                 buf[0] = static_cast<u8_t>( 
       
   302                     core_tools_c::convert_user_priority_to_ac( user_priority ) );
       
   303                 buf[1] = static_cast<u8_t>(
       
   304                     core_access_class_traffic_status_not_admitted );
       
   305                 adaptation_m->notify(
       
   306                     core_notification_ac_traffic_status_changed,
       
   307                     sizeof( buf ),
       
   308                     buf );
       
   309 
       
   310                 /**
       
   311                  * Reset TX queue parameters back to default values.
       
   312                  */
       
   313                 DEBUG( "core_operation_delete_ts_c::next_state() - resetting tx queue parameters" ); 
       
   314 
       
   315                 drivers_m->set_tx_queue_parameters(
       
   316                     request_id_m,
       
   317                     core_tools_c::convert_user_priority_to_ac( user_priority ),
       
   318                     0,
       
   319                     server_m->get_device_settings().max_tx_msdu_life_time );
       
   320                 }
       
   321             else
       
   322                 {
       
   323                 /**
       
   324                  * Since TX queue parameters apply only to uplink, there is nothing
       
   325                  * more to do on downlink streams.
       
   326                  */
       
   327                 return core_error_ok; 
       
   328                 }
       
   329 
       
   330             break;
       
   331             }
       
   332         case core_base_state_parameters_set:
       
   333             {
       
   334             DEBUG( "core_operation_delete_ts_c::next_state() - tx queue parameters reset" );
       
   335             
       
   336             return core_error_ok;
       
   337             }
       
   338         default:
       
   339             {
       
   340             ASSERT( false_t );
       
   341             }
       
   342         }
       
   343 
       
   344     return core_error_request_pending;
       
   345     }