00001
00013 #include "sm_task.h"
00014 #include "co_endian.h"
00015 #include "scanu_task.h"
00016 #include "scanu.h"
00017 #include "sm.h"
00018 #include "me_utils.h"
00019 #include "mac_frame.h"
00020
00021 #include "ke_timer.h"
00022 #include "mac.h"
00023 #include "mm_task.h"
00024 #include "me.h"
00025 #include "me_mgmtframe.h"
00026 #include "mm.h"
00027 #include "vif_mgmt.h"
00028 #include "sta_mgmt.h"
00029 #include "rxu_task.h"
00030 #include "ps.h"
00031
00048 static int
00049 sm_connect_req_handler(ke_msg_id_t const msgid,
00050 struct sm_connect_req const *param,
00051 ke_task_id_t const dest_id,
00052 ke_task_id_t const src_id)
00053 {
00054 struct mac_addr const *bssid = NULL;
00055 struct mac_chan_def const *chan = NULL;
00056 uint8_t status = CO_BUSY;
00057 int msg_status = KE_MSG_CONSUMED;
00058 struct sm_connect_cfm *cfm;
00059
00060 do
00061 {
00062 struct vif_info_tag *vif = &vif_info_tab[param->vif_idx];
00063
00064 if (ke_state_get(TASK_SM) == SM_DISCONNECTING)
00065 return (KE_MSG_SAVED);
00066
00067
00068 cfm = KE_MSG_ALLOC(SM_CONNECT_CFM, src_id, dest_id, sm_connect_cfm);
00069
00070
00071 if (ke_state_get(TASK_SM) != SM_IDLE)
00072 {
00073 status = CO_BUSY;
00074 break;
00075 }
00076
00077
00078 if (((vif->type != VIF_STA) || (vif->active)) && (param->auth_type != MAC_AUTH_ALGO_FT))
00079 {
00080 status = CO_OP_IN_PROGRESS;
00081 break;
00082 }
00083
00084 if (param->auth_type != MAC_AUTH_ALGO_FT)
00085 {
00086
00087
00088 ASSERT_ERR(vif->u.sta.ap_id == INVALID_STA_IDX);
00089 ASSERT_ERR(vif->chan_ctxt == NULL);
00090 }
00091
00092 if ((param->auth_type == MAC_AUTH_ALGO_SAE) &&
00093 (sm_get_rsnie_pmkid_count(CPU2HW(param->ie_buf), param->ie_len) > 0))
00094 {
00095 uint8_t *update_auth_type = (uint8_t *)¶m->auth_type;
00096
00097
00098
00099
00100 *update_auth_type = MAC_AUTH_ALGO_OPEN;
00101 }
00102
00103
00104 sm_env.connect_param = param;
00105
00106
00107 sm_env.connect_ind = KE_MSG_ALLOC(SM_CONNECT_IND, src_id, dest_id, sm_connect_ind);
00108
00109
00110 sm_env.ft_over_ds = 0;
00111
00112
00113 if (param->auth_type == MAC_AUTH_ALGO_FT)
00114 {
00115 PROF_FT_OVER_DS_REQ_SET();
00116 sm_env.ft_over_ds = 1;
00117 memcpy(&sm_env.ft_old_bssid, &vif_info_tab[param->vif_idx].bssid, sizeof(sm_env.ft_old_bssid));
00118 ke_state_set(TASK_SM, SM_DISCONNECTING);
00119 sm_disconnect_process(&vif_info_tab[param->vif_idx], 0);
00120 status = CO_OK;
00121 msg_status = KE_MSG_NO_FREE;
00122 PROF_FT_OVER_DS_REQ_CLR();
00123 break;
00124 }
00125
00126
00127 sm_get_bss_params(&bssid, &chan);
00128
00129
00130 if (bssid && chan)
00131 {
00132 sm_join_bss(bssid, chan, false);
00133 }
00134 else
00135 {
00136 sm_scan_bss(bssid, chan);
00137 }
00138
00139
00140 status = CO_OK;
00141 msg_status = KE_MSG_NO_FREE;
00142 } while(0);
00143
00144
00145 cfm->status = status;
00146 ke_msg_send(cfm);
00147
00148 return (msg_status);
00149 }
00150
00162 static int
00163 sm_disconnect_req_handler(ke_msg_id_t const msgid,
00164 struct sm_disconnect_req const *param,
00165 ke_task_id_t const dest_id,
00166 ke_task_id_t const src_id)
00167 {
00168
00169 if ((ke_state_get(TASK_SM) != SM_IDLE))
00170 return (KE_MSG_SAVED);
00171
00172
00173 sm_disconnect(param->vif_idx, param->reason_code);
00174
00175 return (KE_MSG_CONSUMED);
00176 }
00177
00189 static int
00190 mm_connection_loss_ind_handler(ke_msg_id_t const msgid,
00191 struct mm_connection_loss_ind const *param,
00192 ke_task_id_t const dest_id,
00193 ke_task_id_t const src_id)
00194 {
00195 struct vif_info_tag *vif = &vif_info_tab[param->inst_nbr];
00196
00197
00198 if (ke_state_get(TASK_SM) != SM_IDLE)
00199
00200 return KE_MSG_SAVED;
00201
00202 if ((vif->type != VIF_STA) || (!vif->active))
00203 return KE_MSG_CONSUMED;
00204
00205 ke_state_set(TASK_SM, SM_DISCONNECTING);
00206
00207
00208 sm_disconnect_process(vif, MAC_RS_UNSPECIFIED);
00209
00210 return (KE_MSG_CONSUMED);
00211 }
00212
00213
00226 static int
00227 sm_rsp_timeout_ind_handler(ke_msg_id_t const msgid,
00228 void const *param,
00229 ke_task_id_t const dest_id,
00230 ke_task_id_t const src_id)
00231
00232 {
00233
00234 if ((ke_state_get(TASK_SM) != SM_AUTHENTICATING) &&
00235 (ke_state_get(TASK_SM) != SM_EXTERNAL_AUTHENTICATING) &&
00236 (ke_state_get(TASK_SM) != SM_ASSOCIATING) )
00237 return (KE_MSG_CONSUMED);
00238
00239
00240 sm_connect_ind(MAC_ST_FAILURE);
00241
00242 return (KE_MSG_CONSUMED);
00243 }
00244
00245
00257 static int
00258 scanu_start_cfm_handler(ke_msg_id_t const msgid,
00259 void const *param,
00260 ke_task_id_t const dest_id,
00261 ke_task_id_t const src_id)
00262 {
00263 struct mac_addr const *bssid = NULL;
00264 struct mac_chan_def const *chan = NULL;
00265
00266
00267 ASSERT_ERR(ke_state_get(TASK_SM) == SM_SCANNING);
00268
00269
00270 sm_get_bss_params(&bssid, &chan);
00271
00272
00273 if (bssid && chan)
00274 {
00275 sm_join_bss(bssid, chan, false);
00276 }
00277 else
00278 {
00279
00280 sm_connect_ind(MAC_ST_FAILURE);
00281 }
00282
00283 return (KE_MSG_CONSUMED);
00284 }
00285
00297 static int
00298 scanu_join_cfm_handler(ke_msg_id_t const msgid,
00299 void const *param,
00300 ke_task_id_t const dest_id,
00301 ke_task_id_t const src_id)
00302 {
00303 struct sm_connect_req const *con_par = sm_env.connect_param;
00304 struct vif_info_tag *vif;
00305 struct me_bss_info *bss;
00306
00307
00308 ASSERT_ERR(ke_state_get(TASK_SM) == SM_JOINING);
00309
00310
00311 vif = &vif_info_tab[con_par->vif_idx];
00312 bss = &vif->bss_info;
00313
00314
00315 if (BSS_CAPA(bss, VALID))
00316 {
00317
00318 uint8_t chan_idx;
00319
00320
00321 if (sm_add_chan_ctx(&chan_idx) == CO_OK)
00322 {
00323 struct mm_sta_add_req *req = KE_MSG_ALLOC(MM_STA_ADD_REQ, TASK_MM,
00324 TASK_SM, mm_sta_add_req);
00325 uint32_t paid_gid = 0;
00326
00327
00328 chan_ctxt_link(con_par->vif_idx, chan_idx);
00329
00330
00331 req->inst_nbr = con_par->vif_idx;
00332 req->mac_addr = bss->bssid;
00333 req->tdls_sta = false;
00334 req->bssid_index = bss->bssid_index;
00335 req->max_bssid_ind = bss->max_bssid_ind;
00336 if (BSS_CAPA(bss, HT))
00337 {
00338 struct mac_htcapability *ht_cap = &bss->ht_cap;
00339 struct mac_vhtcapability *vht_cap = NULL;
00340 struct mac_hecapability *he_cap = NULL;
00341
00342 #if NX_VHT
00343 if (BSS_CAPA(bss, VHT))
00344 {
00345 vht_cap = &bss->vht_cap;
00346 paid_gid = mac_paid_gid_sta_compute(&bss->bssid);
00347 }
00348 #endif
00349 #if NX_HE
00350 if (BSS_CAPA(bss, HE))
00351 {
00352 he_cap = &bss->he_cap;
00353 }
00354 #endif
00355 me_get_ampdu_params(ht_cap, vht_cap, he_cap, &req->ampdu_size_max_ht,
00356 &req->ampdu_size_max_vht, &req->ampdu_size_max_he,
00357 &req->ampdu_spacing_min);
00358 }
00359 req->paid_gid = paid_gid;
00360
00361
00362 ke_msg_send(req);
00363
00364
00365 ke_state_set(TASK_SM, SM_STA_ADDING);
00366 }
00367 else
00368 {
00369
00370 sm_connect_ind(MAC_ST_FAILURE);
00371 }
00372
00373
00374 vif->flags = con_par->flags;
00375
00376
00377 if (con_par->flags & DISABLE_HT)
00378 {
00379 BSS_CAPA_CLR(bss, HT);
00380 BSS_CAPA_CLR(bss, VHT);
00381 BSS_CAPA_CLR(bss, HE);
00382 }
00383 }
00384 else
00385 {
00386
00387 if (sm_env.join_passive)
00388 {
00389 struct mac_addr const *bssid = NULL;
00390 struct mac_chan_def const *chan = NULL;
00391 sm_get_bss_params(&bssid, &chan);
00392
00393 #if (NX_ANT_DIV)
00394
00395 if (!scanu_env.join_status)
00396 {
00397
00398 ke_msg_send_basic(MM_SWITCH_ANTENNA_REQ, TASK_MM, TASK_SM);
00399 }
00400 #endif //(NX_ANT_DIV)
00401 sm_join_bss(bssid, chan, true);
00402 }
00403 else
00404 {
00405
00406 sm_connect_ind(MAC_ST_FAILURE);
00407 }
00408 }
00409
00410 return (KE_MSG_CONSUMED);
00411 }
00412
00424 static int
00425 mm_sta_add_cfm_handler(ke_msg_id_t const msgid,
00426 struct mm_sta_add_cfm const *param,
00427 ke_task_id_t const dest_id,
00428 ke_task_id_t const src_id)
00429 {
00430
00431 ASSERT_ERR(ke_state_get(TASK_SM) == SM_STA_ADDING);
00432
00433
00434 if (param->status == CO_OK)
00435 {
00436 struct sta_info_tag *sta = &sta_info_tab[param->sta_idx];
00437 struct vif_info_tag *vif = &vif_info_tab[sta->inst_nbr];
00438 struct sta_capa_info *info = &sta->info;
00439 struct me_bss_info *bss = &vif->bss_info;
00440
00441
00442 info->rate_set = bss->rate_set;
00443 if (BSS_CAPA(bss, QOS))
00444 {
00445 STA_CAPA_SET(sta, QOS);
00446 }
00447 if (BSS_CAPA(bss, HT))
00448 {
00449 STA_CAPA_SET(sta, HT);
00450 info->ht_cap = bss->ht_cap;
00451 #if NX_HE
00452 if (BSS_CAPA(bss, HE))
00453 {
00454 STA_CAPA_SET(sta, HE);
00455 info->he_cap = bss->he_cap;
00456 }
00457 #endif
00458 #if NX_VHT
00459 if (BSS_CAPA(bss, VHT))
00460 {
00461 STA_CAPA_SET(sta, VHT);
00462 info->vht_cap = bss->vht_cap;
00463 }
00464 #endif
00465
00466
00467 me_set_sta_ht_vht_param(sta, bss);
00468 }
00469
00470
00471 sm_set_bss_param();
00472
00473
00474 me_init_rate(sta);
00475 }
00476 else
00477 {
00478
00479 sm_connect_ind(MAC_ST_FAILURE);
00480 }
00481 return (KE_MSG_CONSUMED);
00482 }
00483
00495 static int
00496 me_set_ps_disable_cfm_handler(ke_msg_id_t const msgid,
00497 void const *param,
00498 ke_task_id_t const dest_id,
00499 ke_task_id_t const src_id)
00500 {
00501
00502 ASSERT_ERR((ke_state_get(TASK_SM) == SM_BSS_PARAM_SETTING) ||
00503 (ke_state_get(TASK_SM) == SM_IDLE) ||
00504 (ke_state_get(TASK_SM) == SM_DISCONNECTING));
00505
00506
00507 if ((ke_state_get(TASK_SM) == SM_BSS_PARAM_SETTING) ||
00508 (ke_state_get(TASK_SM) == SM_DISCONNECTING))
00509 {
00510
00511 sm_bss_config_send();
00512 }
00513
00514 return (KE_MSG_CONSUMED);
00515 }
00516
00529 static int
00530 mm_bss_param_setting_handler(ke_msg_id_t const msgid,
00531 void const *param,
00532 ke_task_id_t const dest_id,
00533 ke_task_id_t const src_id)
00534 {
00535
00536 ASSERT_ERR(ke_state_get(TASK_SM) == SM_BSS_PARAM_SETTING);
00537
00538
00539 sm_bss_config_send();
00540
00541 return (KE_MSG_CONSUMED);
00542 }
00543
00556 static int
00557 me_set_active_cfm_handler(ke_msg_id_t const msgid,
00558 void const *param,
00559 ke_task_id_t const dest_id,
00560 ke_task_id_t const src_id)
00561 {
00562
00563 ASSERT_ERR((ke_state_get(TASK_SM) == SM_BSS_PARAM_SETTING) ||
00564 (ke_state_get(TASK_SM) == SM_DISCONNECTING));
00565
00566
00567 if (ke_state_get(TASK_SM) == SM_DISCONNECTING)
00568 {
00569 struct vif_info_tag *vif = sm_env.vif_disconnect;
00570
00571
00572 BSS_CAPA_RESET(&vif->bss_info);
00573
00574 if (sm_env.host_disconnect)
00575 {
00576 ke_msg_send_basic(SM_DISCONNECT_CFM, TASK_API, TASK_SM);
00577 sm_env.host_disconnect = false;
00578 }
00579
00580 ke_msg_send(ke_msg2param(sm_env.disconnect_ind));
00581 sm_env.disconnect_ind = NULL;
00582
00583 if (sm_env.ft_over_ds == 1)
00584 {
00585 struct mac_addr const *bssid = NULL;
00586 struct mac_chan_def const *chan = NULL;
00587 sm_get_bss_params(&bssid, &chan);
00588 sm_join_bss(bssid, chan, false);
00589 }
00590 else
00591 {
00592 ke_state_set(TASK_SM, SM_IDLE);
00593 }
00594 }
00595 else
00596 {
00597
00598 if (sm_env.ft_over_ds == 1)
00599 {
00600
00601 sm_assoc_req_send();
00602 }
00603 else
00604 {
00605 struct sm_connect_req const *con_par = sm_env.connect_param;
00606 switch(con_par->auth_type)
00607 {
00608 case MAC_AUTH_ALGO_OPEN:
00609 case MAC_AUTH_ALGO_SHARED:
00610 case MAC_AUTH_ALGO_FT:
00611 sm_auth_send(MAC_AUTH_FIRST_SEQ, NULL);
00612 break;
00613 case MAC_AUTH_ALGO_SAE:
00614 sm_external_auth_start(MAC_RSNIE_AKM_SAE);
00615 break;
00616 default:
00617 sm_connect_ind(MAC_ST_FAILURE);
00618 }
00619
00620 }
00621 }
00622
00623 return (KE_MSG_CONSUMED);
00624 }
00625
00626
00639 static int
00640 mm_set_vif_state_cfm_handler(ke_msg_id_t const msgid,
00641 void const *param,
00642 ke_task_id_t const dest_id,
00643 ke_task_id_t const src_id)
00644 {
00645
00646 if (ke_state_get(TASK_SM) == SM_ACTIVATING)
00647 {
00648 struct sm_connect_req const *con_par = sm_env.connect_param;
00649 struct vif_info_tag *vif = &vif_info_tab[con_par->vif_idx];
00650 struct sta_info_tag *sta = &sta_info_tab[vif->u.sta.ap_id];
00651
00652 #if NX_POWERSAVE
00653 struct mm_set_ps_options_req *req;
00654
00655
00656 req = KE_MSG_ALLOC(MM_SET_PS_OPTIONS_REQ, TASK_MM, TASK_SM, mm_set_ps_options_req);
00657
00658
00659 req->dont_listen_bc_mc = con_par->dont_wait_bcmc;
00660 req->listen_interval = con_par->listen_interval;
00661 req->vif_index = con_par->vif_idx;
00662
00663
00664 ke_msg_send(req);
00665 #endif
00666
00667
00668 sta->ctrl_port_state = (vif->flags & CONTROL_PORT_HOST)?PORT_CONTROLED:PORT_OPEN;
00669 sta->ctrl_port_ethertype = co_ntohs(con_par->ctrl_port_ethertype);
00670
00671
00672 if (sta->ctrl_port_state == PORT_OPEN)
00673 {
00674 struct me_set_ps_disable_req *ps = KE_MSG_ALLOC(ME_SET_PS_DISABLE_REQ, TASK_ME, TASK_SM,
00675 me_set_ps_disable_req);
00676
00677 ps->ps_disable = false;
00678 ps->vif_idx = con_par->vif_idx;
00679
00680 ke_msg_send(ps);
00681 }
00682
00683
00684 sm_connect_ind(MAC_ST_SUCCESSFUL);
00685 }
00686
00687 else if (ke_state_get(TASK_SM) == SM_DISCONNECTING)
00688 {
00689
00690 sm_bss_config_send();
00691 }
00692
00693 return (KE_MSG_CONSUMED);
00694 }
00695
00708 static int
00709 mm_sta_del_cfm_handler(ke_msg_id_t const msgid,
00710 struct mm_sta_del_cfm const *param,
00711 ke_task_id_t const dest_id,
00712 ke_task_id_t const src_id)
00713 {
00714
00715 ASSERT_ERR(ke_state_get(TASK_SM) == SM_DISCONNECTING);
00716
00717
00718 sm_bss_config_send();
00719
00720 return (KE_MSG_CONSUMED);
00721 }
00722
00735 static int
00736 mm_chan_ctxt_unlink_cfm_handler(ke_msg_id_t const msgid,
00737 void const *param,
00738 ke_task_id_t const dest_id,
00739 ke_task_id_t const src_id)
00740 {
00741
00742 ASSERT_ERR(ke_state_get(TASK_SM) == SM_DISCONNECTING);
00743
00744
00745 sm_bss_config_send();
00746
00747 return (KE_MSG_CONSUMED);
00748 }
00749
00762 static int
00763 rxu_mgt_ind_handler(ke_msg_id_t const msgid,
00764 struct rxu_mgt_ind const *param,
00765 ke_task_id_t const dest_id,
00766 ke_task_id_t const src_id)
00767 {
00768 uint16_t fctl = param->framectrl & MAC_FCTRL_TYPESUBTYPE_MASK;
00769 int msg_status = KE_MSG_CONSUMED;
00770
00771
00772 if ((fctl == MAC_FCTRL_AUTHENT) && (ke_state_get(TASK_SM) == SM_AUTHENTICATING))
00773 {
00774 sm_auth_handler(param);
00775 }
00776 else if ((fctl == MAC_FCTRL_ASSOCRSP) && (ke_state_get(TASK_SM) == SM_ASSOCIATING))
00777 {
00778 sm_assoc_rsp_handler(param);
00779 }
00780 else if ((fctl == MAC_FCTRL_REASSOCRSP) && (ke_state_get(TASK_SM) == SM_ASSOCIATING))
00781 {
00782 sm_assoc_rsp_handler(param);
00783 }
00784 else if ((fctl == MAC_FCTRL_DEAUTHENT) || (fctl == MAC_FCTRL_DISASSOC))
00785 {
00786 msg_status = sm_deauth_handler(param);
00787 }
00788 else if (fctl == MAC_FCTRL_ACTION)
00789 {
00790 #if NX_MFP
00791 uint32_t payload = CPU2HW(param->payload);
00792 uint8_t action = co_read8p(payload + MAC_ACTION_CATEGORY_OFT);
00793
00794 if (action == MAC_SA_QUERY_ACTION_CATEGORY)
00795 sm_sa_query_handler(param);
00796 #endif // NX_MFP
00797 }
00798
00799 return (msg_status);
00800 }
00801
00815 static int
00816 sm_external_auth_required_rsp_handler(ke_msg_id_t const msgid,
00817 struct sm_external_auth_required_rsp const *param,
00818 ke_task_id_t const dest_id,
00819 ke_task_id_t const src_id)
00820 {
00821
00822 ASSERT_ERR(ke_state_get(TASK_SM) == SM_EXTERNAL_AUTHENTICATING);
00823
00824 sm_external_auth_end(param->status);
00825
00826 return (KE_MSG_CONSUMED);
00827 }
00828
00830 const struct ke_msg_handler sm_default_state[] =
00831 {
00832 {SM_CONNECT_REQ, (ke_msg_func_t)sm_connect_req_handler},
00833 {SM_DISCONNECT_REQ, (ke_msg_func_t)sm_disconnect_req_handler},
00834 {SCANU_START_CFM, (ke_msg_func_t)scanu_start_cfm_handler},
00835 {SCANU_JOIN_CFM, (ke_msg_func_t)scanu_join_cfm_handler},
00836 {SM_RSP_TIMEOUT_IND, (ke_msg_func_t)sm_rsp_timeout_ind_handler},
00837 {MM_CONNECTION_LOSS_IND, (ke_msg_func_t)mm_connection_loss_ind_handler},
00838 {MM_STA_ADD_CFM, (ke_msg_func_t)mm_sta_add_cfm_handler},
00839 {ME_SET_ACTIVE_CFM, (ke_msg_func_t)me_set_active_cfm_handler},
00840 {MM_SET_BSSID_CFM, mm_bss_param_setting_handler},
00841 {MM_SET_BASIC_RATES_CFM, mm_bss_param_setting_handler},
00842 {MM_SET_BEACON_INT_CFM, mm_bss_param_setting_handler},
00843 {MM_SET_BSS_COLOR_CFM, mm_bss_param_setting_handler},
00844 {MM_SET_EDCA_CFM, mm_bss_param_setting_handler},
00845 {MM_SET_VIF_STATE_CFM, mm_set_vif_state_cfm_handler},
00846 {ME_SET_PS_DISABLE_CFM, (ke_msg_func_t)me_set_ps_disable_cfm_handler},
00847 #if NX_POWERSAVE
00848 {MM_SET_PS_OPTIONS_CFM, ke_msg_discard},
00849 #endif
00850 {MM_STA_DEL_CFM, (ke_msg_func_t)mm_sta_del_cfm_handler},
00851 {MM_CHAN_CTXT_UNLINK_CFM, (ke_msg_func_t)mm_chan_ctxt_unlink_cfm_handler},
00852 {RXU_MGT_IND, (ke_msg_func_t)rxu_mgt_ind_handler},
00853 {SM_EXTERNAL_AUTH_REQUIRED_RSP, (ke_msg_func_t)sm_external_auth_required_rsp_handler}
00854 };
00855
00857 const struct ke_state_handler sm_default_handler =
00858 KE_STATE_HANDLER(sm_default_state);
00859
00861 ke_state_t sm_state[SM_IDX_MAX];
00862