1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * 文 件 名 : hmac_roam_connect.c
15 * 生成日期 : 2015年3月18日
16 * 功能描述 : 漫游connect流程实现
17 */
18
19
20 /*****************************************************************************
21 1 头文件包含
22 *****************************************************************************/
23 #include "hmac_roam_connect.h"
24 #include "oam_ext_if.h"
25 #include "mac_ie.h"
26 #include "mac_device_ext.h"
27 #include "mac_resource_ext.h"
28 #include "dmac_ext_if_hcm.h"
29 #include "hmac_fsm.h"
30 #include "hmac_sme_sta.h"
31 #include "hmac_resource.h"
32 #include "hmac_device.h"
33 #include "hmac_mgmt_sta.h"
34 #include "hmac_mgmt_bss_comm.h"
35 #include "hmac_encap_frame_sta.h"
36 #include "hmac_tx_amsdu.h"
37 #include "hmac_rx_data.h"
38 #include "hmac_chan_mgmt.h"
39 #include "hmac_11i.h"
40 #include "hmac_user.h"
41 #include "hmac_roam_main.h"
42 #include "wlan_msg.h"
43 #include "hmac_feature_dft.h"
44 #include "hmac_mbo.h"
45 #include "hmac_feature_interface.h"
46 #include "hmac_11r.h"
47
48 #ifdef __cplusplus
49 #if __cplusplus
50 extern "C" {
51 #endif
52 #endif
53
54 #undef THIS_FILE_ID
55 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_ROAM_CONNECT_C
56
57 #undef THIS_MOD_ID
58 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
59
60 /*****************************************************************************
61 2 全局变量定义
62 *****************************************************************************/
63 hmac_roam_fsm_func g_hmac_roam_connect_fsm_func[ROAM_CONNECT_STATE_BUTT][ROAM_CONNECT_FSM_EVENT_TYPE_BUTT];
64
65 OAL_STATIC osal_u32 hmac_roam_connect_null_fn(hmac_roam_info_stru *roam_info, osal_void *param);
66 OAL_STATIC osal_u32 hmac_roam_start_join(hmac_roam_info_stru *roam_info, osal_void *p_param);
67 OAL_STATIC osal_u32 hmac_roam_send_auth_seq1(hmac_roam_info_stru *roam_info);
68 OAL_STATIC osal_u32 hmac_roam_process_auth_seq2(hmac_roam_info_stru *roam_info, osal_void *p_param);
69 OAL_STATIC osal_u32 hmac_roam_process_assoc_rsp(hmac_roam_info_stru *roam_info, osal_void *p_param);
70 OAL_STATIC osal_u32 hmac_roam_process_action(hmac_roam_info_stru *roam_info, osal_void *p_param);
71 osal_u32 hmac_roam_connect_succ(hmac_roam_info_stru *roam_info, osal_void *param);
72 OAL_STATIC osal_u32 hmac_roam_auth_timeout(hmac_roam_info_stru *roam_info, osal_void *p_param);
73 OAL_STATIC osal_u32 hmac_roam_assoc_timeout(hmac_roam_info_stru *roam_info, osal_void *p_param);
74 OAL_STATIC osal_u32 hmac_roam_handshaking_timeout(hmac_roam_info_stru *roam_info, osal_void *p_param);
75 osal_u32 hmac_roam_send_reassoc_req(hmac_roam_info_stru *roam_info);
76 OAL_STATIC osal_u32 hmac_roam_connect_timeout_etc(osal_void *p_arg);
77
78 /*****************************************************************************
79 3 函数实现
80 *****************************************************************************/
81
hmac_roam_connect_fsm_deinit_etc(osal_void)82 osal_void hmac_roam_connect_fsm_deinit_etc(osal_void)
83 {
84 osal_u32 state;
85 osal_u32 event;
86
87 for (state = 0; state < ROAM_CONNECT_STATE_BUTT; state++) {
88 for (event = 0; event < ROAM_CONNECT_FSM_EVENT_TYPE_BUTT; event++) {
89 g_hmac_roam_connect_fsm_func[state][event] = hmac_roam_connect_null_fn;
90 }
91 }
92 }
93 /*****************************************************************************
94 函 数 名 : hmac_roam_connect_fsm_init_etc
95 功能描述 : roam connect模块状态-事件-行为表
96 输出参数 : 无
97 返 回 值 : 无
98 *****************************************************************************/
hmac_roam_connect_fsm_init_etc(osal_void)99 osal_void hmac_roam_connect_fsm_init_etc(osal_void)
100 {
101 osal_void *fhook = hmac_get_feature_fhook(HMAC_FHOOK_11R_ROAM_CONNECT_FSM_INIT);
102
103 hmac_roam_connect_fsm_deinit_etc();
104 g_hmac_roam_connect_fsm_func[ROAM_CONNECT_STATE_INIT][ROAM_CONNECT_FSM_EVENT_START] =
105 hmac_roam_start_join;
106 g_hmac_roam_connect_fsm_func[ROAM_CONNECT_STATE_WAIT_AUTH_COMP][ROAM_CONNECT_FSM_EVENT_MGMT_RX] =
107 hmac_roam_process_auth_seq2;
108 g_hmac_roam_connect_fsm_func[ROAM_CONNECT_STATE_WAIT_AUTH_COMP][ROAM_CONNECT_FSM_EVENT_TIMEOUT] =
109 hmac_roam_auth_timeout;
110 g_hmac_roam_connect_fsm_func[ROAM_CONNECT_STATE_WAIT_ASSOC_COMP][ROAM_CONNECT_FSM_EVENT_MGMT_RX] =
111 hmac_roam_process_assoc_rsp;
112 g_hmac_roam_connect_fsm_func[ROAM_CONNECT_STATE_WAIT_ASSOC_COMP][ROAM_CONNECT_FSM_EVENT_TIMEOUT] =
113 hmac_roam_assoc_timeout;
114 g_hmac_roam_connect_fsm_func[ROAM_CONNECT_STATE_HANDSHAKING][ROAM_CONNECT_FSM_EVENT_MGMT_RX] =
115 hmac_roam_process_action;
116 g_hmac_roam_connect_fsm_func[ROAM_CONNECT_STATE_HANDSHAKING][ROAM_CONNECT_FSM_EVENT_KEY_DONE] =
117 hmac_roam_connect_succ;
118 g_hmac_roam_connect_fsm_func[ROAM_CONNECT_STATE_HANDSHAKING][ROAM_CONNECT_FSM_EVENT_TIMEOUT] =
119 hmac_roam_handshaking_timeout;
120
121 if (fhook != OSAL_NULL) {
122 ((hmac_11r_roam_connect_fsm_init_cb)fhook)(g_hmac_roam_connect_fsm_func);
123 }
124 }
125
126 /*****************************************************************************
127 函 数 名 : hmac_roam_connect_fsm_action_etc
128 功能描述 : 调用漫游connect状态机函数表
129 输入参数 : hmac_vap: hmac vap
130 event: 事件类型
131 p_param: 输入参数
132 *****************************************************************************/
hmac_roam_connect_fsm_action_etc(hmac_roam_info_stru * roam_info,roam_connect_fsm_event_type_enum event,osal_void * p_param)133 osal_u32 hmac_roam_connect_fsm_action_etc(hmac_roam_info_stru *roam_info,
134 roam_connect_fsm_event_type_enum event, osal_void *p_param)
135 {
136 if (roam_info == OAL_PTR_NULL) {
137 return OAL_ERR_CODE_PTR_NULL;
138 }
139
140 if (roam_info->connect.state >= ROAM_CONNECT_STATE_BUTT) {
141 return OAL_ERR_CODE_ROAM_STATE_UNEXPECT;
142 }
143
144 if (event >= ROAM_CONNECT_FSM_EVENT_TYPE_BUTT) {
145 return OAL_ERR_CODE_ROAM_EVENT_UXEXPECT;
146 }
147
148 oam_warning_log2(0, OAM_SF_ROAM, "hmac_roam_connect_fsm_action_etc::roam_conn_state[%d] event[%d]\r\n",
149 roam_info->connect.state, event);
150 return g_hmac_roam_connect_fsm_func[roam_info->connect.state][event](roam_info, p_param);
151 }
152
153 /*****************************************************************************
154 函 数 名 : hmac_roam_connect_change_state
155 功能描述 : 改变状态机状态
156 输入参数 : hmac_vap : HMAC VAP
157 roam_main_state: 要切换到的状态
158 输出参数 : 无
159 *****************************************************************************/
hmac_roam_connect_change_state(hmac_roam_info_stru * roam_info,roam_connect_state_enum_uint8 state)160 osal_void hmac_roam_connect_change_state(hmac_roam_info_stru *roam_info,
161 roam_connect_state_enum_uint8 state)
162 {
163 if (roam_info) {
164 oam_warning_log2(0, OAM_SF_ROAM,
165 "{hmac_roam_connect_change_state::[%d]->[%d]}", roam_info->connect.state, state);
166 roam_info->connect.state = state;
167 }
168 }
169
170 /*****************************************************************************
171 函 数 名 : hmac_roam_connect_check_state
172 功能描述 : 参数检查接口
173 输出参数 : 无
174 返 回 值 : OAL_SUCC 或 失败错误码
175 *****************************************************************************/
hmac_roam_connect_check_state(hmac_roam_info_stru * roam_info,mac_vap_state_enum_uint8 vap_state,roam_main_state_enum_uint8 main_state,roam_connect_state_enum_uint8 connect_state)176 osal_u32 hmac_roam_connect_check_state(hmac_roam_info_stru *roam_info,
177 mac_vap_state_enum_uint8 vap_state,
178 roam_main_state_enum_uint8 main_state,
179 roam_connect_state_enum_uint8 connect_state)
180 {
181 if (roam_info == OAL_PTR_NULL) {
182 return OAL_ERR_CODE_PTR_NULL;
183 }
184
185 if (roam_info->hmac_vap == OAL_PTR_NULL) {
186 return OAL_ERR_CODE_ROAM_INVALID_VAP;
187 }
188
189 if (roam_info->hmac_user == OAL_PTR_NULL) {
190 return OAL_ERR_CODE_ROAM_INVALID_USER;
191 }
192
193 if (roam_info->enable == 0) {
194 return OAL_ERR_CODE_ROAM_DISABLED;
195 }
196
197 if (roam_info->hmac_vap->wpa3_roaming == OSAL_TRUE) {
198 oam_warning_log0(0, OAM_SF_ROAM, "hmac_roam_connect_check_state::wpa3 roaming skip state check");
199 return OAL_SUCC;
200 }
201
202 if ((roam_info->hmac_vap->vap_state != vap_state) ||
203 (roam_info->main_state != main_state) ||
204 (roam_info->connect.state != connect_state)) {
205 oam_warning_log3(0, OAM_SF_ROAM,
206 "{hmac_roam_connect_check_state::unexpect vap_state[%d] main_state[%d] connect_state[%d]!}",
207 roam_info->hmac_vap->vap_state, roam_info->main_state,
208 roam_info->connect.state);
209 return OAL_ERR_CODE_ROAM_INVALID_VAP_STATUS;
210 }
211
212 return OAL_SUCC;
213 }
214
215
216 /*****************************************************************************
217 函 数 名 : hmac_roam_connect_timeout_etc
218 输出参数 : 无
219 返 回 值 : OAL_SUCC 或 失败错误码
220 *****************************************************************************/
hmac_roam_connect_timeout_etc(osal_void * p_arg)221 OAL_STATIC osal_u32 hmac_roam_connect_timeout_etc(osal_void *p_arg)
222 {
223 hmac_roam_info_stru *roam_info;
224
225 roam_info = (hmac_roam_info_stru *)p_arg;
226 if (roam_info == OAL_PTR_NULL) {
227 oam_error_log0(0, OAM_SF_ROAM, "{hmac_roam_connect_timeout_etc::p_arg is null.}");
228 return OAL_ERR_CODE_PTR_NULL;
229 }
230
231 oam_warning_log2(0, OAM_SF_ROAM, "{hmac_roam_connect_timeout_etc::MAIN_STATE[%d] CONNECT_STATE[%d].}",
232 roam_info->main_state, roam_info->connect.state);
233
234 return hmac_roam_connect_fsm_action_etc(roam_info, ROAM_CONNECT_FSM_EVENT_TIMEOUT, OAL_PTR_NULL);
235 }
236 /*****************************************************************************
237 函 数 名 : hmac_roam_connect_null_fn
238 输出参数 : 无
239 返 回 值 : OAL_SUCC 或 失败错误码
240 *****************************************************************************/
hmac_roam_connect_null_fn(hmac_roam_info_stru * roam_info,osal_void * param)241 OAL_STATIC osal_u32 hmac_roam_connect_null_fn(hmac_roam_info_stru *roam_info, osal_void *param)
242 {
243 unref_param(roam_info);
244 unref_param(param);
245
246 return OAL_CONTINUE;
247 }
248
249 /*****************************************************************************
250 函 数 名 : hmac_roam_connect_start_timer
251 功能描述 : 如果定时器已存在,重启,否则创建定时器
252 输出参数 : 无
253 返 回 值 : OAL_SUCC 或 失败错误码
254 *****************************************************************************/
hmac_roam_connect_start_timer(hmac_roam_info_stru * roam_info,osal_u32 timeout)255 osal_void hmac_roam_connect_start_timer(hmac_roam_info_stru *roam_info, osal_u32 timeout)
256 {
257 frw_timeout_stru *timer = &(roam_info->connect.timer);
258
259 oam_info_log1(0, OAM_SF_ROAM, "{hmac_roam_connect_start_timer [%d].}", timeout);
260
261 /* 启动认证超时定时器 */
262 frw_create_timer_entry(timer,
263 hmac_roam_connect_timeout_etc,
264 timeout,
265 roam_info,
266 OAL_FALSE);
267 }
268
269 /*****************************************************************************
270 函 数 名 : hmac_roam_connect_del_timer
271 功能描述 : 立即删除roam connect定时器
272 输出参数 : 无
273 返 回 值 : OAL_SUCC 或 失败错误码
274 *****************************************************************************/
hmac_roam_connect_del_timer(hmac_roam_info_stru * roam_info)275 OAL_STATIC osal_u32 hmac_roam_connect_del_timer(hmac_roam_info_stru *roam_info)
276 {
277 frw_destroy_timer_entry(&(roam_info->connect.timer));
278 return OAL_SUCC;
279 }
280
281 /*****************************************************************************
282 函 数 名 : hmac_roam_connect_set_join_reg_etc
283 功能描述 : 根据bss更新mib信息
284 输入参数 : hmac_vap_stru *hmac_vap,
285 mac_bss_dscr_stru *bss_dscr
286 输出参数 : 无
287 返 回 值 : osal_u32
288 *****************************************************************************/
hmac_roam_connect_set_join_reg_etc(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user)289 osal_u32 hmac_roam_connect_set_join_reg_etc(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user)
290 {
291 hmac_ctx_join_req_set_reg_stru reg_params;
292 hmac_join_req_stru join_req;
293
294 memset_s(&join_req, OAL_SIZEOF(hmac_join_req_stru), 0, OAL_SIZEOF(hmac_join_req_stru));
295
296 /* 设置需要写入寄存器的BSSID信息 */
297 oal_set_mac_addr(reg_params.bssid, hmac_vap->bssid);
298
299 /* 填写信道相关信息 */
300 reg_params.current_channel.chan_number = hmac_vap->channel.chan_number;
301 reg_params.current_channel.band = hmac_vap->channel.band;
302 reg_params.current_channel.en_bandwidth = hmac_vap->channel.en_bandwidth;
303 reg_params.current_channel.chan_idx = hmac_vap->channel.chan_idx;
304
305 /* 以old user信息塑造虚假的入网结构体,调用函数 */
306 /* 填写速率相关信息 */
307 join_req.bss_dscr.num_supp_rates = hmac_user->op_rates.rs_nrates;
308 (osal_void)memcpy_s(join_req.bss_dscr.supp_rates, OAL_SIZEOF(osal_u8) * WLAN_MAX_SUPP_RATES,
309 hmac_user->op_rates.rs_rates, OAL_SIZEOF(osal_u8) * WLAN_MAX_SUPP_RATES);
310 join_req.bss_dscr.ht_capable = hmac_user->ht_hdl.ht_capable;
311 join_req.bss_dscr.vht_capable = hmac_user->vht_hdl.vht_capable;
312 hmac_sta_get_min_rate(®_params.min_rate, &join_req);
313
314 /* 设置dtim period信息 */
315 reg_params.beacon_period = (osal_u16)mac_mib_get_beacon_period(hmac_vap);
316
317 /* 同步FortyMHzOperationImplemented */
318 reg_params.dot11_40mhz_operation_implemented = mac_mib_get_forty_mhz_operation_implemented(hmac_vap);
319
320 /* 设置beacon filter关闭 */
321 reg_params.beacon_filter = OAL_FALSE;
322
323 /* 设置no frame filter打开 */
324 reg_params.non_frame_filter = OAL_TRUE;
325
326 hmac_join_set_reg_event_process(hmac_vap, ®_params);
327 return OAL_SUCC;
328 }
329
hmac_roam_connect_msg_to_wpas(const hmac_vap_stru * hmac_vap,const hmac_roam_info_stru * roam_info,hmac_roam_rsp_stru * roam_rsp,const hmac_asoc_rsp_stru * asoc_rsp)330 OAL_STATIC osal_s32 hmac_roam_connect_msg_to_wpas(const hmac_vap_stru *hmac_vap,
331 const hmac_roam_info_stru *roam_info, hmac_roam_rsp_stru *roam_rsp, const hmac_asoc_rsp_stru *asoc_rsp)
332 {
333 frw_msg msg_info = {0};
334
335 if (osal_memcmp(roam_rsp->bssid, roam_info->old_bss.bssid, WLAN_MAC_ADDR_LEN) == 0) {
336 /* Reassociation to the same BSSID: report NL80211_CMD_CONNECT event to supplicant instead of NL80211_CMD_ROAM
337 * event in case supplicant ignore roam event to the same bssid which will cause 4-way handshake failure */
338 /* wpa_supplicant: wlan0: WPA: EAPOL-Key Replay Counter did not increase - dropping packet */
339 oam_warning_log4(0, OAM_SF_ROAM,
340 "{hmac_roam_connect_notify_wpas::roam to the same ap %02X:%02X:%02X:%02X:XX:XX}",
341 /* 0:1:2:3:数组下标 */
342 roam_rsp->bssid[0], roam_rsp->bssid[1], roam_rsp->bssid[2], roam_rsp->bssid[3]);
343
344 msg_info.data = (osal_u8 *)asoc_rsp;
345 msg_info.data_len = OAL_SIZEOF(hmac_asoc_rsp_stru);
346
347 return frw_asyn_host_post_msg(WLAN_MSG_H2W_ASOC_COMP_STA, FRW_POST_PRI_LOW, hmac_vap->vap_id, &msg_info);
348 } else {
349 msg_info.data = (osal_u8 *)roam_rsp;
350 msg_info.data_len = OAL_SIZEOF(hmac_roam_rsp_stru);
351
352 return frw_asyn_host_post_msg(WLAN_MSG_H2W_ROAM_COMP_STA, FRW_POST_PRI_LOW, hmac_vap->vap_id, &msg_info);
353 }
354 }
355
356 /*****************************************************************************
357 函 数 名 : hmac_roam_connect_notify_wpas
358 功能描述 : 将关联成功消息通知wpa_supplicant,以便开始4-way握手流程
359 输出参数 : 无
360 返 回 值 : OAL_SUCC 或 失败错误码
361 *****************************************************************************/
hmac_roam_connect_notify_wpas(hmac_roam_info_stru * roam_info,osal_u8 * mac_hdr,osal_u16 msg_len)362 OAL_STATIC osal_u32 hmac_roam_connect_notify_wpas(hmac_roam_info_stru *roam_info, osal_u8 *mac_hdr,
363 osal_u16 msg_len)
364 {
365 hmac_asoc_rsp_stru asoc_rsp;
366 hmac_roam_rsp_stru roam_rsp;
367 hmac_vap_stru *hmac_vap;
368 hmac_user_stru *hmac_user;
369 osal_u8 *mgmt_data;
370
371 memset_s(&asoc_rsp, OAL_SIZEOF(hmac_asoc_rsp_stru), 0, OAL_SIZEOF(hmac_asoc_rsp_stru));
372 memset_s(&roam_rsp, OAL_SIZEOF(hmac_roam_rsp_stru), 0, OAL_SIZEOF(hmac_roam_rsp_stru));
373 /* 获取AP的mac地址 */
374 mac_get_address3(mac_hdr, roam_rsp.bssid);
375 mac_get_address3(mac_hdr, asoc_rsp.addr_ap);
376
377 hmac_vap = roam_info->hmac_vap;
378 hmac_user = (hmac_user_stru *)mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
379 if (hmac_user == OAL_PTR_NULL) {
380 oam_warning_log1(0, OAM_SF_ROAM, "{hmac_roam_connect_notify_wpas, hmac_user[%d] = NULL!}",
381 hmac_vap->assoc_vap_id);
382 return OAL_ERR_CODE_PTR_NULL;
383 }
384
385 /* 获取关联请求帧信息 */
386 roam_rsp.asoc_req_ie_buff = hmac_user->assoc_req_ie_buff;
387 roam_rsp.asoc_req_ie_len = hmac_user->assoc_req_ie_len;
388 asoc_rsp.asoc_req_ie_buff = hmac_user->assoc_req_ie_buff;
389 asoc_rsp.asoc_req_ie_len = hmac_user->assoc_req_ie_len;
390
391 /* 记录关联响应帧的部分内容,用于上报给内核 */
392 /* asoc_rsp 帧拷贝一份上报上层,防止帧内容上报wal侧处理后被hmac侧释放 */
393 if (msg_len < OAL_ASSOC_RSP_IE_OFFSET) {
394 oam_error_log2(0, OAM_SF_ASSOC, "vap_id[%d] {hmac_handle_asoc_rsp_sta_etc::msg_len is too short, %d.}",
395 hmac_vap->vap_id, msg_len);
396 return OAL_ERR_CODE_ALLOC_MEM_FAIL;
397 }
398
399 mgmt_data = (osal_u8 *)oal_memalloc(msg_len - OAL_ASSOC_RSP_IE_OFFSET);
400 if (mgmt_data == OAL_PTR_NULL) {
401 oam_error_log2(0, OAM_SF_ASSOC, "vap_id[%d] {hmac_handle_asoc_rsp_sta_etc::mgmt_data alloc null,size %d.}",
402 hmac_vap->vap_id, (msg_len - OAL_ASSOC_RSP_IE_OFFSET));
403 return OAL_ERR_CODE_ALLOC_MEM_FAIL;
404 }
405 roam_rsp.asoc_rsp_ie_len = msg_len - OAL_ASSOC_RSP_IE_OFFSET;
406 (osal_void)memcpy_s(mgmt_data, roam_rsp.asoc_rsp_ie_len,
407 (osal_u8 *)(mac_hdr + OAL_ASSOC_RSP_IE_OFFSET), roam_rsp.asoc_rsp_ie_len);
408 roam_rsp.asoc_rsp_ie_buff = mgmt_data;
409 asoc_rsp.asoc_rsp_ie_len = roam_rsp.asoc_rsp_ie_len;
410 asoc_rsp.asoc_rsp_ie_buff = roam_rsp.asoc_rsp_ie_buff;
411
412 #ifdef _PRE_WLAN_FEATURE_WS92_MERGE
413 roam_rsp.st_channel.chan_number = roam_info->connect.bss_dscr->st_channel.chan_number;
414 #endif
415
416 if (hmac_roam_connect_msg_to_wpas(hmac_vap, roam_info, &roam_rsp, &asoc_rsp) != OAL_SUCC) {
417 oal_free(mgmt_data);
418 }
419 return OAL_SUCC;
420 }
421
hmac_roam_prepare_join_info(hmac_vap_stru * hmac_vap,mac_bss_dscr_stru * bss_dscr)422 OAL_STATIC osal_u32 hmac_roam_prepare_join_info(hmac_vap_stru *hmac_vap, mac_bss_dscr_stru *bss_dscr)
423 {
424 hmac_join_req_stru join_req;
425 oal_app_ie_stru app_ie;
426 osal_u8 *pmkid = OSAL_NULL;
427 osal_u8 ie_len = 0;
428 osal_u32 ret;
429
430 /* 配置join参数 */
431 hmac_prepare_join_req_etc(&join_req, bss_dscr);
432
433 ret = hmac_sta_update_join_req_params_etc(hmac_vap, &join_req);
434 if ((ret != OAL_SUCC)) {
435 oam_error_log2(0, OAM_SF_ROAM,
436 "vap_id[%d] {hmac_roam_start_join::hmac_sta_update_join_req_params_etc fail[%d].}",
437 hmac_vap->vap_id, ret);
438 return ret;
439 }
440
441 if (hmac_vap->cap_flag.wpa == OSAL_TRUE) {
442 /* 设置 WPA Capability IE */
443 hmac_set_wpa_ie_etc((osal_void *)hmac_vap, app_ie.ie, &ie_len);
444 }
445
446 if (hmac_vap->cap_flag.wpa2 == OSAL_TRUE || hmac_vap->cap_flag.wpa3 == OSAL_TRUE) {
447 /* 设置 RSN Capability IE */
448 if (hmac_vap->cap_flag.wpa3 != OSAL_TRUE) {
449 pmkid = hmac_vap_get_pmksa_etc(hmac_vap, bss_dscr->bssid);
450 }
451 hmac_set_rsn_ie_etc((osal_void *)hmac_vap, pmkid, app_ie.ie, &ie_len);
452 }
453
454 hmac_vap->wpa3_roaming = (hmac_vap->cap_flag.wpa3 == OSAL_TRUE) ? OSAL_TRUE : OSAL_FALSE;
455 if (ie_len != 0) {
456 app_ie.app_ie_type = (hmac_vap->wpa3_roaming == OSAL_TRUE) ? OAL_APP_ASSOC_REQ_IE :
457 OAL_APP_REASSOC_REQ_IE;
458 app_ie.ie_len = ie_len;
459 ret = hmac_config_set_app_ie_to_vap_etc(hmac_vap, &app_ie, app_ie.app_ie_type);
460 if (ret != OAL_SUCC) {
461 oam_warning_log2(0, OAM_SF_ROAM,
462 "vap_id[%d] {hmac_roam_start_join::hmac_config_set_app_ie_to_vap_etc fail, ret=[%d].}",
463 hmac_vap->vap_id, ret);
464 }
465 } else {
466 hmac_vap_clear_app_ie_etc(hmac_vap, OAL_APP_REASSOC_REQ_IE);
467 hmac_vap_clear_app_ie_etc(hmac_vap, OAL_APP_ASSOC_REQ_IE);
468 }
469
470 ret = (osal_u32)hmac_join_set_dtim_reg_event_process(hmac_vap);
471 if (ret != OAL_SUCC) {
472 oam_warning_log2(0, OAM_SF_ROAM,
473 "vap_id[%d] {hmac_roam_start_join::hmac_roam_connect_set_dtim_param_etc fail, ret=[%d].}",
474 hmac_vap->vap_id, ret);
475 }
476
477 return OAL_SUCC;
478 }
479
480 /*****************************************************************************
481 函 数 名 : hmac_roam_connect_complete_etc
482 返 回 值 : OAL_SUCC 或 失败错误码
483 *****************************************************************************/
hmac_roam_connect_complete_etc(hmac_vap_stru * hmac_vap,osal_u32 result)484 osal_void hmac_roam_connect_complete_etc(hmac_vap_stru *hmac_vap, osal_u32 result)
485 {
486 hmac_roam_info_stru *roam_info;
487
488 if (hmac_vap == OAL_PTR_NULL) {
489 oam_error_log0(0, OAM_SF_ROAM, "{hmac_roam_connect_complete_etc::vap null!}");
490 return;
491 }
492
493 roam_info = hmac_get_roam_info(hmac_vap->vap_id);
494 if (roam_info == OAL_PTR_NULL) {
495 oam_error_log1(0, OAM_SF_ROAM, "vap_id[%d] {hmac_roam_connect_complete_etc::roam_info null!}",
496 hmac_vap->vap_id);
497 return;
498 }
499
500 /* 漫游开关没有开时,不处理扫描结果 */
501 if (roam_info->enable == 0) {
502 oam_error_log1(0, OAM_SF_ROAM, "vap_id[%d] {hmac_roam_connect_complete_etc::roam disabled!}",
503 hmac_vap->vap_id);
504 return;
505 }
506
507 if (result == OAL_SUCC) {
508 hmac_roam_main_fsm_action_etc(roam_info, ROAM_MAIN_FSM_EVENT_CONNECT_SUCC, OAL_PTR_NULL);
509 } else if (result == OAL_ERR_CODE_ROAM_HANDSHAKE_FAIL) {
510 hmac_roam_main_fsm_action_etc(roam_info, ROAM_MAIN_FSM_EVENT_HANDSHAKE_FAIL, OAL_PTR_NULL);
511 } else if (result == OAL_ERR_CODE_ROAM_NO_RESPONSE) {
512 hmac_roam_main_fsm_action_etc(roam_info, ROAM_MAIN_FSM_EVENT_CONNECT_FAIL, OAL_PTR_NULL);
513 } else {
514 hmac_roam_main_fsm_action_etc(roam_info, ROAM_MAIN_FSM_EVENT_TIMEOUT, OAL_PTR_NULL);
515 }
516 }
517
518 /*****************************************************************************
519 函 数 名 : hmac_roam_start_join
520 功能描述 : 启动定时器用来接收tbtt中断
521 输出参数 : 无
522 返 回 值 : OAL_SUCC 或 失败错误码
523 *****************************************************************************/
hmac_roam_start_join(hmac_roam_info_stru * roam_info,osal_void * p_param)524 OAL_STATIC osal_u32 hmac_roam_start_join(hmac_roam_info_stru *roam_info, osal_void *p_param)
525 {
526 osal_u32 ret;
527 hmac_vap_stru *hmac_vap;
528 mac_bss_dscr_stru *bss_dscr;
529 #ifdef _PRE_WLAN_FEATURE_WPA3
530 hmac_user_stru *hmac_user = roam_info->hmac_user;
531 #endif
532 ret = hmac_roam_connect_check_state(roam_info, MAC_VAP_STATE_ROAMING, ROAM_MAIN_STATE_CONNECTING,
533 ROAM_CONNECT_STATE_INIT);
534 if ((ret != OAL_SUCC)) {
535 oam_warning_log1(0, OAM_SF_ROAM, "{hmac_roam_start_join::check_state fail[%d]!}", ret);
536 return ret;
537 }
538
539 hmac_vap = roam_info->hmac_vap;
540
541 bss_dscr = (mac_bss_dscr_stru *)p_param;
542
543 (osal_void)memcpy_s(hmac_vap->supp_rates, bss_dscr->num_supp_rates,
544 bss_dscr->supp_rates, bss_dscr->num_supp_rates);
545 mac_mib_set_SupportRateSetNums(hmac_vap, bss_dscr->num_supp_rates);
546
547 ret = hmac_roam_prepare_join_info(hmac_vap, bss_dscr);
548 if ((ret != OAL_SUCC)) {
549 oam_warning_log1(0, OAM_SF_ROAM, "{hmac_roam_start_join::prepare_join_info fail[%d]!}", ret);
550 return ret;
551 }
552
553 #ifdef _PRE_WLAN_FEATURE_WPA3
554 if (hmac_vap->wpa3_roaming == OSAL_TRUE) {
555 hmac_vap->reassoc_flag = OSAL_FALSE;
556 mac_mib_set_authentication_mode(hmac_vap, WLAN_WITP_AUTH_SAE);
557 oal_set_mac_addr(hmac_user->user_mac_addr, roam_info->connect.bss_dscr->bssid);
558 hmac_fsm_change_state_etc(hmac_vap, MAC_VAP_STATE_STA_WAIT_AUTH_SEQ2);
559 ret = hmac_report_ext_auth_event(hmac_vap);
560 if (ret != OAL_SUCC) {
561 oam_warning_log1(0, OAM_SF_ROAM, "{hmac_roam_start_join::start WPA3 auth fail[%d]!}", ret);
562 return ret;
563 }
564 return OAL_SUCC;
565 }
566 #endif
567
568 hmac_roam_connect_change_state(roam_info, ROAM_CONNECT_STATE_WAIT_JOIN);
569
570 ret = hmac_roam_send_auth_seq1(roam_info);
571 if ((ret != OAL_SUCC)) {
572 hmac_roam_connect_change_state(roam_info, ROAM_CONNECT_STATE_FAIL);
573
574 /* 通知ROAM主状态机 */
575 hmac_roam_connect_complete_etc(hmac_vap, OAL_FAIL);
576 oam_warning_log2(0, OAM_SF_SCAN,
577 "vap_id[%d] {hmac_roam_process_beacon::hmac_roam_send_auth_seq1 fail[%d].}",
578 hmac_vap->vap_id, ret);
579 return ret;
580 }
581
582 return OAL_SUCC;
583 }
584
hmac_roam_encap_auth_proc(hmac_roam_info_stru * roam_info,oal_netbuf_stru ** auth_frame,osal_u16 * auth_len)585 OAL_STATIC osal_u32 hmac_roam_encap_auth_proc(hmac_roam_info_stru *roam_info, oal_netbuf_stru **auth_frame,
586 osal_u16 *auth_len)
587 {
588 mac_tx_ctl_stru *tx_ctl;
589 hmac_user_stru *hmac_user = roam_info->hmac_user;
590 osal_void *fhook = OSAL_NULL;
591
592 *auth_frame = OAL_MEM_NETBUF_ALLOC(OAL_NORMAL_NETBUF, WLAN_MEM_NETBUF_SIZE2, OAL_NETBUF_PRIORITY_MID);
593 if (*auth_frame == OAL_PTR_NULL) {
594 oam_error_log1(0, OAM_SF_ROAM, "vap_id[%d] {hmac_roam_encap_auth_proc::OAL_MEM_NETBUF_ALLOC fail.}",
595 roam_info->hmac_vap->vap_id);
596 return OAL_ERR_CODE_ALLOC_MEM_FAIL;
597 }
598
599 memset_s(oal_netbuf_cb(*auth_frame), OAL_NETBUF_CB_SIZE(), 0, OAL_NETBUF_CB_SIZE());
600
601 memset_s((osal_u8 *)oal_netbuf_header(*auth_frame), MAC_80211_FRAME_LEN, 0, MAC_80211_FRAME_LEN);
602
603 /* 更新用户mac */
604 oal_set_mac_addr(hmac_user->user_mac_addr, roam_info->connect.bss_dscr->bssid);
605
606 *auth_len = hmac_mgmt_encap_auth_req_etc(roam_info->hmac_vap, (osal_u8 *)(OAL_NETBUF_HEADER(*auth_frame)));
607 if (*auth_len < OAL_AUTH_IE_OFFSET) {
608 hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, OAL_PTR_NULL);
609 oam_warning_log1(0, OAM_SF_ROAM, "vap_id[%d] {hmac_roam_encap_auth_proc::encap auth req failed.}",
610 roam_info->hmac_vap->vap_id);
611 oal_netbuf_free(*auth_frame);
612 return OAL_ERR_CODE_ROAM_FRAMER_LEN;
613 }
614
615 fhook = hmac_get_feature_fhook(HMAC_FHOOK_MBO_STA_ATTACH_MBO_IE_AUTH);
616 if (fhook != OSAL_NULL) {
617 ((hmac_roam_attach_mbo_ie_auth_cb)fhook)(roam_info->hmac_vap, (osal_u8 *)(oal_netbuf_header(*auth_frame)),
618 auth_len, roam_info->connect.bss_dscr);
619 }
620
621 oal_netbuf_put(*auth_frame, *auth_len);
622
623 /* 为填写发送描述符准备参数 */
624 tx_ctl = (mac_tx_ctl_stru *)oal_netbuf_cb(*auth_frame);
625 mac_get_cb_mpdu_len(tx_ctl) = *auth_len;
626 mac_get_cb_tx_user_idx(tx_ctl) = (osal_u8)hmac_user->assoc_id;
627 mac_get_cb_netbuf_num(tx_ctl) = 1;
628
629 return OAL_CONTINUE;
630 }
631
632 /*****************************************************************************
633 函 数 名 : hmac_roam_send_auth_seq1
634 功能描述 : 发送auth_seq1,并且启动auth超时定时器
635 输出参数 : 无
636 返 回 值 : OAL_SUCC 或 失败错误码
637 *****************************************************************************/
hmac_roam_send_auth_seq1(hmac_roam_info_stru * roam_info)638 OAL_STATIC osal_u32 hmac_roam_send_auth_seq1(hmac_roam_info_stru *roam_info)
639 {
640 osal_u32 ret;
641 hmac_vap_stru *hmac_vap = roam_info->hmac_vap;
642 oal_netbuf_stru *auth_frame;
643 osal_u16 auth_len;
644
645 ret = hmac_roam_encap_auth_proc(roam_info, &auth_frame, &auth_len);
646 if (ret != OAL_CONTINUE) {
647 return ret;
648 }
649
650 /* 抛事件让dmac将该帧发送 */
651 ret = hmac_tx_mgmt_send_event_etc(hmac_vap, auth_frame, auth_len);
652 if ((ret != OAL_SUCC)) {
653 oal_netbuf_free(auth_frame);
654 oam_error_log2(0, OAM_SF_ROAM, "vap_id[%d] {hmac_roam_send_auth_seq1::send event failed[%d].}",
655 hmac_vap->vap_id, ret);
656 return ret;
657 }
658
659 hmac_roam_connect_change_state(roam_info, ROAM_CONNECT_STATE_WAIT_AUTH_COMP);
660
661 /* 启动认证超时定时器 */
662 hmac_roam_connect_start_timer(roam_info, ROAM_AUTH_TIME_MAX);
663
664 return OAL_SUCC;
665 }
666
hmac_roam_encap_reassoc_req(oal_netbuf_stru ** assoc_req_frame,osal_u32 * assoc_len,hmac_roam_info_stru * roam_info)667 OAL_STATIC osal_u32 hmac_roam_encap_reassoc_req(oal_netbuf_stru **assoc_req_frame, osal_u32 *assoc_len,
668 hmac_roam_info_stru *roam_info)
669 {
670 hmac_vap_stru *hmac_vap = roam_info->hmac_vap;
671 hmac_user_stru *hmac_user = roam_info->hmac_user;
672 mac_tx_ctl_stru *tx_ctl = OSAL_NULL;
673 osal_u32 ret;
674
675 *assoc_req_frame = OAL_MEM_NETBUF_ALLOC(OAL_NORMAL_NETBUF, WLAN_MEM_NETBUF_SIZE2, OAL_NETBUF_PRIORITY_MID);
676 if (*assoc_req_frame == OAL_PTR_NULL) {
677 oam_error_log1(0, OAM_SF_ROAM, "vap_id[%d] {hmac_roam_send_reassoc_req::paras error.}", hmac_vap->vap_id);
678 return OAL_ERR_CODE_PTR_NULL;
679 }
680
681 memset_s(oal_netbuf_cb(*assoc_req_frame), OAL_NETBUF_CB_SIZE(), 0, OAL_NETBUF_CB_SIZE());
682
683 /* 将mac header清零 */
684 memset_s((osal_u8 *)oal_netbuf_header(*assoc_req_frame), MAC_80211_FRAME_LEN, 0, MAC_80211_FRAME_LEN);
685
686 hmac_vap->reassoc_flag = OAL_TRUE;
687
688 *assoc_len = hmac_mgmt_encap_asoc_req_sta_etc(hmac_vap,
689 (osal_u8 *)(OAL_NETBUF_HEADER(*assoc_req_frame)), roam_info->old_bss.bssid, hmac_vap->bssid);
690
691 oal_netbuf_put(*assoc_req_frame, *assoc_len);
692
693 /* 帧长异常 */
694 if (*assoc_len <= OAL_ASSOC_REQ_IE_OFFSET) {
695 hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, OAL_PTR_NULL);
696 oam_error_log2(0, OAM_SF_ROAM, "vap_id[%d] {hmac_roam_send_reassoc_req::unexpected assoc len[%d].}",
697 hmac_vap->vap_id, *assoc_len);
698 oal_netbuf_free(*assoc_req_frame);
699 return OAL_FAIL;
700 }
701 hmac_user_free_asoc_req_ie(hmac_user);
702
703 /* 记录关联请求帧的部分内容,用于上报给内核 */
704 ret = hmac_user_set_asoc_req_ie(hmac_user, OAL_NETBUF_HEADER(*assoc_req_frame) + OAL_ASSOC_REQ_IE_OFFSET,
705 *assoc_len - OAL_ASSOC_REQ_IE_OFFSET, OAL_TRUE);
706 if (ret != OAL_SUCC) {
707 hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, *assoc_req_frame);
708 oam_error_log1(0, OAM_SF_ROAM, "vap_id[%d] {hmac_roam_send_reassoc_req::set ie fail}", hmac_vap->vap_id);
709 oal_netbuf_free(*assoc_req_frame);
710 return OAL_FAIL;
711 }
712
713 /* 为填写发送描述符准备参数 */
714 tx_ctl = (mac_tx_ctl_stru *)oal_netbuf_cb(*assoc_req_frame);
715 mac_get_cb_mpdu_len(tx_ctl) = (osal_u16)*assoc_len;
716 mac_get_cb_tx_user_idx(tx_ctl) = (osal_u8)hmac_user->assoc_id;
717 mac_get_cb_netbuf_num(tx_ctl) = 1;
718
719 return OAL_SUCC;
720 }
721
722 /*****************************************************************************
723 函 数 名 : hmac_roam_send_assoc_req
724 功能描述 : 发送assoc req,并且启动assoc超时定时器
725 输出参数 : 无
726 返 回 值 : OAL_SUCC 或 失败错误码
727 *****************************************************************************/
hmac_roam_send_reassoc_req(hmac_roam_info_stru * roam_info)728 osal_u32 hmac_roam_send_reassoc_req(hmac_roam_info_stru *roam_info)
729 {
730 hmac_vap_stru *hmac_vap = roam_info->hmac_vap;
731 hmac_user_stru *hmac_user = roam_info->hmac_user;
732 oal_netbuf_stru *assoc_req_frame;
733 osal_u32 assoc_len;
734 osal_u32 ret;
735
736 ret = hmac_roam_encap_reassoc_req(&assoc_req_frame, &assoc_len, roam_info);
737 if (ret != OAL_SUCC) {
738 return ret;
739 }
740
741 /* 抛事件让dmac将该帧发送 */
742 ret = hmac_tx_mgmt_send_event_etc(hmac_vap, assoc_req_frame, (osal_u16)assoc_len);
743 if (ret != OAL_SUCC) {
744 oal_netbuf_free(assoc_req_frame);
745 hmac_user_free_asoc_req_ie(hmac_user);
746 oam_error_log2(0, OAM_SF_ROAM, "vap_id[%d] {hmac_roam_send_reassoc_req::tx_mgmt_send_event failed[%d].}",
747 hmac_vap->vap_id, ret);
748 return ret;
749 }
750
751 /* 启动关联超时定时器 */
752 hmac_roam_connect_start_timer(roam_info, ROAM_ASSOC_TIME_MAX);
753
754 hmac_roam_connect_change_state(roam_info, ROAM_CONNECT_STATE_WAIT_ASSOC_COMP);
755
756 return OAL_SUCC;
757 }
758
759 /*****************************************************************************
760 函 数 名 : hmac_roam_process_auth_seq2
761 输出参数 : 无
762 返 回 值 : OAL_SUCC 或 失败错误码
763 *****************************************************************************/
hmac_roam_process_auth_seq2(hmac_roam_info_stru * roam_info,osal_void * p_param)764 OAL_STATIC osal_u32 hmac_roam_process_auth_seq2(hmac_roam_info_stru *roam_info, osal_void *p_param)
765 {
766 osal_u32 ret;
767 hmac_vap_stru *hmac_vap = OSAL_NULL;
768 hmac_user_stru *hmac_user = OSAL_NULL;
769 mac_rx_ctl_stru *pst_rx_ctrl = OSAL_NULL;
770 osal_u8 *mac_hdr = OSAL_NULL;
771 osal_u8 bssid[WLAN_MAC_ADDR_LEN] = {0};
772 osal_u16 auth_status;
773 osal_u8 frame_sub_type;
774 osal_u16 auth_seq_num;
775 osal_void *fhook = hmac_get_feature_fhook(HMAC_FHOOK_11R_AUTH_SEQ2_PROCESS);
776
777 ret = hmac_roam_connect_check_state(roam_info, MAC_VAP_STATE_ROAMING, ROAM_MAIN_STATE_CONNECTING,
778 ROAM_CONNECT_STATE_WAIT_AUTH_COMP);
779 if ((ret != OAL_SUCC)) {
780 oam_warning_log1(0, OAM_SF_ROAM, "{hmac_roam_process_auth_seq2::check_state fail[%d]!}", ret);
781 return ret;
782 }
783
784 hmac_vap = roam_info->hmac_vap;
785 hmac_user = roam_info->hmac_user;
786
787 pst_rx_ctrl = (mac_rx_ctl_stru *)oal_netbuf_cb((oal_netbuf_stru *)p_param);
788 mac_hdr = (osal_u8 *)mac_get_rx_cb_mac_header_addr(pst_rx_ctrl);
789
790 mac_get_address3(mac_hdr, (osal_u8 *)bssid);
791 if (oal_compare_mac_addr(hmac_user->user_mac_addr, (const osal_u8 *)bssid) != 0) {
792 return OAL_SUCC;
793 }
794
795 frame_sub_type = mac_get_frame_type_and_subtype(mac_hdr);
796 auth_seq_num = mac_get_auth_seq_num(mac_hdr, mac_get_rx_cb_payload_len(pst_rx_ctrl));
797 auth_status = mac_get_auth_status(mac_hdr);
798 /* auth_seq2帧校验,错误帧不处理,在超时中统一处理 */
799 if ((frame_sub_type != (WLAN_FC0_SUBTYPE_AUTH | WLAN_FC0_TYPE_MGT)) ||
800 (auth_seq_num != WLAN_AUTH_TRASACTION_NUM_TWO) || (auth_status != MAC_SUCCESSFUL_STATUSCODE)) {
801 return OAL_SUCC;
802 }
803
804 if (fhook != OSAL_NULL) {
805 ret = ((hmac_roam_auth_seq2_11r_process_cb)fhook)(hmac_vap, roam_info, pst_rx_ctrl, mac_hdr);
806 if (ret != OAL_CONTINUE) {
807 return ret;
808 }
809 }
810
811 if (mac_get_auth_alg(mac_hdr) != WLAN_WITP_AUTH_OPEN_SYSTEM) {
812 return OAL_SUCC;
813 }
814
815 /* 发送关联请求 */
816 ret = hmac_roam_send_reassoc_req(roam_info);
817 if (ret != OAL_SUCC) {
818 oam_error_log2(0, OAM_SF_ROAM, "vap_id[%d] {hmac_roam_process_auth_seq2::roam_send_assoc_req failed[%d].}",
819 hmac_vap->vap_id, ret);
820 return ret;
821 }
822
823 return OAL_SUCC;
824 }
825
hmac_roam_process_assoc_rsp_check_para(hmac_roam_info_stru * roam_info,osal_void * p_param,mac_rx_ctl_stru ** rx_ctrl)826 OAL_STATIC osal_u32 hmac_roam_process_assoc_rsp_check_para(hmac_roam_info_stru *roam_info,
827 osal_void *p_param, mac_rx_ctl_stru **rx_ctrl)
828 {
829 osal_u32 ret;
830 hmac_vap_stru *hmac_vap = OAL_PTR_NULL;
831 hmac_user_stru *hmac_user = OAL_PTR_NULL;
832 oal_netbuf_stru *net_buffer = OAL_PTR_NULL;
833 mac_rx_ctl_stru *pst_rx_ctrl = OAL_PTR_NULL;
834 osal_u8 *mac_hdr = OAL_PTR_NULL;
835 osal_u8 *payload = OAL_PTR_NULL;
836 mac_status_code_enum_uint16 asoc_status;
837 osal_u8 bss_addr[WLAN_MAC_ADDR_LEN];
838 osal_u8 frame_sub_type;
839
840 hmac_vap = roam_info->hmac_vap;
841 hmac_user = roam_info->hmac_user;
842
843 ret = hmac_roam_connect_check_state(roam_info, MAC_VAP_STATE_ROAMING, ROAM_MAIN_STATE_CONNECTING,
844 ROAM_CONNECT_STATE_WAIT_ASSOC_COMP);
845 if (ret != OAL_SUCC) {
846 oam_warning_log1(0, OAM_SF_ROAM, "{hmac_roam_process_assoc_rsp_check_para::check_state fail[%d]!}", ret);
847 return ret;
848 }
849
850 net_buffer = (oal_netbuf_stru *)p_param;
851 pst_rx_ctrl = (mac_rx_ctl_stru *)oal_netbuf_cb(net_buffer);
852 mac_hdr = (osal_u8 *)mac_get_rx_cb_mac_header_addr(pst_rx_ctrl);
853 payload = mac_hdr + pst_rx_ctrl->mac_header_len;
854
855 *rx_ctrl = pst_rx_ctrl; /* 把解析出来的pst_rx_ctrl传出去 */
856
857 /* mac地址校验 */
858 mac_get_address3(mac_hdr, (osal_u8 *)bss_addr);
859 if (oal_compare_mac_addr(hmac_user->user_mac_addr, (const osal_u8 *)bss_addr) != 0) {
860 return OAL_SUCC;
861 }
862
863 /* assoc帧校验,错误帧处理 */
864 frame_sub_type = mac_get_frame_type_and_subtype(mac_hdr);
865 asoc_status = mac_get_asoc_status(payload);
866
867 if ((frame_sub_type != (WLAN_FC0_SUBTYPE_REASSOC_RSP | WLAN_FC0_TYPE_MGT)) &&
868 (frame_sub_type != (WLAN_FC0_SUBTYPE_ASSOC_RSP | WLAN_FC0_TYPE_MGT))) {
869 return OAL_SUCC;
870 }
871
872 /* 关联响应帧长度校验 */
873 if (pst_rx_ctrl->frame_len <= OAL_ASSOC_RSP_IE_OFFSET) {
874 oam_warning_log2(0, OAM_SF_ROAM,
875 "vap_id[%d] {hmac_roam_process_assoc_rsp_check_para::rsp ie length error, len[%d].}",
876 hmac_vap->vap_id, pst_rx_ctrl->frame_len);
877 return OAL_ERR_CODE_ROAM_FRAMER_LEN;
878 }
879
880 roam_info->connect.status_code = MAC_SUCCESSFUL_STATUSCODE;
881
882 if (asoc_status != MAC_SUCCESSFUL_STATUSCODE) {
883 roam_info->connect.status_code = asoc_status;
884 return OAL_SUCC;
885 }
886
887 return OAL_CONTINUE;
888 }
889
890 /*****************************************************************************
891 函 数 名 : hmac_roam_process_assoc_rsp
892 功能描述 : 根据关联响应中的ie,更新本地用户能力及vap能力
893 输出参数 : 无
894 返 回 值 : OAL_SUCC 或 失败错误码
895 *****************************************************************************/
hmac_roam_process_assoc_rsp(hmac_roam_info_stru * roam_info,osal_void * p_param)896 OAL_STATIC osal_u32 hmac_roam_process_assoc_rsp(hmac_roam_info_stru *roam_info, osal_void *p_param)
897 {
898 osal_u32 ret;
899 hmac_vap_stru *hmac_vap;
900 hmac_user_stru *hmac_user;
901 mac_rx_ctl_stru *pst_rx_ctrl = OAL_PTR_NULL;
902 osal_u8 *mac_hdr, *payload;
903 osal_void *fhook = hmac_get_feature_fhook(HMAC_FHOOK_11R_PROCESS_ASSOC_RSP);
904
905 ret = hmac_roam_process_assoc_rsp_check_para(roam_info, p_param, &pst_rx_ctrl);
906 if (ret != OAL_CONTINUE) {
907 return ret;
908 }
909
910 hmac_vap = roam_info->hmac_vap;
911 hmac_user = roam_info->hmac_user;
912 mac_hdr = (osal_u8 *)mac_get_rx_cb_mac_header_addr(pst_rx_ctrl);
913 payload = mac_hdr + pst_rx_ctrl->mac_header_len;
914
915 ret = hmac_process_assoc_rsp_etc(hmac_vap, hmac_user, mac_hdr, pst_rx_ctrl->mac_header_len,
916 payload, pst_rx_ctrl->frame_len - pst_rx_ctrl->mac_header_len);
917 if (ret != OAL_SUCC) {
918 oam_warning_log2(0, OAM_SF_ROAM, "vap_id[%d] {hmac_roam_process_assoc_rsp:: process assoc rsp failed[%d]}",
919 hmac_vap->vap_id, ret);
920 return ret;
921 }
922
923 /* user已经关联上,抛事件给DMAC,在DMAC层挂用户算法钩子 */
924 hmac_user_add_notify_alg_etc(hmac_vap, hmac_user->assoc_id);
925
926 /* 上报关联成功消息给APP */
927 ret = hmac_roam_connect_notify_wpas(roam_info, mac_hdr, pst_rx_ctrl->frame_len);
928 if (ret != OAL_SUCC) {
929 oam_error_log2(0, OAM_SF_ROAM, "vap_id[%d] {hmac_roam_process_assoc_rsp:: connect notify wpas failed[%d]}",
930 hmac_vap->vap_id, ret);
931 return ret;
932 }
933
934 if (fhook != OSAL_NULL) {
935 ret = ((hmac_11r_process_assoc_rsp_cb)fhook)(hmac_vap, roam_info);
936 if (ret == OAL_SUCC) {
937 return OAL_SUCC;
938 }
939 }
940
941 if (mac_mib_get_privacyinvoked(hmac_vap) != OSAL_TRUE) {
942 /* 非加密情况下,漫游成功 */
943 hmac_roam_connect_change_state(roam_info, ROAM_CONNECT_STATE_HANDSHAKING);
944 hmac_roam_connect_succ(roam_info, OAL_PTR_NULL);
945 } else {
946 if (mac_mib_get_rsnaactivated(hmac_vap) == OAL_TRUE) {
947 hmac_roam_connect_change_state(roam_info, ROAM_CONNECT_STATE_HANDSHAKING);
948 /* 启动握手超时定时器 */
949 hmac_roam_connect_start_timer(roam_info, ROAM_HANDSHAKE_TIME_MAX);
950 } else {
951 /* 非 WPA 或者 WPA2 加密情况下(WEP_OPEN/WEP_SHARED),漫游成功 */
952 hmac_roam_connect_change_state(roam_info, ROAM_CONNECT_STATE_HANDSHAKING);
953 hmac_roam_connect_succ(roam_info, OAL_PTR_NULL);
954 }
955 }
956
957 return OAL_SUCC;
958 }
959
960 /*****************************************************************************
961 函 数 名 : hmac_roam_process_action
962 功能描述 : 处理漫游过程中的action帧
963 输出参数 : 无
964 返 回 值 : OAL_SUCC 或 失败错误码
965 *****************************************************************************/
hmac_roam_process_action(hmac_roam_info_stru * roam_info,osal_void * p_param)966 OAL_STATIC osal_u32 hmac_roam_process_action(hmac_roam_info_stru *roam_info, osal_void *p_param)
967 {
968 osal_u32 ret;
969 hmac_vap_stru *hmac_vap;
970 hmac_user_stru *hmac_user;
971 oal_netbuf_stru *net_buffer;
972 mac_rx_ctl_stru *pst_rx_ctrl;
973 osal_u8 *mac_hdr;
974 osal_u8 *payload;
975 osal_u8 bss_addr[WLAN_MAC_ADDR_LEN];
976 osal_u8 frame_sub_type;
977
978 ret = hmac_roam_connect_check_state(roam_info, MAC_VAP_STATE_ROAMING, ROAM_MAIN_STATE_CONNECTING,
979 ROAM_CONNECT_STATE_HANDSHAKING);
980 if (ret != OAL_SUCC) {
981 oam_warning_log1(0, OAM_SF_ROAM, "{hmac_roam_process_action::check_state fail[%d]!}", ret);
982 return ret;
983 }
984
985 hmac_vap = roam_info->hmac_vap;
986 hmac_user = roam_info->hmac_user;
987
988 net_buffer = (oal_netbuf_stru *)p_param;
989 pst_rx_ctrl = (mac_rx_ctl_stru *)oal_netbuf_cb(net_buffer);
990 mac_hdr = (osal_u8 *)mac_get_rx_cb_mac_header_addr(pst_rx_ctrl);
991 payload = mac_hdr + pst_rx_ctrl->mac_header_len;
992
993 /* mac地址校验 */
994 mac_get_address3(mac_hdr, (osal_u8 *)bss_addr);
995 if (oal_compare_mac_addr(hmac_user->user_mac_addr, (const osal_u8 *)bss_addr) != 0) {
996 return OAL_SUCC;
997 }
998
999 frame_sub_type = mac_get_frame_type_and_subtype(mac_hdr);
1000 if (frame_sub_type != (WLAN_FC0_SUBTYPE_ACTION | WLAN_FC0_TYPE_MGT)) {
1001 return OAL_SUCC;
1002 }
1003
1004 if (payload[MAC_ACTION_OFFSET_CATEGORY] == MAC_ACTION_CATEGORY_BA) {
1005 oam_warning_log2(0, OAM_SF_ROAM,
1006 "vap_id[%d] {hmac_roam_process_action::BA_ACTION_TYPE [%d].}", hmac_vap->vap_id,
1007 payload[MAC_ACTION_OFFSET_ACTION]);
1008 switch (payload[MAC_ACTION_OFFSET_ACTION]) {
1009 case MAC_BA_ACTION_ADDBA_REQ:
1010 ret = hmac_mgmt_rx_addba_req_etc(hmac_vap, hmac_user, payload);
1011 break;
1012
1013 case MAC_BA_ACTION_ADDBA_RSP:
1014 ret = hmac_mgmt_rx_addba_rsp_etc(hmac_vap, hmac_user, payload);
1015 break;
1016
1017 case MAC_BA_ACTION_DELBA:
1018 ret = hmac_mgmt_rx_delba_etc(hmac_vap, hmac_user, payload);
1019 break;
1020
1021 default:
1022 break;
1023 }
1024 }
1025
1026 return ret;
1027 }
1028
1029 /*****************************************************************************
1030 函 数 名 : hmac_roam_connect_succ
1031 功能描述 : 关联过程成功后,通知roam main状态机
1032 输出参数 : 无
1033 返 回 值 : OAL_SUCC 或 失败错误码
1034 *****************************************************************************/
hmac_roam_connect_succ(hmac_roam_info_stru * roam_info,osal_void * param)1035 osal_u32 hmac_roam_connect_succ(hmac_roam_info_stru *roam_info, osal_void *param)
1036 {
1037 osal_u32 ret;
1038
1039 unref_param(param);
1040
1041 ret = hmac_roam_connect_check_state(roam_info, MAC_VAP_STATE_ROAMING, ROAM_MAIN_STATE_CONNECTING,
1042 ROAM_CONNECT_STATE_HANDSHAKING);
1043 if (ret != OAL_SUCC) {
1044 oam_warning_log1(0, OAM_SF_ROAM, "{hmac_roam_connect_succ::check_state fail[%d]!}", ret);
1045 return ret;
1046 }
1047
1048 hmac_roam_connect_change_state(roam_info, ROAM_CONNECT_STATE_UP);
1049
1050 /* 删除定时器 */
1051 ret = hmac_roam_connect_del_timer(roam_info);
1052 if (ret != OAL_SUCC) {
1053 oam_warning_log1(0, OAM_SF_ROAM, "{hmac_roam_connect_succ::hmac_roam_connect_del_timer fail[%d]!}", ret);
1054 }
1055
1056 /* 通知ROAM主状态机 */
1057 hmac_roam_connect_complete_etc(roam_info->hmac_vap, OAL_SUCC);
1058
1059 return OAL_SUCC;
1060 }
1061
1062 /*****************************************************************************
1063 函 数 名 : hmac_roam_auth_timeout
1064 功能描述 : 处理认证超时,漫游期间最多5次auth
1065 输出参数 : 无
1066 返 回 值 : OAL_SUCC 或 失败错误码
1067 *****************************************************************************/
hmac_roam_auth_timeout(hmac_roam_info_stru * roam_info,osal_void * p_param)1068 OAL_STATIC osal_u32 hmac_roam_auth_timeout(hmac_roam_info_stru *roam_info, osal_void *p_param)
1069 {
1070 osal_u32 ret;
1071 hmac_vap_stru *hmac_vap;
1072
1073 unref_param(p_param);
1074 ret = hmac_roam_connect_check_state(roam_info, MAC_VAP_STATE_ROAMING, ROAM_MAIN_STATE_CONNECTING,
1075 ROAM_CONNECT_STATE_WAIT_AUTH_COMP);
1076 if (ret != OAL_SUCC) {
1077 oam_warning_log1(0, OAM_SF_ROAM, "{hmac_roam_auth_timeout::check_state fail[%d]!}", ret);
1078 return ret;
1079 }
1080
1081 hmac_vap = roam_info->hmac_vap;
1082
1083 if (++roam_info->connect.auth_num >= MAX_AUTH_CNT) {
1084 return hmac_roam_connect_fail(roam_info);
1085 }
1086
1087 ret = hmac_roam_send_auth_seq1(roam_info);
1088 if (ret != OAL_SUCC) {
1089 oam_error_log2(0, OAM_SF_ROAM,
1090 "vap_id[%d] {hmac_roam_auth_timeout::hmac_roam_send_auth_seq1 failed[%d].}",
1091 hmac_vap->vap_id, ret);
1092 }
1093
1094 return ret;
1095 }
1096
1097 /*****************************************************************************
1098 函 数 名 : hmac_roam_assoc_timeout
1099 功能描述 : 处理关联超时,漫游期间最多5次auth
1100 输出参数 : 无
1101 返 回 值 : OAL_SUCC 或 失败错误码
1102 *****************************************************************************/
hmac_roam_assoc_timeout(hmac_roam_info_stru * roam_info,osal_void * p_param)1103 OAL_STATIC osal_u32 hmac_roam_assoc_timeout(hmac_roam_info_stru *roam_info, osal_void *p_param)
1104 {
1105 osal_u32 ret;
1106
1107 unref_param(p_param);
1108 ret = hmac_roam_connect_check_state(roam_info, MAC_VAP_STATE_ROAMING, ROAM_MAIN_STATE_CONNECTING,
1109 ROAM_CONNECT_STATE_WAIT_ASSOC_COMP);
1110 if (ret != OAL_SUCC) {
1111 oam_warning_log1(0, OAM_SF_ROAM, "{hmac_roam_assoc_timeout::check_state fail[%d]!}", ret);
1112 return ret;
1113 }
1114
1115 if ((++roam_info->connect.assoc_num >= MAX_ASOC_CNT) || (roam_info->connect.status_code == MAC_REJECT_TEMP)) {
1116 return hmac_roam_connect_fail(roam_info);
1117 }
1118
1119 ret = hmac_roam_send_reassoc_req(roam_info);
1120 if (ret != OAL_SUCC) {
1121 oam_error_log1(0, OAM_SF_ROAM, "{hmac_roam_assoc_timeout::hmac_roam_send_reassoc_req failed[%d].}", ret);
1122 }
1123 return ret;
1124 }
1125
1126 /*****************************************************************************
1127 函 数 名 : hmac_roam_handshaking_timeout
1128 功能描述 : 处理握手超时
1129 输出参数 : 无
1130 返 回 值 : OAL_SUCC 或 失败错误码
1131 *****************************************************************************/
hmac_roam_handshaking_timeout(hmac_roam_info_stru * roam_info,osal_void * p_param)1132 OAL_STATIC osal_u32 hmac_roam_handshaking_timeout(hmac_roam_info_stru *roam_info, osal_void *p_param)
1133 {
1134 osal_u32 ret;
1135
1136 unref_param(p_param);
1137 ret = hmac_roam_connect_check_state(roam_info, MAC_VAP_STATE_ROAMING, ROAM_MAIN_STATE_CONNECTING,
1138 ROAM_CONNECT_STATE_HANDSHAKING);
1139 if (ret != OAL_SUCC) {
1140 oam_warning_log1(0, OAM_SF_ROAM, "{hmac_roam_handshaking_timeout::check_state fail[%d]!}", ret);
1141 return ret;
1142 }
1143
1144 return hmac_roam_connect_fail(roam_info);
1145 }
1146
1147 /*****************************************************************************
1148 函 数 名 : hmac_roam_connect_stop_etc
1149 功能描述 : 停止connect状态机,删除connect定时器。并通知roam main状态机
1150 输出参数 : 无
1151 返 回 值 : OAL_SUCC 或 失败错误码
1152 *****************************************************************************/
hmac_roam_connect_fail(hmac_roam_info_stru * roam_info)1153 osal_u32 hmac_roam_connect_fail(hmac_roam_info_stru *roam_info)
1154 {
1155 hmac_vap_stru *hmac_vap = roam_info->hmac_vap;
1156 roam_connect_state_enum_uint8 connect_state = roam_info->connect.state;
1157
1158 /* connect状态切换 */
1159 hmac_roam_connect_change_state(roam_info, ROAM_CONNECT_STATE_FAIL);
1160
1161 /* connect失败时,需要添加到黑名单 */
1162 hmac_roam_alg_add_blacklist_etc(roam_info, roam_info->connect.bss_dscr->bssid,
1163 ROAM_BLACKLIST_TYPE_REJECT_AP);
1164 oam_warning_log1(0, OAM_SF_ROAM,
1165 "vap_id[%d] {hmac_roam_connect_fail::hmac_roam_alg_add_blacklist_etc!}",
1166 hmac_vap->vap_id);
1167
1168 /* 通知ROAM主状态机,BSS回退由主状态机完成 */
1169
1170 if (connect_state == ROAM_CONNECT_STATE_HANDSHAKING) {
1171 hmac_roam_connect_complete_etc(hmac_vap, OAL_ERR_CODE_ROAM_HANDSHAKE_FAIL);
1172 } else if ((connect_state == ROAM_CONNECT_STATE_WAIT_ASSOC_COMP) || \
1173 (connect_state == ROAM_CONNECT_STATE_WAIT_AUTH_COMP)) {
1174 hmac_roam_connect_complete_etc(hmac_vap, OAL_ERR_CODE_ROAM_NO_RESPONSE);
1175 } else {
1176 hmac_roam_connect_complete_etc(hmac_vap, OAL_FAIL);
1177 }
1178
1179 return OAL_SUCC;
1180 }
1181 /*****************************************************************************
1182 函 数 名 : hmac_roam_connect_start_etc
1183 输出参数 : 无
1184 返 回 值 : OAL_SUCC 或 失败错误码
1185 *****************************************************************************/
hmac_roam_connect_start_etc(hmac_vap_stru * hmac_vap,mac_bss_dscr_stru * bss_dscr)1186 osal_u32 hmac_roam_connect_start_etc(hmac_vap_stru *hmac_vap, mac_bss_dscr_stru *bss_dscr)
1187 {
1188 hmac_roam_info_stru *roam_info;
1189 osal_u32 ret;
1190 osal_void *fhook = hmac_get_feature_fhook(HMAC_FHOOK_11R_ROAM_CONNECT_START_ETC);
1191
1192 if (hmac_vap == OAL_PTR_NULL) {
1193 oam_error_log0(0, OAM_SF_ROAM, "{hmac_roam_connect_start_etc::vap null!}");
1194 return OAL_ERR_CODE_ROAM_INVALID_VAP;
1195 }
1196
1197 roam_info = hmac_get_roam_info(hmac_vap->vap_id);
1198
1199 roam_info->connect.bss_dscr = bss_dscr;
1200 roam_info->connect.auth_num = 0;
1201 roam_info->connect.assoc_num = 0;
1202 roam_info->connect.ft_num = 0;
1203
1204 if (fhook != OSAL_NULL) {
1205 ret = ((hmac_11r_roam_connect_start_etc_cb)fhook)(hmac_vap, roam_info, bss_dscr);
1206 if (ret != OAL_CONTINUE) {
1207 return ret;
1208 }
1209 }
1210
1211 return hmac_roam_connect_fsm_action_etc(roam_info, ROAM_CONNECT_FSM_EVENT_START, (osal_void *)bss_dscr);
1212 }
1213
1214 /*****************************************************************************
1215 函 数 名 : hmac_roam_connect_stop_etc
1216 输出参数 : 无
1217 返 回 值 : OAL_SUCC 或 失败错误码
1218 *****************************************************************************/
hmac_roam_connect_stop_etc(hmac_vap_stru * hmac_vap)1219 osal_u32 hmac_roam_connect_stop_etc(hmac_vap_stru *hmac_vap)
1220 {
1221 hmac_roam_info_stru *roam_info = OSAL_NULL;
1222
1223 if (hmac_vap == OSAL_NULL) {
1224 oam_error_log0(0, OAM_SF_ROAM, "{hmac_roam_connect_start_etc::vap null!}");
1225 return OAL_ERR_CODE_ROAM_INVALID_VAP;
1226 }
1227
1228 roam_info = hmac_get_roam_info(hmac_vap->vap_id);
1229 roam_info->connect.state = ROAM_CONNECT_STATE_INIT;
1230 return OAL_SUCC;
1231 }
1232
1233 /*****************************************************************************
1234 函 数 名 : hmac_roam_connect_rx_mgmt_etc
1235 输出参数 : 无
1236 返 回 值 : OAL_SUCC 或 失败错误码
1237 *****************************************************************************/
hmac_roam_connect_rx_mgmt_etc(oal_netbuf_stru * netbuf,hmac_vap_stru * hmac_vap)1238 osal_u32 hmac_roam_connect_rx_mgmt_etc(oal_netbuf_stru *netbuf, hmac_vap_stru *hmac_vap)
1239 {
1240 hmac_roam_info_stru *roam_info;
1241 osal_u32 ret;
1242
1243 roam_info = hmac_get_roam_info(hmac_vap->vap_id);
1244 if (roam_info == OAL_PTR_NULL) {
1245 return OAL_CONTINUE;
1246 }
1247
1248 /* 漫游开关没有开时,不处理管理帧接收 */
1249 if (roam_info->enable == 0) {
1250 return OAL_CONTINUE;
1251 }
1252
1253 ret = hmac_roam_connect_fsm_action_etc(roam_info, ROAM_CONNECT_FSM_EVENT_MGMT_RX, (osal_void *)netbuf);
1254 if (ret != OAL_CONTINUE) {
1255 oal_netbuf_free(netbuf);
1256 return OAL_SUCC;
1257 }
1258
1259 return OAL_CONTINUE;
1260 }
1261
1262 /*****************************************************************************
1263 函 数 名 : hmac_roam_connect_key_done_etc
1264 输出参数 : 无
1265 返 回 值 : OAL_SUCC 或 失败错误码
1266 *****************************************************************************/
hmac_roam_connect_key_done_etc(hmac_vap_stru * hmac_vap)1267 osal_void hmac_roam_connect_key_done_etc(hmac_vap_stru *hmac_vap)
1268 {
1269 hmac_roam_info_stru *roam_info;
1270 osal_u32 ret;
1271
1272 roam_info = hmac_get_roam_info(hmac_vap->vap_id);
1273 if (roam_info == OAL_PTR_NULL) {
1274 return;
1275 }
1276
1277 /* 漫游开关没有开时,不处理管理帧接收 */
1278 if (roam_info->enable == 0) {
1279 return;
1280 }
1281
1282 /* WPA3漫游切换状态机状态,否则主状态机为非CONNECTING状态/CONNECT状态机为非UP状态,失败 */
1283 if (hmac_vap->wpa3_roaming == OSAL_TRUE) {
1284 hmac_roam_main_change_state(roam_info, ROAM_MAIN_STATE_CONNECTING);
1285 hmac_roam_connect_change_state(roam_info, ROAM_CONNECT_STATE_HANDSHAKING);
1286 } else if (roam_info->main_state != ROAM_MAIN_STATE_CONNECTING) {
1287 return;
1288 }
1289
1290 ret = hmac_roam_connect_fsm_action_etc(roam_info, ROAM_CONNECT_FSM_EVENT_KEY_DONE, OAL_PTR_NULL);
1291 if (ret != OAL_SUCC && ret != OAL_CONTINUE) {
1292 oam_error_log2(0, OAM_SF_ROAM, "vap_id[%d] {hmac_roam_connect_key_done_etc::KEY_DONE FAIL[%d]!}",
1293 hmac_vap->vap_id, ret);
1294 }
1295 oam_warning_log0(0, OAM_SF_ROAM, "{hmac_roam_connect_key_done_etc::KEY_DONE !}");
1296
1297 return;
1298 }
1299
1300 #ifdef __cplusplus
1301 #if __cplusplus
1302 }
1303 #endif
1304 #endif
1305