|
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: Main class for core server |
|
15 * |
|
16 */ |
|
17 |
|
18 /* |
|
19 * %version: 89 % |
|
20 */ |
|
21 |
|
22 #include "core_server.h" |
|
23 #include "abs_core_server_callback.h" |
|
24 #include "abs_core_driverif.h" |
|
25 #include "abs_core_timer.h" |
|
26 #include "abs_core_frame_handler.h" |
|
27 #include "abs_core_event_handler.h" |
|
28 #include "core_timer_factory.h" |
|
29 #include "core_operation_connect.h" |
|
30 #include "core_operation_update_device_settings.h" |
|
31 #include "core_operation_scan.h" |
|
32 #include "core_operation_get_available_iaps.h" |
|
33 #include "core_operation_release.h" |
|
34 #include "core_operation_unload_drivers.h" |
|
35 #include "core_operation_check_rcpi.h" |
|
36 #include "core_operation_handle_frame.h" |
|
37 #include "core_operation_null.h" |
|
38 #include "core_operation_get_rcpi.h" |
|
39 #include "core_operation_configure_multicast_group.h" |
|
40 #include "core_operation_update_power_mode.h" |
|
41 #include "core_operation_update_rxtx_parameters.h" |
|
42 #include "core_operation_get_statistics.h" |
|
43 #include "core_operation_set_uapsd_settings.h" |
|
44 #include "core_operation_set_power_save_settings.h" |
|
45 #include "core_operation_protected_setup.h" |
|
46 #include "core_operation_create_ts.h" |
|
47 #include "core_operation_delete_ts.h" |
|
48 #include "core_operation_power_save_test.h" |
|
49 #include "core_operation_set_arp_filter.h" |
|
50 #include "core_operation_directed_roam.h" |
|
51 #include "core_frame_ethernet.h" |
|
52 #include "core_connection_data.h" |
|
53 #include "core_eapol_handler.h" |
|
54 #include "core_frame_dot11.h" |
|
55 #include "core_frame_echo_test.h" |
|
56 #include "am_debug.h" |
|
57 #include "core_callback.h" |
|
58 #include "core_tools.h" |
|
59 #include "core_tools_parser.h" |
|
60 #include "core_wpx_adaptation_factory.h" |
|
61 #include "core_traffic_stream_list_iter.h" |
|
62 |
|
63 // ======== MEMBER FUNCTIONS ======== |
|
64 |
|
65 // --------------------------------------------------------------------------- |
|
66 // --------------------------------------------------------------------------- |
|
67 // |
|
68 core_server_c::core_server_c( |
|
69 abs_core_server_callback_c& callback, |
|
70 abs_core_driverif_c& drivers, |
|
71 const core_device_settings_s& settings, |
|
72 const core_mac_address_s& mac_address, |
|
73 u32_t features ) : |
|
74 callback_m( callback ), |
|
75 drivers_m( drivers ), |
|
76 device_settings_m( settings ), |
|
77 queue_m( ), |
|
78 queue_timer_m( NULL ), |
|
79 driver_unload_timer_m( NULL ), |
|
80 core_settings_m( features ), |
|
81 connection_data_m( NULL ), |
|
82 own_mac_addr_m( mac_address ), |
|
83 eapol_handler_m( NULL ), |
|
84 eapol_m( NULL ), |
|
85 cm_timer_m( ), |
|
86 roam_timer_m( NULL ), |
|
87 operation_timer_m( NULL ), |
|
88 driver_dhcp_timer_m( NULL ), |
|
89 frame_handler_m( NULL ), |
|
90 event_handler_m( NULL ), |
|
91 scan_list_m( ), |
|
92 wpx_adaptation_m( NULL ) |
|
93 { |
|
94 DEBUG( "core_server_c::core_server_c()" ); |
|
95 queue_m.clear(); |
|
96 } |
|
97 |
|
98 // --------------------------------------------------------------------------- |
|
99 // --------------------------------------------------------------------------- |
|
100 // |
|
101 core_server_c::~core_server_c() |
|
102 { |
|
103 DEBUG( "core_server_c::~core_server_c()" ); |
|
104 |
|
105 queue_m.clear(); |
|
106 delete connection_data_m; |
|
107 |
|
108 if ( queue_timer_m ) |
|
109 { |
|
110 queue_timer_m->stop(); |
|
111 core_timer_factory_c::destroy_timer( queue_timer_m ); |
|
112 queue_timer_m = NULL; |
|
113 } |
|
114 if ( driver_unload_timer_m ) |
|
115 { |
|
116 driver_unload_timer_m->stop(); |
|
117 core_timer_factory_c::destroy_timer( driver_unload_timer_m ); |
|
118 driver_unload_timer_m = NULL; |
|
119 } |
|
120 if ( roam_timer_m ) |
|
121 { |
|
122 roam_timer_m->stop(); |
|
123 core_timer_factory_c::destroy_timer( roam_timer_m ); |
|
124 roam_timer_m = NULL; |
|
125 } |
|
126 if ( operation_timer_m ) |
|
127 { |
|
128 operation_timer_m->stop(); |
|
129 core_timer_factory_c::destroy_timer( operation_timer_m ); |
|
130 operation_timer_m = NULL; |
|
131 } |
|
132 if ( driver_dhcp_timer_m ) |
|
133 { |
|
134 driver_dhcp_timer_m->stop(); |
|
135 core_timer_factory_c::destroy_timer( driver_dhcp_timer_m ); |
|
136 driver_dhcp_timer_m = NULL; |
|
137 } |
|
138 if ( eapol_m ) |
|
139 { |
|
140 eapol_m->shutdown(); |
|
141 delete eapol_m; |
|
142 } |
|
143 delete wpx_adaptation_m; |
|
144 delete eapol_handler_m; |
|
145 frame_handler_m = NULL; |
|
146 event_handler_m = NULL; |
|
147 } |
|
148 |
|
149 // --------------------------------------------------------------------------- |
|
150 // --------------------------------------------------------------------------- |
|
151 // |
|
152 core_error_e core_server_c::init() |
|
153 { |
|
154 DEBUG( "core_server_c::init()" ); |
|
155 |
|
156 drivers_m.init( this ); |
|
157 |
|
158 core_callback_c* queue_timer_callback = |
|
159 new core_callback_c( &(core_server_c::queue_timer_expired), this ); |
|
160 if( !queue_timer_callback ) |
|
161 { |
|
162 DEBUG("ERROR creating callback object"); |
|
163 return core_error_no_memory; |
|
164 } |
|
165 queue_timer_m = core_timer_factory_c::create_timer( queue_timer_callback ); |
|
166 if( !queue_timer_m ) |
|
167 { |
|
168 DEBUG( "ERROR creating timer" ); |
|
169 delete queue_timer_callback; |
|
170 return core_error_no_memory; |
|
171 } |
|
172 |
|
173 core_callback_c* unload_timer_callback = |
|
174 new core_callback_c( &(core_server_c::unload_timer_expired), this ); |
|
175 if( !unload_timer_callback ) |
|
176 { |
|
177 DEBUG("ERROR creating callback object"); |
|
178 return core_error_no_memory; |
|
179 } |
|
180 driver_unload_timer_m = core_timer_factory_c::create_timer( unload_timer_callback ); |
|
181 if( !driver_unload_timer_m ) |
|
182 { |
|
183 DEBUG( "ERROR creating timer" ); |
|
184 delete unload_timer_callback; |
|
185 return core_error_no_memory; |
|
186 } |
|
187 |
|
188 core_callback_c* roam_timer_callback = |
|
189 new core_callback_c( &(core_server_c::roam_timer_expired), this ); |
|
190 if( !roam_timer_callback ) |
|
191 { |
|
192 DEBUG("ERROR creating callback object"); |
|
193 return core_error_no_memory; |
|
194 } |
|
195 roam_timer_m = core_timer_factory_c::create_timer( roam_timer_callback ); |
|
196 if( !roam_timer_m ) |
|
197 { |
|
198 DEBUG( "ERROR creating timer" ); |
|
199 delete roam_timer_callback; |
|
200 return core_error_no_memory; |
|
201 } |
|
202 |
|
203 core_callback_c* operation_timer_callback = |
|
204 new core_callback_c( &(core_server_c::operation_timer_expired), this ); |
|
205 if( !operation_timer_callback ) |
|
206 { |
|
207 DEBUG("ERROR creating callback object"); |
|
208 return core_error_no_memory; |
|
209 } |
|
210 operation_timer_m = core_timer_factory_c::create_timer( operation_timer_callback ); |
|
211 if( !operation_timer_m ) |
|
212 { |
|
213 DEBUG( "ERROR creating timer" ); |
|
214 delete operation_timer_callback; |
|
215 return core_error_no_memory; |
|
216 } |
|
217 |
|
218 core_callback_c* dhcp_timer_callback = |
|
219 new core_callback_c( &(core_server_c::dhcp_timer_expired), this ); |
|
220 if( !dhcp_timer_callback ) |
|
221 { |
|
222 DEBUG("ERROR creating callback object"); |
|
223 return core_error_no_memory; |
|
224 } |
|
225 driver_dhcp_timer_m = core_timer_factory_c::create_timer( dhcp_timer_callback ); |
|
226 if( !driver_dhcp_timer_m ) |
|
227 { |
|
228 DEBUG( "ERROR creating timer" ); |
|
229 delete dhcp_timer_callback; |
|
230 return core_error_no_memory; |
|
231 } |
|
232 |
|
233 wpx_adaptation_m = core_wpx_adaptation_factory_c::instance( |
|
234 this, &drivers_m, &callback_m ); |
|
235 if ( !wpx_adaptation_m ) |
|
236 { |
|
237 DEBUG("ERROR creating WPX adaptation"); |
|
238 return core_error_no_memory; |
|
239 } |
|
240 |
|
241 eapol_handler_m = new core_eapol_handler_c( |
|
242 this, &drivers_m, &callback_m ); |
|
243 if ( !eapol_handler_m ) |
|
244 { |
|
245 DEBUG("ERROR creating eapol handler"); |
|
246 return core_error_no_memory; |
|
247 } |
|
248 |
|
249 core_settings_m.set_rcpi_boundaries( |
|
250 device_settings_m.rcpi_trigger, |
|
251 device_settings_m.rcpi_trigger + device_settings_m.rcpi_difference ); |
|
252 |
|
253 return core_error_ok; |
|
254 } |
|
255 |
|
256 // --------------------------------------------------------------------------- |
|
257 // --------------------------------------------------------------------------- |
|
258 // |
|
259 core_device_settings_s& core_server_c::get_device_settings() |
|
260 { |
|
261 return device_settings_m; |
|
262 } |
|
263 |
|
264 // --------------------------------------------------------------------------- |
|
265 // --------------------------------------------------------------------------- |
|
266 // |
|
267 core_settings_c& core_server_c::get_core_settings() |
|
268 { |
|
269 return core_settings_m; |
|
270 } |
|
271 |
|
272 // --------------------------------------------------------------------------- |
|
273 // --------------------------------------------------------------------------- |
|
274 // |
|
275 core_connection_data_c* core_server_c::get_connection_data() |
|
276 { |
|
277 return connection_data_m; |
|
278 } |
|
279 |
|
280 // --------------------------------------------------------------------------- |
|
281 // --------------------------------------------------------------------------- |
|
282 // |
|
283 core_wlan_eapol_interface_c& core_server_c::get_eapol_instance() |
|
284 { |
|
285 return *eapol_m; |
|
286 } |
|
287 |
|
288 // --------------------------------------------------------------------------- |
|
289 // --------------------------------------------------------------------------- |
|
290 // |
|
291 void core_server_c::set_eapol_handler( |
|
292 abs_wlan_eapol_callback_interface_c* handler ) |
|
293 { |
|
294 eapol_handler_m->set_eapol_handler( handler ); |
|
295 } |
|
296 |
|
297 // --------------------------------------------------------------------------- |
|
298 // --------------------------------------------------------------------------- |
|
299 // |
|
300 core_mac_address_s& core_server_c::own_mac_addr() |
|
301 { |
|
302 return own_mac_addr_m; |
|
303 } |
|
304 |
|
305 // --------------------------------------------------------------------------- |
|
306 // --------------------------------------------------------------------------- |
|
307 // |
|
308 core_error_e core_server_c::queue_int_operation( |
|
309 core_operation_base_c* operation ) |
|
310 { |
|
311 DEBUG( "core_server_c::queue_int_operation()" ); |
|
312 |
|
313 if ( !operation ) |
|
314 { |
|
315 DEBUG( "core_server_c::queue_int_operation() - no operation" ); |
|
316 |
|
317 return core_error_no_memory; |
|
318 } |
|
319 else if ( operation->is_flags( core_operation_base_c::core_base_flag_only_one_instance ) && |
|
320 is_operation_in_queue_with_type( operation->operation_type() ) ) |
|
321 { |
|
322 DEBUG( "core_server_c::queue_int_operation() - only one instance allowed in the operation queue" ); |
|
323 |
|
324 delete operation; |
|
325 operation = NULL; |
|
326 |
|
327 return core_error_already_exists; |
|
328 } |
|
329 else |
|
330 { |
|
331 core_error_e ret = queue_m.append( operation ); |
|
332 if ( ret != core_error_ok ) |
|
333 { |
|
334 DEBUG1( "core_server_c::queue_int_operation() - unable to queue the request (%u)", |
|
335 ret ); |
|
336 |
|
337 delete operation; |
|
338 operation = NULL; |
|
339 |
|
340 return ret; |
|
341 } |
|
342 } |
|
343 |
|
344 return core_error_ok; |
|
345 } |
|
346 |
|
347 // --------------------------------------------------------------------------- |
|
348 // --------------------------------------------------------------------------- |
|
349 // |
|
350 core_error_e core_server_c::queue_int_operation_and_run_next( |
|
351 core_operation_base_c* operation ) |
|
352 { |
|
353 DEBUG( "core_server_c::queue_int_operation_and_run_next()" ); |
|
354 |
|
355 core_error_e ret = queue_int_operation( operation ); |
|
356 if ( ret != core_error_ok ) |
|
357 { |
|
358 return ret; |
|
359 } |
|
360 |
|
361 schedule_operation(); |
|
362 |
|
363 return core_error_ok; |
|
364 } |
|
365 |
|
366 // --------------------------------------------------------------------------- |
|
367 // --------------------------------------------------------------------------- |
|
368 // |
|
369 core_error_e core_server_c::init_connection_data( |
|
370 const core_iap_data_s& iap_data, |
|
371 const core_device_settings_s& device_settings ) |
|
372 { |
|
373 connection_data_m = new core_connection_data_c( iap_data, device_settings ); |
|
374 |
|
375 if ( !connection_data_m ) |
|
376 { |
|
377 return core_error_no_memory; |
|
378 } |
|
379 |
|
380 return core_error_ok; |
|
381 } |
|
382 |
|
383 // --------------------------------------------------------------------------- |
|
384 // --------------------------------------------------------------------------- |
|
385 // |
|
386 void core_server_c::clear_connection_data() |
|
387 { |
|
388 DEBUG( "core_server_c::clear_connection_data()" ); |
|
389 |
|
390 delete connection_data_m; |
|
391 connection_data_m = NULL; |
|
392 } |
|
393 |
|
394 // --------------------------------------------------------------------------- |
|
395 // --------------------------------------------------------------------------- |
|
396 // |
|
397 void core_server_c::schedule_roam_timer( |
|
398 u32_t delay ) |
|
399 { |
|
400 DEBUG1( "core_server_c::schedule_roam_timer() - delay %u", |
|
401 delay ); |
|
402 |
|
403 ASSERT( !roam_timer_m->is_active() ); |
|
404 |
|
405 roam_timer_m->start( |
|
406 delay ); |
|
407 } |
|
408 |
|
409 // --------------------------------------------------------------------------- |
|
410 // --------------------------------------------------------------------------- |
|
411 // |
|
412 void core_server_c::cancel_roam_timer() |
|
413 { |
|
414 DEBUG( "core_server_c::cancel_roam_timer()" ); |
|
415 |
|
416 roam_timer_m->stop(); |
|
417 } |
|
418 |
|
419 // --------------------------------------------------------------------------- |
|
420 // --------------------------------------------------------------------------- |
|
421 // |
|
422 void core_server_c::roam_timer_expired( |
|
423 void* this_ptr ) |
|
424 { |
|
425 DEBUG("core_server_c::roam_timer_expired()"); |
|
426 core_server_c* self = static_cast<core_server_c*>( this_ptr ); |
|
427 |
|
428 // send an indication to adaptation |
|
429 self->callback_m.notify( |
|
430 core_notification_rcpi_roam_attempt_started, |
|
431 0, |
|
432 NULL ); |
|
433 |
|
434 core_operation_base_c* command = new core_operation_check_rcpi_c( |
|
435 REQUEST_ID_CORE_INTERNAL, |
|
436 self, |
|
437 &(self->drivers_m), |
|
438 &(self->callback_m), |
|
439 core_operation_check_rcpi_c::core_rcpi_check_reason_timer ); |
|
440 |
|
441 self->queue_int_operation_and_run_next( command ); |
|
442 } |
|
443 |
|
444 // --------------------------------------------------------------------------- |
|
445 // --------------------------------------------------------------------------- |
|
446 // |
|
447 void core_server_c::schedule_operation_timer( |
|
448 u32_t delay ) |
|
449 { |
|
450 DEBUG1( "core_server_c::schedule_operation_timer() - delay %u", |
|
451 delay ); |
|
452 |
|
453 ASSERT( !operation_timer_m->is_active() ); |
|
454 operation_timer_m->start( |
|
455 delay ); |
|
456 } |
|
457 |
|
458 // --------------------------------------------------------------------------- |
|
459 // --------------------------------------------------------------------------- |
|
460 // |
|
461 void core_server_c::cancel_operation_timer() |
|
462 { |
|
463 DEBUG( "core_server_c::cancel_operation_timer()" ); |
|
464 operation_timer_m->stop(); |
|
465 } |
|
466 |
|
467 // --------------------------------------------------------------------------- |
|
468 // --------------------------------------------------------------------------- |
|
469 // |
|
470 void core_server_c::operation_timer_expired( |
|
471 void* this_ptr ) |
|
472 { |
|
473 DEBUG("core_server_c::operation_timer_expired()"); |
|
474 core_server_c* self = static_cast<core_server_c*>( this_ptr ); |
|
475 |
|
476 core_operation_base_c* command = self->queue_m.first(); |
|
477 ASSERT( command ); |
|
478 ASSERT( command->is_executing() ); |
|
479 self->request_complete( command->request_id(), core_error_ok ); |
|
480 } |
|
481 |
|
482 // --------------------------------------------------------------------------- |
|
483 // --------------------------------------------------------------------------- |
|
484 // |
|
485 bool_t core_server_c::is_operation_in_queue_with_flags( |
|
486 u32_t feature_flags ) |
|
487 { |
|
488 core_type_list_iterator_c<core_operation_base_c> iter( queue_m ); |
|
489 for( core_operation_base_c* current = iter.first(); current; current = iter.next() ) |
|
490 { |
|
491 if ( current->is_flags( feature_flags ) ) |
|
492 { |
|
493 return true_t; |
|
494 } |
|
495 } |
|
496 |
|
497 return false_t; |
|
498 } |
|
499 |
|
500 // --------------------------------------------------------------------------- |
|
501 // --------------------------------------------------------------------------- |
|
502 // |
|
503 bool_t core_server_c::is_operation_in_queue_with_type( |
|
504 u32_t type ) |
|
505 { |
|
506 core_type_list_iterator_c<core_operation_base_c> iter( queue_m ); |
|
507 for( core_operation_base_c* current = iter.first(); current; current = iter.next() ) |
|
508 { |
|
509 if ( current->operation_type() == type ) |
|
510 { |
|
511 return true_t; |
|
512 } |
|
513 } |
|
514 |
|
515 return false_t; |
|
516 } |
|
517 |
|
518 // --------------------------------------------------------------------------- |
|
519 // --------------------------------------------------------------------------- |
|
520 // |
|
521 bool_t core_server_c::is_dhcp_timer_active() |
|
522 { |
|
523 return driver_dhcp_timer_m->is_active(); |
|
524 } |
|
525 |
|
526 // --------------------------------------------------------------------------- |
|
527 // --------------------------------------------------------------------------- |
|
528 // |
|
529 void core_server_c::schedule_dhcp_timer( |
|
530 u32_t delay ) |
|
531 { |
|
532 DEBUG1( "core_server_c::schedule_dhcp_timer() - delay %u", |
|
533 delay ); |
|
534 |
|
535 ASSERT( !is_dhcp_timer_active() ); |
|
536 |
|
537 driver_dhcp_timer_m->start( |
|
538 delay ); |
|
539 } |
|
540 |
|
541 // --------------------------------------------------------------------------- |
|
542 // --------------------------------------------------------------------------- |
|
543 // |
|
544 void core_server_c::cancel_dhcp_timer() |
|
545 { |
|
546 DEBUG( "core_server_c::cancel_dhcp_timer()" ); |
|
547 |
|
548 driver_dhcp_timer_m->stop(); |
|
549 } |
|
550 |
|
551 // --------------------------------------------------------------------------- |
|
552 // --------------------------------------------------------------------------- |
|
553 // |
|
554 void core_server_c::dhcp_timer_expired( |
|
555 void* this_ptr ) |
|
556 { |
|
557 DEBUG( "core_server_c::dhcp_timer_expired()" ); |
|
558 |
|
559 core_server_c* self = static_cast<core_server_c*>( this_ptr ); |
|
560 |
|
561 core_operation_base_c* command = new core_operation_power_save_test_c( |
|
562 REQUEST_ID_CORE_INTERNAL, |
|
563 self, |
|
564 &(self->drivers_m), |
|
565 &(self->callback_m) ); |
|
566 |
|
567 self->queue_int_operation_and_run_next( command ); |
|
568 } |
|
569 |
|
570 // --------------------------------------------------------------------------- |
|
571 // --------------------------------------------------------------------------- |
|
572 // |
|
573 void core_server_c::schedule_unload_timer( |
|
574 u32_t delay ) |
|
575 { |
|
576 DEBUG1( "core_server_c::schedule_unload_timer() - delay %u", |
|
577 delay ); |
|
578 |
|
579 ASSERT( !driver_unload_timer_m->is_active() ); |
|
580 |
|
581 driver_unload_timer_m->start( |
|
582 delay ); |
|
583 } |
|
584 |
|
585 // --------------------------------------------------------------------------- |
|
586 // --------------------------------------------------------------------------- |
|
587 // |
|
588 void core_server_c::cancel_unload_timer() |
|
589 { |
|
590 DEBUG( "core_server_c::cancel_unload_timer()" ); |
|
591 |
|
592 driver_unload_timer_m->stop(); |
|
593 } |
|
594 |
|
595 // --------------------------------------------------------------------------- |
|
596 // --------------------------------------------------------------------------- |
|
597 // |
|
598 void core_server_c::cancel_operations_with_flags( |
|
599 u32_t feature_flags ) |
|
600 { |
|
601 DEBUG( "core_server_c::cancel_operations_with_flags()" ); |
|
602 DEBUG1( "core_server_c::cancel_operations_with_flags() - feature_flags %u", |
|
603 feature_flags ); |
|
604 |
|
605 core_operation_base_c* command = queue_m.first(); |
|
606 while ( command ) |
|
607 { |
|
608 if ( !command->is_executing() && |
|
609 command->is_flags( feature_flags ) ) |
|
610 { |
|
611 DEBUG2( "core_server_c::cancel_operations_with_flags() - canceling operation (id %u, type %u)", |
|
612 command->request_id(), command->operation_type() ); |
|
613 if ( command->request_id() != REQUEST_ID_CORE_INTERNAL ) |
|
614 { |
|
615 DEBUG( "core_server_c::cancel_operations_with_flags() - adaptation request, completing it" ); |
|
616 callback_m.request_complete( |
|
617 command->request_id(), |
|
618 core_error_cancel ); |
|
619 } |
|
620 |
|
621 queue_m.remove( command ); |
|
622 delete command; |
|
623 command = queue_m.first(); |
|
624 } |
|
625 else |
|
626 { |
|
627 command = queue_m.next(); |
|
628 } |
|
629 } |
|
630 } |
|
631 |
|
632 // --------------------------------------------------------------------------- |
|
633 // --------------------------------------------------------------------------- |
|
634 // |
|
635 void core_server_c::cancel_operations_with_type( |
|
636 u32_t type ) |
|
637 { |
|
638 DEBUG( "core_server_c::cancel_operation_with_type()" ); |
|
639 DEBUG1( "core_server_c::cancel_operation_with_type() - type %u", |
|
640 type ); |
|
641 |
|
642 core_operation_base_c* command = queue_m.first(); |
|
643 while ( command ) |
|
644 { |
|
645 if ( !command->is_executing() && |
|
646 command->operation_type() == type ) |
|
647 { |
|
648 DEBUG2( "core_server_c::cancel_operation_with_type() - canceling operation (id %u, type %u)", |
|
649 command->request_id(), command->operation_type() ); |
|
650 if ( command->request_id() != REQUEST_ID_CORE_INTERNAL ) |
|
651 { |
|
652 DEBUG( "core_server_c::cancel_operation_with_type() - adaptation request, completing it" ); |
|
653 callback_m.request_complete( |
|
654 command->request_id(), |
|
655 core_error_cancel ); |
|
656 } |
|
657 |
|
658 queue_m.remove( command ); |
|
659 delete command; |
|
660 command = queue_m.first(); |
|
661 } |
|
662 else |
|
663 { |
|
664 command = queue_m.next(); |
|
665 } |
|
666 } |
|
667 } |
|
668 |
|
669 // --------------------------------------------------------------------------- |
|
670 // --------------------------------------------------------------------------- |
|
671 // |
|
672 void core_server_c::cancel_all_operations( |
|
673 bool_t is_graceful_cancel ) |
|
674 { |
|
675 DEBUG( "core_server_c::cancel_all_operations()" ); |
|
676 |
|
677 core_operation_base_c* command = queue_m.first(); |
|
678 while ( command ) |
|
679 { |
|
680 if ( !command->is_executing() ) |
|
681 { |
|
682 DEBUG2( "core_server_c::cancel_all_operations() - canceling operation (id %u, type %u)", |
|
683 command->request_id(), command->operation_type() ); |
|
684 if ( command->request_id() != REQUEST_ID_CORE_INTERNAL ) |
|
685 { |
|
686 DEBUG( "core_server_c::cancel_all_operations() - adaptation request, completing it" ); |
|
687 callback_m.request_complete( |
|
688 command->request_id(), |
|
689 core_error_cancel ); |
|
690 } |
|
691 |
|
692 queue_m.remove( command ); |
|
693 delete command; |
|
694 command = queue_m.first(); |
|
695 } |
|
696 else |
|
697 { |
|
698 command = queue_m.next(); |
|
699 } |
|
700 } |
|
701 |
|
702 command = queue_m.first(); |
|
703 if ( command ) |
|
704 { |
|
705 if( is_graceful_cancel ) |
|
706 { |
|
707 DEBUG2( "core_server_c::cancel_all_operations() - canceling currently executing operation (id %u, type %u) (graceful cancel)", |
|
708 command->request_id(), command->operation_type() ); |
|
709 } |
|
710 else |
|
711 { |
|
712 DEBUG2( "core_server_c::cancel_all_operations() - canceling currently executing operation (id %u, type %u) (forced cancel)", |
|
713 command->request_id(), command->operation_type() ); |
|
714 } |
|
715 |
|
716 ASSERT( command->is_executing() ); |
|
717 |
|
718 // Let operation handle it's own cancelling |
|
719 command->user_cancel_operation( is_graceful_cancel ); |
|
720 } |
|
721 } |
|
722 |
|
723 // --------------------------------------------------------------------------- |
|
724 // --------------------------------------------------------------------------- |
|
725 // |
|
726 bool_t core_server_c::create_eapol_instance( |
|
727 core_eapol_operating_mode_e mode ) |
|
728 { |
|
729 DEBUG( "core_server_c::create_eapol_instance()" ); |
|
730 |
|
731 if ( eapol_m && |
|
732 eapol_m->operating_mode() == mode ) |
|
733 { |
|
734 DEBUG( "core_server_c::create_eapol_instance() - an instance already exists" ); |
|
735 |
|
736 return true_t; |
|
737 } |
|
738 |
|
739 if ( eapol_m ) |
|
740 { |
|
741 DEBUG( "core_server_c::create_eapol_instance() - deleting old core_wlan_eapol_interface_c instance" ); |
|
742 |
|
743 eapol_m->shutdown(); |
|
744 delete eapol_m; |
|
745 eapol_m = NULL; |
|
746 } |
|
747 |
|
748 DEBUG1( "core_server_c::create_eapol_instance() - creating core_wlan_eapol_interface_c (mode %u)", |
|
749 mode ); |
|
750 |
|
751 eapol_m = new core_wlan_eapol_interface_c( callback_m ); |
|
752 if ( !eapol_m ) |
|
753 { |
|
754 DEBUG( "core_server_c::create_eapol_instance() - unable to create core_wlan_eapol_interface_c" ); |
|
755 return false_t; |
|
756 } |
|
757 core_error_e error = eapol_m->load_eapol( mode, eapol_handler_m ); |
|
758 if ( error != core_error_ok ) |
|
759 { |
|
760 DEBUG1( "core_server_c::create_eapol_instance() - load_eapol failed with %i", error ); |
|
761 delete eapol_m; |
|
762 eapol_m = NULL; |
|
763 return false_t; |
|
764 } |
|
765 error = eapol_m->configure(); |
|
766 if ( error != core_error_ok ) |
|
767 { |
|
768 DEBUG1( "core_server_c::create_eapol_instance() - configure failed with %i", error ); |
|
769 delete eapol_m; |
|
770 eapol_m = NULL; |
|
771 return false_t; |
|
772 } |
|
773 |
|
774 return true_t; |
|
775 } |
|
776 |
|
777 // --------------------------------------------------------------------------- |
|
778 // --------------------------------------------------------------------------- |
|
779 // |
|
780 abs_core_frame_handler_c* core_server_c::frame_handler() |
|
781 { |
|
782 return frame_handler_m; |
|
783 } |
|
784 |
|
785 // --------------------------------------------------------------------------- |
|
786 // --------------------------------------------------------------------------- |
|
787 // |
|
788 void core_server_c::register_frame_handler( |
|
789 abs_core_frame_handler_c* handler ) |
|
790 { |
|
791 ASSERT( handler ); |
|
792 ASSERT( handler == frame_handler_m || !frame_handler_m ); |
|
793 |
|
794 frame_handler_m = handler; |
|
795 } |
|
796 |
|
797 // --------------------------------------------------------------------------- |
|
798 // --------------------------------------------------------------------------- |
|
799 // |
|
800 void core_server_c::unregister_frame_handler( |
|
801 abs_core_frame_handler_c* handler ) |
|
802 { |
|
803 ASSERT( handler ); |
|
804 |
|
805 if ( frame_handler_m != handler ) |
|
806 { |
|
807 DEBUG1( "core_server_c::unregister_frame_handler() - handler 0x%08X not registered", |
|
808 handler ); |
|
809 |
|
810 return; |
|
811 } |
|
812 |
|
813 frame_handler_m = NULL; |
|
814 } |
|
815 |
|
816 // --------------------------------------------------------------------------- |
|
817 // --------------------------------------------------------------------------- |
|
818 // |
|
819 core_scan_list_c& core_server_c::get_scan_list() |
|
820 { |
|
821 return scan_list_m; |
|
822 } |
|
823 |
|
824 // --------------------------------------------------------------------------- |
|
825 // --------------------------------------------------------------------------- |
|
826 // |
|
827 abs_core_event_handler_c* core_server_c::event_handler() |
|
828 { |
|
829 return event_handler_m; |
|
830 } |
|
831 |
|
832 // --------------------------------------------------------------------------- |
|
833 // --------------------------------------------------------------------------- |
|
834 // |
|
835 void core_server_c::register_event_handler( |
|
836 abs_core_event_handler_c* handler ) |
|
837 { |
|
838 ASSERT( handler ); |
|
839 ASSERT( handler == event_handler_m || !event_handler_m ); |
|
840 |
|
841 event_handler_m = handler; |
|
842 } |
|
843 |
|
844 // --------------------------------------------------------------------------- |
|
845 // --------------------------------------------------------------------------- |
|
846 // |
|
847 void core_server_c::unregister_event_handler( |
|
848 abs_core_event_handler_c* handler ) |
|
849 { |
|
850 ASSERT( handler ); |
|
851 |
|
852 if ( event_handler_m != handler ) |
|
853 { |
|
854 DEBUG1( "core_server_c::unregister_event_handler() - handler 0x%08X not registered", |
|
855 handler ); |
|
856 |
|
857 return; |
|
858 } |
|
859 |
|
860 event_handler_m = NULL; |
|
861 } |
|
862 |
|
863 // --------------------------------------------------------------------------- |
|
864 // --------------------------------------------------------------------------- |
|
865 // |
|
866 void core_server_c::schedule_roam( |
|
867 core_operation_handle_bss_lost_c::core_bss_lost_reason_e reason ) |
|
868 { |
|
869 if ( !is_operation_in_queue_with_type( core_operation_handle_bss_lost ) ) |
|
870 { |
|
871 DEBUG( "core_server_c::schedule_roam() - scheduling a core_operation_handle_bss_lost operation" ); |
|
872 |
|
873 core_operation_base_c* command = new core_operation_handle_bss_lost_c( |
|
874 REQUEST_ID_CORE_INTERNAL, |
|
875 this, |
|
876 &drivers_m, |
|
877 &callback_m, |
|
878 reason ); |
|
879 |
|
880 queue_int_operation_and_run_next( command ); |
|
881 } |
|
882 else |
|
883 { |
|
884 DEBUG( "core_server_c::schedule_roam() - core_operation_handle_bss_lost already in the queue" ); |
|
885 } |
|
886 } |
|
887 |
|
888 // --------------------------------------------------------------------------- |
|
889 // --------------------------------------------------------------------------- |
|
890 // |
|
891 bool_t core_server_c::send_management_frame( |
|
892 core_frame_type_e frame_type, |
|
893 const u16_t frame_length, |
|
894 const u8_t* const frame_data, |
|
895 const core_mac_address_s& destination ) |
|
896 { |
|
897 /** Management frames can be sent without downgraded user priority. */ |
|
898 drivers_m.send_frame( |
|
899 frame_type, |
|
900 frame_length, |
|
901 frame_data, |
|
902 core_tools_c::convert_ac_to_user_priority( core_access_class_voice ), |
|
903 destination, |
|
904 true_t ); |
|
905 |
|
906 return true_t; |
|
907 } |
|
908 |
|
909 // --------------------------------------------------------------------------- |
|
910 // --------------------------------------------------------------------------- |
|
911 // |
|
912 bool_t core_server_c::send_data_frame( |
|
913 const core_ap_data_c& ap_data, |
|
914 core_frame_type_e frame_type, |
|
915 const u16_t frame_length, |
|
916 const u8_t* const frame_data, |
|
917 core_access_class_e frame_priority, |
|
918 const core_mac_address_s& destination, |
|
919 bool_t send_unencrypted ) |
|
920 { |
|
921 DEBUG( "core_server_c::send_data_frame()" ); |
|
922 |
|
923 u8_t initial_priority( |
|
924 core_tools_c::convert_ac_to_user_priority( frame_priority ) ); |
|
925 u8_t user_priority = initial_priority; |
|
926 |
|
927 if ( ap_data.is_wmm_ie_present() ) |
|
928 { |
|
929 /** |
|
930 * Collect a list of active streams per user priority. |
|
931 */ |
|
932 bool_t is_ts_for_user_priority[MAX_QOS_USER_PRIORITY]; |
|
933 core_tools_c::fillz( |
|
934 &is_ts_for_user_priority[0], |
|
935 sizeof( is_ts_for_user_priority ) ); |
|
936 |
|
937 core_traffic_stream_list_iter_c iter( |
|
938 get_connection_data()->traffic_stream_list() ); |
|
939 |
|
940 core_traffic_stream_c* entry = iter.first(); |
|
941 while( entry ) |
|
942 { |
|
943 if ( entry->status() == core_traffic_stream_status_active ) |
|
944 { |
|
945 is_ts_for_user_priority[entry->user_priority()] = true_t; |
|
946 } |
|
947 |
|
948 entry = iter.next(); |
|
949 } |
|
950 |
|
951 /** |
|
952 * See if downgrade should be done. |
|
953 */ |
|
954 bool_t is_send_ok( false_t ); |
|
955 |
|
956 while ( user_priority <= initial_priority && !is_send_ok ) |
|
957 { |
|
958 core_access_class_e ac( |
|
959 core_tools_c::convert_user_priority_to_ac( user_priority ) ); |
|
960 |
|
961 #if 0 |
|
962 DEBUG1( "core_server_c::send_data_frame() - user_priority is %u", |
|
963 user_priority ); |
|
964 DEBUG1( "core_server_c::send_data_frame() - ac is %u", |
|
965 ac ); |
|
966 DEBUG1( "core_server_c::send_data_frame() - is_admission_control_required is %u", |
|
967 ap_data.is_admission_control_required( ac ) ); |
|
968 DEBUG1( "core_server_c::send_data_frame() - is_ts_for_user_priority is %u", |
|
969 is_ts_for_user_priority[user_priority] ); |
|
970 #endif // 0 |
|
971 |
|
972 if ( !ap_data.is_admission_control_required( ac ) || |
|
973 is_ts_for_user_priority[user_priority] ) |
|
974 { |
|
975 is_send_ok = true_t; |
|
976 } |
|
977 else |
|
978 { |
|
979 user_priority--; |
|
980 } |
|
981 } |
|
982 |
|
983 if ( !is_send_ok ) |
|
984 { |
|
985 DEBUG( "core_server_c::send_data_frame() - unable to send the frame due to admission control settings" ); |
|
986 return false_t; |
|
987 } |
|
988 } |
|
989 |
|
990 if ( user_priority == initial_priority ) |
|
991 { |
|
992 DEBUG1( "core_server_c::send_data_frame() - no need to downgrade user priority %u", |
|
993 user_priority ); |
|
994 } |
|
995 else |
|
996 { |
|
997 DEBUG2( "core_server_c::send_data_frame() - user priority %u downgraded to %u", |
|
998 initial_priority, user_priority ); |
|
999 } |
|
1000 |
|
1001 drivers_m.send_frame( |
|
1002 frame_type, |
|
1003 frame_length, |
|
1004 frame_data, |
|
1005 user_priority, |
|
1006 destination, |
|
1007 send_unencrypted ); |
|
1008 |
|
1009 return true_t; |
|
1010 } |
|
1011 |
|
1012 // --------------------------------------------------------------------------- |
|
1013 // --------------------------------------------------------------------------- |
|
1014 // |
|
1015 abs_core_wpx_adaptation_c& core_server_c::get_wpx_adaptation_instance() |
|
1016 { |
|
1017 return *wpx_adaptation_m; |
|
1018 } |
|
1019 |
|
1020 // --------------------------------------------------------------------------- |
|
1021 // --------------------------------------------------------------------------- |
|
1022 // |
|
1023 void core_server_c::set_protected_setup_handler( |
|
1024 abs_core_protected_setup_handler_c* handler ) |
|
1025 { |
|
1026 eapol_handler_m->set_protected_setup_handler( handler ); |
|
1027 } |
|
1028 |
|
1029 // --------------------------------------------------------------------------- |
|
1030 // --------------------------------------------------------------------------- |
|
1031 // |
|
1032 void core_server_c::connect( |
|
1033 u32_t request_id, |
|
1034 const core_iap_data_s& settings, |
|
1035 core_connect_status_e& connect_status, |
|
1036 core_type_list_c<core_ssid_entry_s>* ssid_list ) |
|
1037 { |
|
1038 DEBUG( "core_server_c::connect()" ); |
|
1039 |
|
1040 core_operation_base_c* command = new core_operation_connect_c( |
|
1041 request_id, this, &drivers_m, &callback_m, settings, ssid_list, connect_status ); |
|
1042 |
|
1043 queue_ext_operation_and_run_next( command, request_id ); |
|
1044 } |
|
1045 |
|
1046 // --------------------------------------------------------------------------- |
|
1047 // --------------------------------------------------------------------------- |
|
1048 // |
|
1049 void core_server_c::release( |
|
1050 u32_t request_id ) |
|
1051 { |
|
1052 DEBUG( "core_server_c::release()" ); |
|
1053 |
|
1054 /** |
|
1055 * Cancel all pending roaming operations. |
|
1056 */ |
|
1057 cancel_operations_with_flags( |
|
1058 core_operation_base_c::core_base_flag_roam_operation ); |
|
1059 |
|
1060 /** |
|
1061 * If there's an executing roam operation, let it handle |
|
1062 * its own cancel. |
|
1063 */ |
|
1064 core_operation_base_c* operation = queue_m.first(); |
|
1065 if( operation && |
|
1066 operation->is_flags( core_operation_base_c::core_base_flag_roam_operation ) ) |
|
1067 { |
|
1068 operation->user_cancel_operation( true_t ); // Using graceful cancel |
|
1069 } |
|
1070 |
|
1071 core_operation_base_c* command = new core_operation_release_c( |
|
1072 request_id, this, &drivers_m, &callback_m, core_release_reason_external_request ); |
|
1073 |
|
1074 queue_ext_operation_and_run_next( command, request_id ); |
|
1075 } |
|
1076 |
|
1077 // --------------------------------------------------------------------------- |
|
1078 // --------------------------------------------------------------------------- |
|
1079 // |
|
1080 void core_server_c::get_scan_result( |
|
1081 u32_t request_id, |
|
1082 core_scan_mode_e scan_mode, |
|
1083 const core_ssid_s& scan_ssid, |
|
1084 const core_scan_channels_s& scan_channels, |
|
1085 u8_t scan_max_age, |
|
1086 ScanList& scan_data, |
|
1087 bool_t is_current_ap_added ) |
|
1088 { |
|
1089 DEBUG( "core_server_c::get_scan_result()" ); |
|
1090 |
|
1091 core_operation_base_c* command = new core_operation_scan_c( |
|
1092 request_id, this, &drivers_m, &callback_m, |
|
1093 scan_mode, scan_ssid, scan_channels, scan_max_age, scan_data, |
|
1094 true_t, |
|
1095 is_current_ap_added ); |
|
1096 |
|
1097 queue_ext_operation_and_run_next( command, request_id ); |
|
1098 } |
|
1099 |
|
1100 // --------------------------------------------------------------------------- |
|
1101 // --------------------------------------------------------------------------- |
|
1102 // |
|
1103 void core_server_c::get_available_iaps( |
|
1104 u32_t request_id, |
|
1105 bool_t is_active_scan_allowed, |
|
1106 core_type_list_c<core_iap_data_s>& iap_data_list, |
|
1107 core_type_list_c<u32_t>& iap_id_list, |
|
1108 core_type_list_c<core_ssid_entry_s>* iap_ssid_list, |
|
1109 ScanList& scan_data ) |
|
1110 { |
|
1111 DEBUG( "core_server_c::get_available_iaps()" ); |
|
1112 |
|
1113 core_operation_base_c* command = new core_operation_get_available_iaps_c( |
|
1114 request_id, |
|
1115 this, |
|
1116 &drivers_m, |
|
1117 &callback_m, |
|
1118 is_active_scan_allowed, |
|
1119 iap_data_list, |
|
1120 iap_id_list, |
|
1121 iap_ssid_list, |
|
1122 scan_data ); |
|
1123 |
|
1124 queue_ext_operation_and_run_next( command, request_id ); |
|
1125 } |
|
1126 |
|
1127 // --------------------------------------------------------------------------- |
|
1128 // --------------------------------------------------------------------------- |
|
1129 // |
|
1130 void core_server_c::get_current_rcpi( |
|
1131 u32_t request_id, |
|
1132 u32_t& rcpi ) |
|
1133 { |
|
1134 DEBUG( "core_server_c::get_current_rcpi()" ); |
|
1135 |
|
1136 core_operation_base_c* command = new core_operation_get_rcpi_c( |
|
1137 request_id, this, &drivers_m, &callback_m, rcpi ); |
|
1138 |
|
1139 queue_ext_operation_and_run_next( command, request_id ); |
|
1140 } |
|
1141 |
|
1142 // --------------------------------------------------------------------------- |
|
1143 // --------------------------------------------------------------------------- |
|
1144 // |
|
1145 void core_server_c::disable_wlan( |
|
1146 u32_t request_id ) |
|
1147 { |
|
1148 DEBUG( "core_server_c::disable_wlan()" ); |
|
1149 |
|
1150 get_core_settings().set_wlan_enabled( false_t ); |
|
1151 |
|
1152 /** |
|
1153 * Schedule an immediate driver unload. |
|
1154 */ |
|
1155 unload_drivers(); |
|
1156 |
|
1157 core_operation_base_c* command = new core_operation_null_c( |
|
1158 request_id, this, &drivers_m, &callback_m, core_error_ok ); |
|
1159 |
|
1160 queue_ext_operation_and_run_next( command, request_id ); |
|
1161 } |
|
1162 |
|
1163 // --------------------------------------------------------------------------- |
|
1164 // --------------------------------------------------------------------------- |
|
1165 // |
|
1166 void core_server_c::enable_wlan( |
|
1167 u32_t request_id ) |
|
1168 { |
|
1169 DEBUG( "core_server_c::enable_wlan()" ); |
|
1170 |
|
1171 core_settings_m.set_wlan_enabled( true_t ); |
|
1172 |
|
1173 core_operation_base_c* command = new core_operation_null_c( |
|
1174 request_id, this, &drivers_m, &callback_m, core_error_ok ); |
|
1175 |
|
1176 queue_ext_operation_and_run_next( command, request_id ); |
|
1177 } |
|
1178 |
|
1179 // --------------------------------------------------------------------------- |
|
1180 // --------------------------------------------------------------------------- |
|
1181 // |
|
1182 core_error_e core_server_c::unload_drivers() |
|
1183 { |
|
1184 DEBUG( "core_server_c::unload_drivers()" ); |
|
1185 |
|
1186 /** |
|
1187 * If drivers are loaded, schedule an immediate unload. |
|
1188 */ |
|
1189 if( get_core_settings().is_driver_loaded() ) |
|
1190 { |
|
1191 cancel_unload_timer(); |
|
1192 schedule_unload_timer( CORE_TIMER_IMMEDIATELY ); |
|
1193 |
|
1194 return core_error_ok; |
|
1195 } |
|
1196 else |
|
1197 { |
|
1198 return core_error_drivers_not_loaded; |
|
1199 } |
|
1200 } |
|
1201 |
|
1202 // --------------------------------------------------------------------------- |
|
1203 // --------------------------------------------------------------------------- |
|
1204 // |
|
1205 void core_server_c::get_packet_statistics( |
|
1206 u32_t request_id, |
|
1207 core_packet_statistics_s& statistics ) |
|
1208 { |
|
1209 DEBUG( "core_server_c::get_packet_statistics()" ); |
|
1210 |
|
1211 core_operation_base_c* command = new core_operation_get_statistics_c( |
|
1212 request_id, this, &drivers_m, &callback_m, statistics ); |
|
1213 |
|
1214 queue_ext_operation_and_run_next( command, request_id ); |
|
1215 } |
|
1216 |
|
1217 // --------------------------------------------------------------------------- |
|
1218 // --------------------------------------------------------------------------- |
|
1219 // |
|
1220 void core_server_c::create_traffic_stream( |
|
1221 u32_t request_id, |
|
1222 u8_t tid, |
|
1223 u8_t user_priority, |
|
1224 bool_t is_automatic_stream, |
|
1225 const core_traffic_stream_params_s& params, |
|
1226 u32_t& stream_id, |
|
1227 core_traffic_stream_status_e& stream_status ) |
|
1228 { |
|
1229 DEBUG( "core_server_c::create_traffic_stream()" ); |
|
1230 |
|
1231 core_operation_base_c* command = new core_operation_create_ts_c( |
|
1232 request_id, |
|
1233 this, |
|
1234 &drivers_m, |
|
1235 &callback_m, |
|
1236 tid, |
|
1237 user_priority, |
|
1238 is_automatic_stream, |
|
1239 params, |
|
1240 stream_id, |
|
1241 stream_status ); |
|
1242 |
|
1243 queue_ext_operation_and_run_next( command, request_id ); |
|
1244 } |
|
1245 |
|
1246 // --------------------------------------------------------------------------- |
|
1247 // --------------------------------------------------------------------------- |
|
1248 // |
|
1249 void core_server_c::delete_traffic_stream( |
|
1250 u32_t request_id, |
|
1251 u32_t stream_id ) |
|
1252 { |
|
1253 DEBUG( "core_server_c::delete_traffic_stream()" ); |
|
1254 |
|
1255 core_operation_base_c* command = new core_operation_delete_ts_c( |
|
1256 request_id, |
|
1257 this, |
|
1258 &drivers_m, |
|
1259 &callback_m, |
|
1260 stream_id ); |
|
1261 |
|
1262 queue_ext_operation_and_run_next( command, request_id ); |
|
1263 } |
|
1264 |
|
1265 // --------------------------------------------------------------------------- |
|
1266 // --------------------------------------------------------------------------- |
|
1267 // |
|
1268 void core_server_c::run_protected_setup( |
|
1269 u32_t request_id, |
|
1270 const core_iap_data_s& iap_data, |
|
1271 core_type_list_c<core_iap_data_s>& iap_data_list, |
|
1272 core_protected_setup_status_e& protected_setup_status ) |
|
1273 { |
|
1274 DEBUG( "core_server_c::run_protected_setup()" ); |
|
1275 |
|
1276 core_operation_base_c* command = new core_operation_protected_setup_c( |
|
1277 request_id, this, &drivers_m, &callback_m, iap_data, iap_data_list, |
|
1278 protected_setup_status ); |
|
1279 |
|
1280 queue_ext_operation_and_run_next( command, request_id ); |
|
1281 } |
|
1282 |
|
1283 // --------------------------------------------------------------------------- |
|
1284 // --------------------------------------------------------------------------- |
|
1285 // |
|
1286 void core_server_c::directed_roam( |
|
1287 u32_t request_id, |
|
1288 const core_mac_address_s& bssid ) |
|
1289 { |
|
1290 DEBUG( "core_server_c::directed_roam()" ); |
|
1291 |
|
1292 core_operation_base_c* command = new core_operation_directed_roam_c( |
|
1293 request_id, this, &drivers_m, &callback_m, bssid ); |
|
1294 |
|
1295 queue_ext_operation_and_run_next( command, request_id ); |
|
1296 } |
|
1297 |
|
1298 // --------------------------------------------------------------------------- |
|
1299 // --------------------------------------------------------------------------- |
|
1300 // |
|
1301 core_error_e core_server_c::get_current_bssid( |
|
1302 core_mac_address_s& bssid ) |
|
1303 { |
|
1304 DEBUG( "core_server_c::get_current_bssid()" ); |
|
1305 |
|
1306 bssid = ZERO_MAC_ADDR; |
|
1307 if ( core_settings_m.is_connected() && |
|
1308 connection_data_m && |
|
1309 connection_data_m->current_ap_data() ) |
|
1310 { |
|
1311 bssid = connection_data_m->current_ap_data()->bssid(); |
|
1312 |
|
1313 return core_error_ok; |
|
1314 } |
|
1315 |
|
1316 return core_error_not_connected; |
|
1317 } |
|
1318 |
|
1319 // --------------------------------------------------------------------------- |
|
1320 // --------------------------------------------------------------------------- |
|
1321 // |
|
1322 core_error_e core_server_c::get_current_ssid( |
|
1323 core_ssid_s& ssid ) |
|
1324 { |
|
1325 DEBUG( "core_server_c::get_current_ssid()" ); |
|
1326 |
|
1327 ssid = BROADCAST_SSID; |
|
1328 if ( core_settings_m.is_connected() && |
|
1329 connection_data_m && |
|
1330 connection_data_m->current_ap_data() ) |
|
1331 { |
|
1332 ssid = connection_data_m->ssid(); |
|
1333 |
|
1334 return core_error_ok; |
|
1335 } |
|
1336 |
|
1337 return core_error_not_connected; |
|
1338 } |
|
1339 |
|
1340 // --------------------------------------------------------------------------- |
|
1341 // --------------------------------------------------------------------------- |
|
1342 // |
|
1343 core_error_e core_server_c::get_current_security_mode( |
|
1344 core_connection_security_mode_e& mode ) |
|
1345 { |
|
1346 DEBUG( "core_server_c::get_current_security_mode()" ); |
|
1347 |
|
1348 mode = core_connection_security_mode_open; |
|
1349 if ( core_settings_m.is_connected() && |
|
1350 connection_data_m && |
|
1351 connection_data_m->current_ap_data() ) |
|
1352 { |
|
1353 mode = core_tools_c::security_mode( |
|
1354 connection_data_m->iap_data(), |
|
1355 *connection_data_m->current_ap_data() ); |
|
1356 |
|
1357 return core_error_ok; |
|
1358 } |
|
1359 |
|
1360 return core_error_not_connected; |
|
1361 } |
|
1362 |
|
1363 // --------------------------------------------------------------------------- |
|
1364 // --------------------------------------------------------------------------- |
|
1365 // |
|
1366 core_error_e core_server_c::get_current_connection_state( |
|
1367 core_connection_state_e& state ) |
|
1368 { |
|
1369 DEBUG( "core_server_c::get_current_connection_state()" ); |
|
1370 |
|
1371 state = core_settings_m.connection_state(); |
|
1372 |
|
1373 return core_error_ok; |
|
1374 } |
|
1375 |
|
1376 // --------------------------------------------------------------------------- |
|
1377 // --------------------------------------------------------------------------- |
|
1378 // |
|
1379 core_error_e core_server_c::update_device_settings( |
|
1380 core_device_settings_s& settings ) |
|
1381 { |
|
1382 DEBUG( "core_server_c::update_device_settings()" ); |
|
1383 |
|
1384 device_settings_m = settings; |
|
1385 |
|
1386 core_operation_base_c* command = new core_operation_update_device_settings_c( |
|
1387 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m ); |
|
1388 |
|
1389 queue_int_operation_and_run_next( command ); |
|
1390 |
|
1391 return core_error_ok; |
|
1392 } |
|
1393 |
|
1394 // --------------------------------------------------------------------------- |
|
1395 // --------------------------------------------------------------------------- |
|
1396 // |
|
1397 core_error_e core_server_c::set_power_save_mode( |
|
1398 const core_power_save_mode_s& mode ) |
|
1399 { |
|
1400 DEBUG( "core_server_c::set_power_save_mode()" ); |
|
1401 |
|
1402 core_settings_m.set_preferred_power_save_mode( mode ); |
|
1403 |
|
1404 core_operation_base_c* command = new core_operation_update_power_mode_c( |
|
1405 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m ); |
|
1406 |
|
1407 queue_int_operation_and_run_next( command ); |
|
1408 |
|
1409 return core_error_ok; |
|
1410 } |
|
1411 |
|
1412 // --------------------------------------------------------------------------- |
|
1413 // --------------------------------------------------------------------------- |
|
1414 // |
|
1415 core_error_e core_server_c::add_bssid_to_rogue_list( |
|
1416 const core_mac_address_s& bssid ) |
|
1417 { |
|
1418 DEBUG( "core_server_c::add_bssid_to_rogue_list()" ); |
|
1419 |
|
1420 core_settings_m.add_mac_to_permanent_blacklist( |
|
1421 bssid, core_ap_blacklist_reason_external ); |
|
1422 |
|
1423 return core_error_ok; |
|
1424 } |
|
1425 |
|
1426 // --------------------------------------------------------------------------- |
|
1427 // --------------------------------------------------------------------------- |
|
1428 // |
|
1429 core_error_e core_server_c::remove_bssid_from_rogue_list( |
|
1430 const core_mac_address_s& bssid ) |
|
1431 { |
|
1432 DEBUG( "core_server_c::remove_bssid_from_rogue_list()" ); |
|
1433 |
|
1434 core_settings_m.remove_mac_from_permanent_blacklist( bssid ); |
|
1435 |
|
1436 return core_error_ok; |
|
1437 } |
|
1438 |
|
1439 // --------------------------------------------------------------------------- |
|
1440 // --------------------------------------------------------------------------- |
|
1441 // |
|
1442 core_error_e core_server_c::get_rogue_list( |
|
1443 core_type_list_c<core_mac_address_s>& rogue_list ) |
|
1444 { |
|
1445 DEBUG( "core_server_c::get_rogue_list()" ); |
|
1446 |
|
1447 core_type_list_c<core_ap_blacklist_entry_s>& perm_list = core_settings_m.permanent_blacklist(); |
|
1448 DEBUG1( "core_server_c::get_rogue_list() - %d permanent addresses", perm_list.count() ); |
|
1449 |
|
1450 // Loop through permanent blacklist |
|
1451 core_ap_blacklist_entry_s* addr = perm_list.first(); |
|
1452 while ( addr ) |
|
1453 { |
|
1454 // Address must be copied, because rogue_list get ownership for its entries. |
|
1455 core_mac_address_s* copy_addr = new core_mac_address_s; |
|
1456 if ( !copy_addr ) |
|
1457 { |
|
1458 return core_error_no_memory; |
|
1459 } |
|
1460 *copy_addr = addr->bssid; |
|
1461 DEBUG_MAC( copy_addr->addr ); |
|
1462 |
|
1463 core_error_e status = rogue_list.append( copy_addr ); |
|
1464 if ( status != core_error_ok ) |
|
1465 { |
|
1466 return status; |
|
1467 } |
|
1468 |
|
1469 addr = perm_list.next(); |
|
1470 } |
|
1471 |
|
1472 // Check if connection is available. |
|
1473 if ( connection_data_m ) |
|
1474 { |
|
1475 core_type_list_c<core_ap_blacklist_entry_s>& temp_list = connection_data_m->temporary_blacklist(); |
|
1476 DEBUG1( "core_server_c::get_rogue_list() - %d temporary addresses", temp_list.count() ); |
|
1477 |
|
1478 // Loop through temporary blacklist |
|
1479 addr = temp_list.first(); |
|
1480 while ( addr ) |
|
1481 { |
|
1482 // Address must be copied, because rogue_list get ownership for its entries. |
|
1483 core_mac_address_s* copy_addr = new core_mac_address_s; |
|
1484 if ( !copy_addr ) |
|
1485 { |
|
1486 return core_error_no_memory; |
|
1487 } |
|
1488 *copy_addr = addr->bssid; |
|
1489 DEBUG_MAC( copy_addr->addr ); |
|
1490 |
|
1491 core_error_e status = rogue_list.append( copy_addr ); |
|
1492 if ( status != core_error_ok ) |
|
1493 { |
|
1494 return status; |
|
1495 } |
|
1496 |
|
1497 addr = temp_list.next(); |
|
1498 } |
|
1499 } |
|
1500 else |
|
1501 { |
|
1502 DEBUG( "core_server_c::get_rogue_list() - connection is not available, temporary blacklist is empty" ); |
|
1503 } |
|
1504 |
|
1505 return core_error_ok; |
|
1506 } |
|
1507 |
|
1508 // --------------------------------------------------------------------------- |
|
1509 // --------------------------------------------------------------------------- |
|
1510 // |
|
1511 core_error_e core_server_c::set_rcp_level_notification_boundary( |
|
1512 const i32_t rcp_level_boundary, |
|
1513 const i32_t hysteresis ) |
|
1514 { |
|
1515 DEBUG( "core_server_c::set_rcp_level_notification_boundary()" ); |
|
1516 |
|
1517 core_settings_m.set_rcpi_boundaries( |
|
1518 rcp_level_boundary, |
|
1519 rcp_level_boundary + hysteresis ); |
|
1520 |
|
1521 return core_error_ok; |
|
1522 } |
|
1523 |
|
1524 // --------------------------------------------------------------------------- |
|
1525 // --------------------------------------------------------------------------- |
|
1526 // |
|
1527 core_error_e core_server_c::clear_packet_statistics() |
|
1528 { |
|
1529 DEBUG( "core_server_c::clear_packet_statistics()" ); |
|
1530 |
|
1531 core_settings_m.clear_connection_statistics(); |
|
1532 core_settings_m.roam_metrics().clear_metrics(); |
|
1533 |
|
1534 return core_error_ok; |
|
1535 } |
|
1536 |
|
1537 // --------------------------------------------------------------------------- |
|
1538 // --------------------------------------------------------------------------- |
|
1539 // |
|
1540 core_error_e core_server_c::get_uapsd_settings( |
|
1541 core_uapsd_settings_s& settings ) |
|
1542 { |
|
1543 DEBUG( "core_server_c::get_uapsd_settings()" ); |
|
1544 |
|
1545 settings = core_settings_m.uapsd_settings(); |
|
1546 |
|
1547 return core_error_ok; |
|
1548 } |
|
1549 |
|
1550 // --------------------------------------------------------------------------- |
|
1551 // --------------------------------------------------------------------------- |
|
1552 // |
|
1553 core_error_e core_server_c::set_uapsd_settings( |
|
1554 const core_uapsd_settings_s& settings ) |
|
1555 { |
|
1556 DEBUG( "core_server_c::set_uapsd_settings()" ); |
|
1557 |
|
1558 core_operation_base_c* command = new core_operation_set_uapsd_settings_c( |
|
1559 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, settings ); |
|
1560 |
|
1561 queue_int_operation_and_run_next( command ); |
|
1562 |
|
1563 return core_error_ok; |
|
1564 } |
|
1565 |
|
1566 // --------------------------------------------------------------------------- |
|
1567 // --------------------------------------------------------------------------- |
|
1568 // |
|
1569 core_error_e core_server_c::get_power_save_settings( |
|
1570 core_power_save_settings_s& settings ) |
|
1571 { |
|
1572 DEBUG( "core_server_c::get_power_save_settings()" ); |
|
1573 |
|
1574 settings = core_settings_m.power_save_settings(); |
|
1575 |
|
1576 return core_error_ok; |
|
1577 } |
|
1578 |
|
1579 // --------------------------------------------------------------------------- |
|
1580 // --------------------------------------------------------------------------- |
|
1581 // |
|
1582 core_error_e core_server_c::set_power_save_settings( |
|
1583 const core_power_save_settings_s& settings ) |
|
1584 { |
|
1585 DEBUG( "core_server_c::set_power_save_settings()" ); |
|
1586 |
|
1587 core_operation_base_c* command = new core_operation_set_power_save_settings_c( |
|
1588 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, settings ); |
|
1589 |
|
1590 queue_int_operation_and_run_next( command ); |
|
1591 |
|
1592 return core_error_ok; |
|
1593 } |
|
1594 |
|
1595 // --------------------------------------------------------------------------- |
|
1596 // --------------------------------------------------------------------------- |
|
1597 // |
|
1598 core_error_e core_server_c::get_current_ap_info( |
|
1599 core_ap_information_s& info ) |
|
1600 { |
|
1601 DEBUG( "core_server_c::get_current_ap_info()" ); |
|
1602 |
|
1603 if ( core_settings_m.is_connected() && |
|
1604 connection_data_m && |
|
1605 connection_data_m->current_ap_data() ) |
|
1606 { |
|
1607 info = core_tools_parser_c::get_ap_info( |
|
1608 connection_data_m->iap_data(), |
|
1609 *connection_data_m->current_ap_data() ); |
|
1610 |
|
1611 return core_error_ok; |
|
1612 } |
|
1613 |
|
1614 return core_error_not_connected; |
|
1615 } |
|
1616 |
|
1617 // --------------------------------------------------------------------------- |
|
1618 // --------------------------------------------------------------------------- |
|
1619 // |
|
1620 void core_server_c::get_roam_metrics( |
|
1621 core_roam_metrics_s& roam_metrics ) |
|
1622 { |
|
1623 DEBUG( "core_server_c::get_roam_metrics()" ); |
|
1624 |
|
1625 core_roam_metrics_c& metrics = get_core_settings().roam_metrics(); |
|
1626 |
|
1627 roam_metrics.connection_attempt_total_count = metrics.roam_attempt_count( core_roam_reason_initial_connect ); |
|
1628 roam_metrics.unsuccesfull_connection_attempt_count = |
|
1629 metrics.roam_attempt_failed_count( core_roam_failed_reason_timeout ) |
|
1630 + metrics.roam_attempt_failed_count( core_roam_failed_reason_ap_status_code ) |
|
1631 + metrics.roam_attempt_failed_count( core_roam_failed_reason_eapol_failure ) |
|
1632 + metrics.roam_attempt_failed_count( core_roam_failed_reason_other_failure ); |
|
1633 |
|
1634 roam_metrics.roaming_counter = metrics.roam_success_count(); |
|
1635 roam_metrics.coverage_loss_count = metrics.roam_attempt_count( core_roam_reason_bss_lost ); |
|
1636 |
|
1637 roam_metrics.last_roam_total_duration = metrics.roam_total_delay() / MILLISECONDS_FROM_MICROSECONDS; |
|
1638 roam_metrics.last_roam_data_path_broken_duration = metrics.roam_total_delay() / MILLISECONDS_FROM_MICROSECONDS; |
|
1639 |
|
1640 roam_metrics.last_roam_reason = core_roam_reason_none; |
|
1641 if ( get_connection_data() ) |
|
1642 { |
|
1643 roam_metrics.last_roam_reason = get_connection_data()->last_roam_reason(); |
|
1644 } |
|
1645 } |
|
1646 |
|
1647 // --------------------------------------------------------------------------- |
|
1648 // --------------------------------------------------------------------------- |
|
1649 // |
|
1650 core_error_e core_server_c::set_arp_filter( |
|
1651 const core_arp_filter_s& filter ) |
|
1652 { |
|
1653 DEBUG( "core_server_c::set_arp_filter()" ); |
|
1654 |
|
1655 core_operation_base_c* command = new core_operation_set_arp_filter_c( |
|
1656 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, filter ); |
|
1657 |
|
1658 queue_int_operation_and_run_next( command ); |
|
1659 |
|
1660 return core_error_ok; |
|
1661 } |
|
1662 |
|
1663 // --------------------------------------------------------------------------- |
|
1664 // --------------------------------------------------------------------------- |
|
1665 // |
|
1666 core_error_e core_server_c::configure_multicast_group( |
|
1667 bool_t join_group, |
|
1668 const core_mac_address_s& multicast_addr ) |
|
1669 { |
|
1670 DEBUG( "core_server_c::configure_multicast_group" ); |
|
1671 |
|
1672 core_operation_base_c* command = new core_operation_configure_multicast_group_c( |
|
1673 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, join_group, multicast_addr ); |
|
1674 |
|
1675 queue_int_operation_and_run_next( command ); |
|
1676 |
|
1677 return core_error_ok; |
|
1678 } |
|
1679 |
|
1680 // --------------------------------------------------------------------------- |
|
1681 // --------------------------------------------------------------------------- |
|
1682 // |
|
1683 core_error_e core_server_c::get_current_ac_traffic_info( |
|
1684 core_ac_traffic_information_s& info ) |
|
1685 { |
|
1686 DEBUG( "core_server_c::get_current_ac_traffic_info()" ); |
|
1687 |
|
1688 if ( core_settings_m.is_connected() && |
|
1689 connection_data_m && |
|
1690 connection_data_m->current_ap_data() ) |
|
1691 { |
|
1692 info.status_for_voice = connection_data_m->ac_traffic_status( |
|
1693 core_access_class_voice ); |
|
1694 info.status_for_video = connection_data_m->ac_traffic_status( |
|
1695 core_access_class_video ); |
|
1696 info.status_for_best_effort = connection_data_m->ac_traffic_status( |
|
1697 core_access_class_best_effort ); |
|
1698 info.status_for_background = connection_data_m->ac_traffic_status( |
|
1699 core_access_class_background ); |
|
1700 info.mode_for_voice = connection_data_m->ac_traffic_mode( |
|
1701 core_access_class_voice ); |
|
1702 info.mode_for_video = connection_data_m->ac_traffic_mode( |
|
1703 core_access_class_video ); |
|
1704 info.mode_for_best_effort = connection_data_m->ac_traffic_mode( |
|
1705 core_access_class_best_effort ); |
|
1706 info.mode_for_background = connection_data_m->ac_traffic_mode( |
|
1707 core_access_class_background ); |
|
1708 |
|
1709 return core_error_ok; |
|
1710 } |
|
1711 |
|
1712 return core_error_not_connected; |
|
1713 } |
|
1714 |
|
1715 // --------------------------------------------------------------------------- |
|
1716 // --------------------------------------------------------------------------- |
|
1717 // |
|
1718 void core_server_c::request_complete( |
|
1719 u32_t /* request_id */, |
|
1720 core_error_e status ) |
|
1721 { |
|
1722 DEBUG( "core_server_c::request_complete()" ); |
|
1723 |
|
1724 core_operation_base_c* operation = queue_m.first(); |
|
1725 |
|
1726 ASSERT( operation ); |
|
1727 ASSERT( operation->is_executing() ); |
|
1728 |
|
1729 core_error_e ret = operation->continue_operation( status ); |
|
1730 if ( ret == core_error_request_pending ) |
|
1731 { |
|
1732 DEBUG( "core_server_c::request_complete() - operation is not done yet" ); |
|
1733 return; |
|
1734 } |
|
1735 |
|
1736 DEBUG1( "core_server_c::request_complete() - operation completed with code %u", |
|
1737 ret ); |
|
1738 |
|
1739 if ( operation->request_id() != REQUEST_ID_CORE_INTERNAL ) |
|
1740 { |
|
1741 callback_m.request_complete( |
|
1742 operation->request_id(), |
|
1743 ret ); |
|
1744 } |
|
1745 |
|
1746 queue_m.remove( operation ); |
|
1747 delete operation; |
|
1748 operation = NULL; |
|
1749 |
|
1750 schedule_operation(); |
|
1751 } |
|
1752 |
|
1753 // --------------------------------------------------------------------------- |
|
1754 // --------------------------------------------------------------------------- |
|
1755 // |
|
1756 void core_server_c::cancel_request( |
|
1757 u32_t request_id ) |
|
1758 { |
|
1759 DEBUG( "core_server_c::cancel_request()" ); |
|
1760 |
|
1761 // Find correct operation |
|
1762 core_operation_base_c* operation = queue_m.first(); |
|
1763 while ( operation ) |
|
1764 { |
|
1765 if ( operation->request_id() == request_id ) |
|
1766 { |
|
1767 break; |
|
1768 } |
|
1769 operation = queue_m.next(); |
|
1770 } |
|
1771 |
|
1772 if ( !operation ) |
|
1773 { |
|
1774 DEBUG( "core_server_c::cancel_request() - operation not found" ); |
|
1775 return; |
|
1776 } |
|
1777 |
|
1778 if ( operation->is_executing() ) |
|
1779 { |
|
1780 // Let operation handle it's own cancelling |
|
1781 operation->user_cancel_operation( true_t ); // Using graceful cancel |
|
1782 } |
|
1783 else |
|
1784 { |
|
1785 // When operation is not yet running, we don't need to ask for it's permissions... |
|
1786 queue_m.remove( operation ); |
|
1787 delete operation; |
|
1788 operation = NULL; |
|
1789 |
|
1790 // Use null operation for completing correctly |
|
1791 operation = new core_operation_null_c( |
|
1792 request_id, this, &drivers_m, &callback_m, core_error_cancel ); |
|
1793 queue_ext_operation_and_run_next( operation, request_id ); |
|
1794 } |
|
1795 } |
|
1796 |
|
1797 // --------------------------------------------------------------------------- |
|
1798 // --------------------------------------------------------------------------- |
|
1799 // |
|
1800 void core_server_c::receive_frame( |
|
1801 core_frame_type_e frame_type, |
|
1802 const u16_t frame_length, |
|
1803 const u8_t* const frame_data, |
|
1804 u8_t frame_rcpi ) |
|
1805 { |
|
1806 DEBUG( "core_server_c::receive_frame()" ); |
|
1807 |
|
1808 DEBUG1( "core_server_c::receive_frame() - frame type: %u", frame_type ); |
|
1809 DEBUG1( "core_server_c::receive_frame() - frame (%u bytes): ", |
|
1810 frame_length ); |
|
1811 DEBUG_BUFFER( |
|
1812 frame_length, |
|
1813 frame_data ); |
|
1814 |
|
1815 if ( frame_type == core_frame_type_ethernet ) |
|
1816 { |
|
1817 core_frame_ethernet_c* frame = core_frame_ethernet_c::instance( |
|
1818 frame_length, |
|
1819 frame_data, |
|
1820 false_t ); |
|
1821 if ( frame ) |
|
1822 { |
|
1823 /** |
|
1824 * Currently all Ethernet frames are for EAPOL. |
|
1825 */ |
|
1826 |
|
1827 /** |
|
1828 * If an Ethernet frame is received during a roam, store it |
|
1829 * for later use. |
|
1830 */ |
|
1831 if ( get_connection_data()->is_eapol_connecting() ) |
|
1832 { |
|
1833 DEBUG( "core_server_c::receive_frame() - (re-)association in progress, storing EAPOL frame" ); |
|
1834 |
|
1835 (void)eapol_m->store_frame( *frame ); |
|
1836 } |
|
1837 /** |
|
1838 * Frames are discarded during disconnect. |
|
1839 */ |
|
1840 else if ( get_connection_data()->is_disconnecting() ) |
|
1841 { |
|
1842 DEBUG( "core_server_c::receive_frame() - disconnect in progress, discarding EAPOL frame" ); |
|
1843 } |
|
1844 /** |
|
1845 * Otherwise send it to EAPOL for processing. |
|
1846 */ |
|
1847 else if ( eapol_m ) |
|
1848 { |
|
1849 // Clear stored frame so that it is not sent later. |
|
1850 eapol_m->clear_stored_frame(); |
|
1851 |
|
1852 (void)eapol_m->process_frame( *frame ); |
|
1853 } |
|
1854 else |
|
1855 { |
|
1856 DEBUG( "core_server_c::receive_frame() - EAPOL not instantiated, discarding EAPOL frame" ); |
|
1857 } |
|
1858 |
|
1859 delete frame; |
|
1860 frame = NULL; |
|
1861 } |
|
1862 |
|
1863 return; |
|
1864 } |
|
1865 |
|
1866 /** |
|
1867 * WPX frames are handled separately. |
|
1868 */ |
|
1869 if ( wpx_adaptation_m->handle_wpx_frame( |
|
1870 frame_type, |
|
1871 frame_length, |
|
1872 frame_data ) ) |
|
1873 { |
|
1874 return; |
|
1875 } |
|
1876 |
|
1877 /** |
|
1878 * Offer dot11 and echo test frames to the registered frame handler. |
|
1879 */ |
|
1880 bool_t is_handled( false_t ); |
|
1881 |
|
1882 if ( frame_type == core_frame_type_dot11 && |
|
1883 frame_handler_m ) |
|
1884 { |
|
1885 core_frame_dot11_c* frame = core_frame_dot11_c::instance( |
|
1886 frame_length, |
|
1887 frame_data, |
|
1888 false_t ); |
|
1889 if ( frame && |
|
1890 frame_handler_m->receive_frame( frame, frame_rcpi ) ) |
|
1891 { |
|
1892 DEBUG( "core_server_c::receive_frame() - dot11 frame handled by the operation" ); |
|
1893 |
|
1894 is_handled = true_t; |
|
1895 } |
|
1896 |
|
1897 delete frame; |
|
1898 frame = NULL; |
|
1899 } |
|
1900 else if ( frame_type == core_frame_type_test && |
|
1901 frame_handler_m ) |
|
1902 { |
|
1903 core_frame_ethernet_c* frame = core_frame_ethernet_c::instance( |
|
1904 frame_length, |
|
1905 frame_data, |
|
1906 false_t ); |
|
1907 if ( frame ) |
|
1908 { |
|
1909 core_frame_echo_test_c* test_frame = core_frame_echo_test_c::instance( |
|
1910 *frame ); |
|
1911 if ( test_frame && |
|
1912 frame_handler_m->receive_test_frame( test_frame, frame_rcpi ) ) |
|
1913 { |
|
1914 DEBUG( "core_server_c::receive_frame() - echo test frame handled by the operation" ); |
|
1915 |
|
1916 is_handled = true_t; |
|
1917 } |
|
1918 |
|
1919 delete test_frame; |
|
1920 test_frame = NULL; |
|
1921 |
|
1922 delete frame; |
|
1923 frame = NULL; |
|
1924 } |
|
1925 } |
|
1926 |
|
1927 /** |
|
1928 * All other frames are processed in an operation. |
|
1929 */ |
|
1930 if ( !is_handled ) |
|
1931 { |
|
1932 DEBUG( "core_server_c::receive_frame() - queueing the frame for processing" ); |
|
1933 |
|
1934 core_operation_base_c* command = new core_operation_handle_frame_c( |
|
1935 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, |
|
1936 frame_type, frame_length, frame_data ); |
|
1937 |
|
1938 queue_int_operation_and_run_next( command ); |
|
1939 } |
|
1940 } |
|
1941 |
|
1942 // --------------------------------------------------------------------------- |
|
1943 // --------------------------------------------------------------------------- |
|
1944 // |
|
1945 void core_server_c::notify( |
|
1946 core_am_indication_e indication ) |
|
1947 { |
|
1948 DEBUG( "core_server_c::notify()" ); |
|
1949 |
|
1950 #ifdef _DEBUG |
|
1951 switch ( indication ) |
|
1952 { |
|
1953 case core_am_indication_wlan_media_disconnect: |
|
1954 DEBUG( "core_server_c::notify() - core_am_indication_wlan_media_disconnect" ); |
|
1955 break; |
|
1956 case core_am_indication_wlan_hw_failed: |
|
1957 DEBUG( "core_server_c::notify() - core_am_indication_wlan_hw_failed" ); |
|
1958 break; |
|
1959 case core_am_indication_wlan_beacon_lost: |
|
1960 DEBUG( "core_server_c::notify() - core_am_indication_wlan_beacon_lost" ); |
|
1961 break; |
|
1962 case core_am_indication_wlan_power_mode_failure: |
|
1963 DEBUG( "core_server_c::notify() - core_am_indication_wlan_power_mode_failure" ); |
|
1964 break; |
|
1965 case core_am_indication_wlan_tx_fail: |
|
1966 DEBUG( "core_server_c::notify() - core_am_indication_wlan_tx_fail" ); |
|
1967 break; |
|
1968 case core_am_indication_wlan_bss_regained: |
|
1969 DEBUG( "core_server_c::notify() - core_am_indication_wlan_bss_regained" ); |
|
1970 break; |
|
1971 case core_am_indication_wlan_wep_decrypt_failure: |
|
1972 DEBUG( "core_server_c::notify() - core_am_indication_wlan_wep_decrypt_failure" ); |
|
1973 break; |
|
1974 case core_am_indication_wlan_pairwise_key_mic_failure: |
|
1975 DEBUG( "core_server_c::notify() - core_am_indication_wlan_pairwise_key_mic_failure" ); |
|
1976 break; |
|
1977 case core_am_indication_wlan_group_key_mic_failure: |
|
1978 DEBUG( "core_server_c::notify() - core_am_indication_wlan_group_key_mic_failure" ); |
|
1979 break; |
|
1980 case core_am_indication_wlan_scan_complete: |
|
1981 DEBUG( "core_server_c::notify() - core_am_indication_wlan_scan_complete" ); |
|
1982 break; |
|
1983 case core_am_indication_wlan_rcpi_trigger: |
|
1984 DEBUG( "core_server_c::notify() - core_am_indication_wlan_rcpi_trigger" ); |
|
1985 break; |
|
1986 case core_am_indication_wlan_signal_loss_prediction: |
|
1987 DEBUG( "core_server_c::notify() - core_am_indication_wlan_signal_loss_prediction" ); |
|
1988 break; |
|
1989 case core_am_indication_wlan_power_save_test_trigger: |
|
1990 DEBUG( "core_server_c::notify() - core_am_indication_wlan_power_save_test_trigger" ); |
|
1991 break; |
|
1992 case core_am_indication_os_power_standby: |
|
1993 DEBUG( "core_server_c::notify() - core_am_indication_os_power_standby" ); |
|
1994 break; |
|
1995 case core_am_indication_bt_connection_established: |
|
1996 DEBUG( "core_server_c::notify() - core_am_indication_bt_connection_established" ); |
|
1997 break; |
|
1998 case core_am_indication_bt_connection_disconnected: |
|
1999 DEBUG( "core_server_c::notify() - core_am_indication_bt_connection_disconnected" ); |
|
2000 break; |
|
2001 case core_am_indication_voice_call_on: |
|
2002 DEBUG( "core_server_c::notify() - core_am_indication_voice_call_on" ); |
|
2003 break; |
|
2004 case core_am_indication_voice_call_off: |
|
2005 DEBUG( "core_server_c::notify() - core_am_indication_voice_call_off" ); |
|
2006 break; |
|
2007 default: |
|
2008 break; |
|
2009 } |
|
2010 #endif // _DEBUG |
|
2011 |
|
2012 if ( event_handler_m && |
|
2013 event_handler_m->notify( indication ) ) |
|
2014 { |
|
2015 DEBUG( "core_server_c::notify() - indication handled by the operation" ); |
|
2016 |
|
2017 return; |
|
2018 } |
|
2019 |
|
2020 switch ( indication ) |
|
2021 { |
|
2022 case core_am_indication_os_power_standby: |
|
2023 { |
|
2024 /** |
|
2025 * Cancel all operations including the currently executing one. |
|
2026 */ |
|
2027 cancel_all_operations( true_t ); |
|
2028 |
|
2029 /** |
|
2030 * Force an immediate driver unload. |
|
2031 */ |
|
2032 queue_unload_drivers(); |
|
2033 |
|
2034 break; |
|
2035 } |
|
2036 case core_am_indication_wlan_hw_failed: |
|
2037 { |
|
2038 /** |
|
2039 * Cancel all operations including the currently executing one. |
|
2040 */ |
|
2041 cancel_all_operations( false_t ); |
|
2042 |
|
2043 /** |
|
2044 * Force an immediate driver unload. |
|
2045 */ |
|
2046 queue_unload_drivers(); |
|
2047 |
|
2048 break; |
|
2049 } |
|
2050 case core_am_indication_wlan_media_disconnect: |
|
2051 { |
|
2052 /** |
|
2053 * If the current operation is connect, handle_bss_lost or protected_setup, the indication |
|
2054 * is silently ignored. Otherwise this indication is handled like a BSS lost. |
|
2055 */ |
|
2056 core_operation_base_c* op = queue_m.first(); |
|
2057 if( op && |
|
2058 op->is_executing() && |
|
2059 ( op->operation_type() == core_operation_handle_bss_lost || |
|
2060 op->operation_type() == core_operation_connect || |
|
2061 op->operation_type() == core_operation_protected_setup ) ) |
|
2062 { |
|
2063 DEBUG( "core_server_c::notify() - ignoring indication" ); |
|
2064 } |
|
2065 else |
|
2066 { |
|
2067 schedule_roam( |
|
2068 core_operation_handle_bss_lost_c::core_bss_lost_reason_media_disconnect ); |
|
2069 } |
|
2070 |
|
2071 break; |
|
2072 } |
|
2073 case core_am_indication_wlan_beacon_lost: |
|
2074 /** Falls through on purpose. */ |
|
2075 case core_am_indication_wlan_power_mode_failure: |
|
2076 /** Falls through on purpose. */ |
|
2077 case core_am_indication_wlan_tx_fail: |
|
2078 { |
|
2079 // bss_lost is only handled in infrastructure mode |
|
2080 if ( connection_data_m->iap_data().operating_mode() == core_operating_mode_infrastructure ) |
|
2081 { |
|
2082 // send an indication to adaptation |
|
2083 callback_m.notify( |
|
2084 core_notification_bss_lost, |
|
2085 0, |
|
2086 NULL ); |
|
2087 |
|
2088 schedule_roam( |
|
2089 core_operation_handle_bss_lost_c::core_bss_lost_reason_bss_lost ); |
|
2090 } |
|
2091 |
|
2092 break; |
|
2093 } |
|
2094 case core_am_indication_wlan_pairwise_key_mic_failure: |
|
2095 { |
|
2096 DEBUG( "core_server_c::notify() - a pairwise MIC failure has occured" ); |
|
2097 |
|
2098 mic_failure( false_t ); |
|
2099 |
|
2100 break; |
|
2101 } |
|
2102 case core_am_indication_wlan_group_key_mic_failure: |
|
2103 { |
|
2104 DEBUG( "core_server_c::notify() - a group MIC failure has occured" ); |
|
2105 |
|
2106 mic_failure( true_t ); |
|
2107 |
|
2108 break; |
|
2109 } |
|
2110 case core_am_indication_wlan_bss_regained: |
|
2111 // Do nothing. |
|
2112 break; |
|
2113 case core_am_indication_wlan_wep_decrypt_failure: |
|
2114 // Do nothing. |
|
2115 break; |
|
2116 case core_am_indication_bt_connection_established: |
|
2117 { |
|
2118 core_settings_m.set_bt_connection_established( true_t ); |
|
2119 core_operation_base_c* command = new core_operation_update_rxtx_parameters_c( |
|
2120 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m ); |
|
2121 |
|
2122 queue_int_operation_and_run_next( command ); |
|
2123 |
|
2124 break; |
|
2125 } |
|
2126 case core_am_indication_bt_connection_disconnected: |
|
2127 { |
|
2128 core_settings_m.set_bt_connection_established( false_t ); |
|
2129 core_operation_base_c* command = new core_operation_update_rxtx_parameters_c( |
|
2130 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m ); |
|
2131 |
|
2132 queue_int_operation_and_run_next( command ); |
|
2133 |
|
2134 break; |
|
2135 } |
|
2136 case core_am_indication_wlan_scan_complete: |
|
2137 { |
|
2138 DEBUG( "core_server_c::notify() - scan complete received without pending scan operations" ); |
|
2139 ASSERT( false_t ); |
|
2140 |
|
2141 break; |
|
2142 } |
|
2143 case core_am_indication_wlan_rcpi_trigger: |
|
2144 { |
|
2145 if ( !is_operation_in_queue_with_type( core_operation_check_rcpi ) && |
|
2146 !is_operation_in_queue_with_type( core_operation_handle_bss_lost ) ) |
|
2147 { |
|
2148 // send an indication to adaptation |
|
2149 callback_m.notify( |
|
2150 core_notification_rcpi_roam_attempt_started, |
|
2151 0, |
|
2152 NULL ); |
|
2153 |
|
2154 // create operation to handle the indication |
|
2155 core_operation_base_c* command = new core_operation_check_rcpi_c( |
|
2156 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, core_operation_check_rcpi_c::core_rcpi_check_reason_rcpi_trigger ); |
|
2157 |
|
2158 queue_int_operation_and_run_next( command ); |
|
2159 } |
|
2160 else |
|
2161 { |
|
2162 DEBUG( "core_server_c::notify() - roaming operation already in queue " ); |
|
2163 } |
|
2164 |
|
2165 break; |
|
2166 } |
|
2167 case core_am_indication_wlan_signal_loss_prediction: |
|
2168 { |
|
2169 if ( !is_operation_in_queue_with_type( core_operation_check_rcpi ) && |
|
2170 !is_operation_in_queue_with_type( core_operation_handle_bss_lost ) ) |
|
2171 { |
|
2172 // send an indication to adaptation |
|
2173 /* |
|
2174 callback_m.notify( |
|
2175 core_notification_rcpi_roam_attempt_started, |
|
2176 0, |
|
2177 NULL ); |
|
2178 */ |
|
2179 |
|
2180 // create operation to handle the indication |
|
2181 /* |
|
2182 core_operation_base_c* command = new core_operation_check_rcpi_c( |
|
2183 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, core_operation_check_rcpi_c::core_rcpi_check_reason_signal_loss_prediction ); |
|
2184 |
|
2185 queue_int_operation_and_run_next( command, LIST_HIGH_PRIORITY ); |
|
2186 */ |
|
2187 } |
|
2188 else |
|
2189 { |
|
2190 DEBUG( "core_server_c::notify() - roaming operation already in queue " ); |
|
2191 } |
|
2192 |
|
2193 break; |
|
2194 } |
|
2195 case core_am_indication_wlan_power_save_test_trigger: |
|
2196 { |
|
2197 DEBUG( "core_server_c::notify() - scheduling a power save test" ); |
|
2198 |
|
2199 core_operation_base_c* command = new core_operation_power_save_test_c( |
|
2200 REQUEST_ID_CORE_INTERNAL, |
|
2201 this, |
|
2202 &drivers_m, |
|
2203 &callback_m ); |
|
2204 |
|
2205 queue_int_operation_and_run_next( command ); |
|
2206 |
|
2207 break; |
|
2208 } |
|
2209 case core_am_indication_voice_call_on: |
|
2210 { |
|
2211 DEBUG( "core_server_c::notify() - voice call is on" ); |
|
2212 connection_data_m->set_voice_call_state( true_t ); |
|
2213 break; |
|
2214 } |
|
2215 case core_am_indication_voice_call_off: |
|
2216 { |
|
2217 DEBUG( "core_server_c::notify() - voice call is off" ); |
|
2218 connection_data_m->set_voice_call_state( false_t ); |
|
2219 break; |
|
2220 } |
|
2221 case core_am_indication_wlan_ap_ps_mode_error: |
|
2222 // Do nothing. |
|
2223 break; |
|
2224 default: |
|
2225 DEBUG( "core_server_c::notify() - unknown indication" ); |
|
2226 ASSERT( false_t ); |
|
2227 break; |
|
2228 } |
|
2229 } |
|
2230 |
|
2231 // --------------------------------------------------------------------------- |
|
2232 // --------------------------------------------------------------------------- |
|
2233 // |
|
2234 void core_server_c::schedule_operation() |
|
2235 { |
|
2236 DEBUG( "core_server_c::schedule_operation()" ); |
|
2237 |
|
2238 core_operation_base_c* operation = queue_m.first(); |
|
2239 |
|
2240 DEBUG1( "core_server_c::schedule_operation() - %u operation(s) in the queue", |
|
2241 queue_m.count()); |
|
2242 |
|
2243 #ifdef _DEBUG |
|
2244 if( operation && operation->is_executing() ) |
|
2245 { |
|
2246 DEBUG2("core_server_c::schedule_operation() - operation 0x%08X (type %u) is executing", |
|
2247 operation, operation->operation_type() ); |
|
2248 } |
|
2249 #endif // _DEBUG |
|
2250 |
|
2251 if( !operation && |
|
2252 core_settings_m.connection_state() == core_connection_state_notconnected && |
|
2253 core_settings_m.is_driver_loaded() && |
|
2254 !driver_unload_timer_m->is_active() ) |
|
2255 { |
|
2256 // If 1) no more operations and |
|
2257 // 2) no connection exists and |
|
2258 // 3) drivers are loaded and |
|
2259 // 4) driver not already active, |
|
2260 // start unload timer |
|
2261 DEBUG( "core_server_c::schedule_operation() - starting unload timer" ); |
|
2262 schedule_unload_timer( |
|
2263 device_settings_m.unload_driver_timer * SECONDS_FROM_MICROSECONDS ); |
|
2264 |
|
2265 return; |
|
2266 } |
|
2267 |
|
2268 if ( operation && |
|
2269 !operation->is_executing() && |
|
2270 !queue_timer_m->is_active() ) |
|
2271 { |
|
2272 DEBUG( "core_server_c::schedule_operation() - scheduling a new operation" ); |
|
2273 queue_timer_m->start( CORE_TIMER_IMMEDIATELY ); |
|
2274 } |
|
2275 } |
|
2276 |
|
2277 // --------------------------------------------------------------------------- |
|
2278 // --------------------------------------------------------------------------- |
|
2279 // |
|
2280 bool_t core_server_c::is_cm_active() |
|
2281 { |
|
2282 return !cm_timer_m.is_wpa_allowed(); |
|
2283 } |
|
2284 |
|
2285 // --------------------------------------------------------------------------- |
|
2286 // --------------------------------------------------------------------------- |
|
2287 // |
|
2288 void core_server_c::queue_ext_operation_and_run_next( |
|
2289 core_operation_base_c* operation, |
|
2290 u32_t request_id ) |
|
2291 { |
|
2292 DEBUG1( "core_server_c::queue_ext_operation_and_run_next() - request id %u", |
|
2293 request_id ); |
|
2294 if( !operation ) |
|
2295 { |
|
2296 DEBUG( "core_server_c::queue_ext_operation_and_run_next() - no operation, completing request." ); |
|
2297 callback_m.request_complete( request_id, core_error_no_memory ); |
|
2298 } |
|
2299 else if ( operation->is_flags( core_operation_base_c::core_base_flag_only_one_instance ) && |
|
2300 is_operation_in_queue_with_type( operation->operation_type() ) ) |
|
2301 { |
|
2302 DEBUG( "core_server_c::queue_ext_operation_and_run_next() - only one instance allowed in the operation queue, completing request" ); |
|
2303 callback_m.request_complete( request_id, core_error_ok ); |
|
2304 |
|
2305 delete operation; |
|
2306 operation = NULL; |
|
2307 } |
|
2308 else |
|
2309 { |
|
2310 core_error_e ret = queue_m.append( operation ); |
|
2311 if ( ret != core_error_ok ) |
|
2312 { |
|
2313 DEBUG1( "core_server_c::queue_ext_operation_and_run_next() - unable to queue the request (%u)", |
|
2314 ret ); |
|
2315 callback_m.request_complete( request_id, ret ); |
|
2316 |
|
2317 delete operation; |
|
2318 operation = NULL; |
|
2319 } |
|
2320 } |
|
2321 |
|
2322 schedule_operation(); |
|
2323 } |
|
2324 |
|
2325 // --------------------------------------------------------------------------- |
|
2326 // --------------------------------------------------------------------------- |
|
2327 // |
|
2328 void core_server_c::queue_timer_expired( void* this_ptr ) |
|
2329 { |
|
2330 DEBUG( "core_server_c::queue_timer_expired()" ); |
|
2331 core_server_c* self = static_cast<core_server_c*>( this_ptr ); |
|
2332 |
|
2333 core_operation_base_c* operation = self->queue_m.first(); |
|
2334 if( !operation ) |
|
2335 { |
|
2336 /** |
|
2337 * This shouldn't normally happen but it can happen if we have |
|
2338 * schedule an operation and cancel it before it has a chance to |
|
2339 * start executing. |
|
2340 */ |
|
2341 |
|
2342 return; |
|
2343 } |
|
2344 |
|
2345 ASSERT( operation ); |
|
2346 ASSERT( !operation->is_executing() ); |
|
2347 |
|
2348 // Set operation priority in the queue to maximum |
|
2349 self->queue_m.remove( operation ); |
|
2350 self->queue_m.append( operation, LIST_TOP_PRIORITY ); |
|
2351 |
|
2352 // If operation says it needs drivers, stop driver unload timer |
|
2353 if( operation->is_flags( core_operation_base_c::core_base_flag_drivers_needed ) && |
|
2354 self->driver_unload_timer_m->is_active() ) |
|
2355 { |
|
2356 DEBUG( "core_server_c::queue_timer_expired() - stopping unload timer" ); |
|
2357 self->cancel_unload_timer(); |
|
2358 } |
|
2359 |
|
2360 core_error_e ret = operation->start_operation(); |
|
2361 if( ret == core_error_request_pending ) |
|
2362 { |
|
2363 DEBUG( "core_server_c::queue_timer_expired() - operation is not done yet" ); |
|
2364 return; |
|
2365 } |
|
2366 |
|
2367 DEBUG1( "core_server_c::queue_timer_expired() - operation completed with code %u", |
|
2368 ret ); |
|
2369 |
|
2370 if ( operation->request_id() != REQUEST_ID_CORE_INTERNAL ) |
|
2371 { |
|
2372 self->callback_m.request_complete( |
|
2373 operation->request_id(), |
|
2374 ret ); |
|
2375 } |
|
2376 |
|
2377 self->queue_m.remove( operation ); |
|
2378 delete operation; |
|
2379 operation = NULL; |
|
2380 |
|
2381 self->schedule_operation(); |
|
2382 } |
|
2383 |
|
2384 // --------------------------------------------------------------------------- |
|
2385 // --------------------------------------------------------------------------- |
|
2386 // |
|
2387 void core_server_c::unload_timer_expired( void* this_ptr ) |
|
2388 { |
|
2389 DEBUG("core_server_c::unload_timer_expired()"); |
|
2390 core_server_c* self = static_cast<core_server_c*>( this_ptr ); |
|
2391 |
|
2392 /** |
|
2393 * Due to configurable unload timer value and different platform timing issues |
|
2394 * it's possible that a new operation has been added to the operation queue |
|
2395 * AFTER this timer was started but the queue timer has not yet been triggered. |
|
2396 * |
|
2397 * Therefore we have to abort driver unloading if there's an operation in the |
|
2398 * queue that requires drivers. |
|
2399 */ |
|
2400 if( self->is_operation_in_queue_with_flags( |
|
2401 core_operation_base_c::core_base_flag_drivers_needed ) ) |
|
2402 { |
|
2403 DEBUG( "core_server_c::unload_timer_expired() - operation in queue, aborting driver unloading" ); |
|
2404 |
|
2405 return; |
|
2406 } |
|
2407 |
|
2408 self->queue_unload_drivers(); |
|
2409 } |
|
2410 |
|
2411 // --------------------------------------------------------------------------- |
|
2412 // --------------------------------------------------------------------------- |
|
2413 // |
|
2414 void core_server_c::mic_failure( |
|
2415 bool_t is_group_key_fail ) |
|
2416 { |
|
2417 DEBUG( "core_server_c::mic_failure()" ); |
|
2418 |
|
2419 core_connection_security_mode_e mode = core_connection_security_mode_open; |
|
2420 |
|
2421 if( core_error_ok != get_current_security_mode( mode ) ) |
|
2422 { |
|
2423 DEBUG( "core_server_c::mic_failure() - not connected, ignoring mic failure" ); |
|
2424 return; |
|
2425 } |
|
2426 |
|
2427 if( mode != core_connection_security_mode_wpa && |
|
2428 mode != core_connection_security_mode_wpa_psk ) |
|
2429 { |
|
2430 DEBUG( "core_server_c::mic_failure() - security mode not WPA, ignoring mic failure" ); |
|
2431 return; |
|
2432 } |
|
2433 |
|
2434 if( is_group_key_fail ) |
|
2435 { |
|
2436 if( connection_data_m->current_ap_data() != NULL && |
|
2437 connection_data_m->current_ap_data()->best_group_cipher() != core_cipher_suite_tkip ) |
|
2438 { |
|
2439 DEBUG( "core_server_c::mic_failure() - TKIP not the best group cipher, ignoring mic failure" ); |
|
2440 return; |
|
2441 } |
|
2442 } |
|
2443 else |
|
2444 { |
|
2445 if( connection_data_m->current_ap_data() != NULL && |
|
2446 connection_data_m->current_ap_data()->best_pairwise_cipher() != core_cipher_suite_tkip ) |
|
2447 { |
|
2448 DEBUG( "core_server_c::mic_failure() - TKIP not the best pairwise cipher, ignoring mic failure" ); |
|
2449 return; |
|
2450 } |
|
2451 } |
|
2452 |
|
2453 const core_mac_address_s bssid( |
|
2454 connection_data_m->current_ap_data()->bssid() ); |
|
2455 |
|
2456 cm_timer_m.mic_failure(); |
|
2457 |
|
2458 network_id_c network_id( |
|
2459 const_cast<u8_t*>( &bssid.addr[0] ), |
|
2460 MAC_ADDR_LEN, |
|
2461 &own_mac_addr_m.addr[0], |
|
2462 MAC_ADDR_LEN, |
|
2463 eapol_m->ethernet_type() ); |
|
2464 |
|
2465 ASSERT( eapol_m ); |
|
2466 (void)eapol_m->tkip_mic_failure( |
|
2467 &network_id, |
|
2468 !cm_timer_m.is_wpa_allowed() ? true_t : false_t, |
|
2469 is_group_key_fail ? wlan_eapol_if_eapol_tkip_mic_failure_type_group_key : |
|
2470 wlan_eapol_if_eapol_tkip_mic_failure_type_pairwise_key ); |
|
2471 |
|
2472 |
|
2473 if ( !cm_timer_m.is_wpa_allowed() ) |
|
2474 { |
|
2475 DEBUG( "core_server_c::mic_failure() - two MIC failures within 60 seconds, disconnecting" ); |
|
2476 |
|
2477 core_operation_base_c* command = new core_operation_release_c( |
|
2478 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m, core_release_reason_tkip_mic_failure ); |
|
2479 |
|
2480 queue_int_operation_and_run_next( command ); |
|
2481 } |
|
2482 } |
|
2483 |
|
2484 // --------------------------------------------------------------------------- |
|
2485 // --------------------------------------------------------------------------- |
|
2486 // |
|
2487 void core_server_c::queue_unload_drivers() |
|
2488 { |
|
2489 DEBUG( "core_server_c::queue_unload_drivers()" ); |
|
2490 |
|
2491 core_operation_base_c* command = new core_operation_unload_drivers_c( |
|
2492 REQUEST_ID_CORE_INTERNAL, this, &drivers_m, &callback_m ); |
|
2493 |
|
2494 queue_int_operation_and_run_next( command ); |
|
2495 } |