|
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 |