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_11v.c
15 * 生成日期 : 2018年4月7日
16 * 功能描述 : 11v 功能处理
17 */
18
19
20 /*****************************************************************************
21 1 头文件包含
22 *****************************************************************************/
23 #include "hmac_11v.h"
24 #include "oal_ext_if.h"
25 #include "oal_netbuf_ext.h"
26 #include "oal_netbuf_data.h"
27 #include "oal_mem_hcm.h"
28 #include "mac_frame.h"
29 #include "mac_resource_ext.h"
30 #include "mac_ie.h"
31 #include "mac_vap_ext.h"
32 #include "mac_user_ext.h"
33 #include "frw_ext_if.h"
34 #include "wlan_types_common.h"
35 #include "dmac_ext_if_hcm.h"
36 #include "hmac_mgmt_bss_comm.h"
37 #include "hmac_roam_main.h"
38 #include "hmac_scan.h"
39 #include "hmac_feature_dft.h"
40 #include "hmac_mbo.h"
41 #include "frw_util_notifier.h"
42 #include "hmac_feature_interface.h"
43 #include "hmac_hook.h"
44
45 #ifdef __cplusplus
46 #if __cplusplus
47 extern "C" {
48 #endif
49 #endif
50
51 #undef THIS_FILE_ID
52 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_11V_C
53
54 #undef THIS_MOD_ID
55 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
56
57 /*****************************************************************************
58 2 全局变量定义
59 *****************************************************************************/
60 hmac_11v_vap_info_stru *g_11v_vap_info[WLAN_VAP_MAX_NUM_PER_DEVICE_LIMIT] = {
61 OSAL_NULL, OSAL_NULL, OSAL_NULL, OSAL_NULL
62 };
63
64 hmac_user_11v_ctrl_stru *g_11v_user_info[WLAN_USER_MAX_USER_LIMIT];
65
66 /*****************************************************************************
67 3 函数实现
68 *****************************************************************************/
69 OAL_STATIC osal_u32 hmac_rx_bsst_req_action_parses(hmac_bsst_req_info_stru *bsst_req_info,
70 osal_u8 *data, const osal_u16 frame_len, const hmac_user_stru *hmac_user);
71 OAL_STATIC osal_void hmac_rx_bsst_req_action_handle(hmac_vap_stru *hmac_vap,
72 const hmac_bsst_req_info_stru *bsst_req_info, hmac_user_11v_ctrl_stru *pst_11v_ctrl_info,
73 const hmac_user_stru *hmac_user);
74 OAL_STATIC osal_void hmac_get_neighbor_parses_all(hmac_neighbor_bss_info_stru *bss_list_alloc,
75 osal_u8 *data, const osal_u16 len, const osal_u8 bss_number);
76 OAL_STATIC osal_void hmac_get_neighbor_parses_bssid(hmac_neighbor_bss_info_stru *bss_list_alloc,
77 const osal_u8 bss_list_index, const osal_u8 *ie_data);
78 /* 将Neighbor Report IE结构体从帧数据中解析出来 */
79 OAL_STATIC hmac_neighbor_bss_info_stru *hmac_get_neighbor_ie(osal_u8 *data, osal_u16 len,
80 osal_u8 *bss_num);
81 OAL_STATIC osal_u32 hmac_tx_bsst_rsp_action(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
82 hmac_bsst_rsp_info_stru *bsst_rsp_info);
83
hmac_11v_get_vap_info(osal_u8 vap_id)84 OAL_STATIC hmac_11v_vap_info_stru *hmac_11v_get_vap_info(osal_u8 vap_id)
85 {
86 if (hmac_vap_id_param_check(vap_id) != OSAL_TRUE) {
87 return OSAL_NULL;
88 }
89
90 return g_11v_vap_info[vap_id];
91 }
92
hmac_11v_get_user_info(osal_u8 user_idx)93 OAL_STATIC hmac_user_11v_ctrl_stru *hmac_11v_get_user_info(osal_u8 user_idx)
94 {
95 if (osal_unlikely(user_idx >= WLAN_USER_MAX_USER_LIMIT)) {
96 return OSAL_NULL;
97 }
98
99 return g_11v_user_info[user_idx];
100 }
101
hmac_11v_get_roam_info(osal_u8 vap_id)102 OAL_STATIC hmac_11v_vap_roam_info_stru *hmac_11v_get_roam_info(osal_u8 vap_id)
103 {
104 hmac_11v_vap_info_stru *hmac_11v_vap_info = hmac_11v_get_vap_info(vap_id);
105
106 if (hmac_11v_vap_info == OSAL_NULL) {
107 return OSAL_NULL;
108 }
109
110 return hmac_11v_vap_info->roam_info_11v;
111 }
112
113 /*****************************************************************************
114 函 数 名 : hmac_11v_roam_scan_check
115 功能描述 : STA 11v trigger类型的漫游后,检查漫游扫描结果
116
117 输入参数 : hmac_vap_stru *hmac_vap
118 输出参数 : osal_u32
119 返 回 值 : 0:成功,其他:失败
120 调用函数 : 无
121 被调函数 : 无
122 *****************************************************************************/
hmac_11v_roam_scan_check(hmac_vap_stru * hmac_vap)123 OAL_STATIC osal_u32 hmac_11v_roam_scan_check(hmac_vap_stru *hmac_vap)
124 {
125 hmac_user_stru *hmac_user;
126 hmac_user_11v_ctrl_stru *pst_11v_ctrl_info;
127 hmac_roam_info_stru *roam_info = hmac_get_roam_info(hmac_vap->vap_id);
128 hmac_11v_vap_roam_info_stru *roam_info_11v = hmac_11v_get_roam_info(hmac_vap->vap_id);
129
130 if (roam_info == OAL_PTR_NULL || roam_info_11v == OSAL_NULL) {
131 oam_error_log0(0, OAM_SF_ANY, "{hmac_11v_roam_scan_check::roam_info/roam_info_11v IS NULL}");
132 return OAL_ERR_CODE_ROAM_INVALID_VAP;
133 }
134
135 /* 获取发送端的用户指针 */
136 hmac_user = mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
137 if (hmac_user == OAL_PTR_NULL) {
138 oam_error_log0(0, OAM_SF_ANY, "{hmac_11v_roam_scan_check::hmac_user is NULL}");
139 return OAL_ERR_CODE_ROAM_INVALID_USER;
140 }
141
142 pst_11v_ctrl_info = hmac_11v_get_user_info((osal_u8)hmac_user->assoc_id);
143 if (pst_11v_ctrl_info == OSAL_NULL) {
144 return OAL_ERR_CODE_PTR_NULL;
145 }
146
147 if (pst_11v_ctrl_info->mac_11v_callback_fn == OAL_PTR_NULL) {
148 return OAL_SUCC;
149 }
150
151 if (pst_11v_ctrl_info->uc_11v_roam_scan_times < MAC_11V_ROAM_SCAN_ONE_CHANNEL_LIMIT) {
152 /* 触发单信道扫描漫游 */
153 pst_11v_ctrl_info->uc_11v_roam_scan_times++;
154 oam_warning_log3(0, OAM_SF_ANY, "{One channel scan roam,11v_roam_scan_times=[%d],limit_times=[%d]channel=[%d]}",
155 pst_11v_ctrl_info->uc_11v_roam_scan_times,
156 MAC_11V_ROAM_SCAN_ONE_CHANNEL_LIMIT, roam_info_11v->bsst_rsp_info.chl_num);
157 hmac_roam_start_etc(hmac_vap, ROAM_SCAN_CHANNEL_ORG_1, OAL_FALSE, ROAM_TRIGGER_11V);
158 } else if (pst_11v_ctrl_info->uc_11v_roam_scan_times == MAC_11V_ROAM_SCAN_ONE_CHANNEL_LIMIT) {
159 /* 触发全信道扫描漫游 */
160 pst_11v_ctrl_info->uc_11v_roam_scan_times++;
161 oam_warning_log0(0, OAM_SF_ANY, "{hmac_11v_roam_scan_check::Trigger ALL Channel scan roam.}");
162 hmac_roam_start_etc(hmac_vap, ROAM_SCAN_CHANNEL_ORG_BUTT, OAL_FALSE, ROAM_TRIGGER_11V);
163 }
164 return OAL_SUCC;
165 }
166
167 /*****************************************************************************
168 函 数 名 : hmac_rx_bsst_req_candidate_info_check
169 功能描述 : 检查channel是否在管制域内或是否存在扫描列表内
170 输出参数 : osal_u32
171 返 回 值 : 0:成功,其他:失败
172 调用函数 : 无
173 被调函数 : 无
174 *****************************************************************************/
hmac_rx_bsst_req_candidate_info_check(hmac_vap_stru * hmac_vap,osal_u8 channel,osal_u8 * bssid)175 OAL_STATIC osal_u32 hmac_rx_bsst_req_candidate_info_check(hmac_vap_stru *hmac_vap, osal_u8 channel,
176 osal_u8 *bssid)
177 {
178 wlan_channel_band_enum_uint8 channel_band;
179 osal_u32 check;
180 mac_bss_dscr_stru *bss_dscr;
181
182 channel_band = mac_get_band_by_channel_num(channel);
183 check = hmac_is_channel_num_valid_etc(channel_band, channel);
184 if (check != OAL_SUCC) {
185 /* 对于无效channel如果bssid存在扫描列表中则继续11v漫游流程 */
186 bss_dscr = (mac_bss_dscr_stru *)hmac_scan_get_scanned_bss_by_bssid(hmac_vap,
187 bssid);
188 if (bss_dscr != OAL_PTR_NULL) {
189 oam_warning_log1(0, OAM_SF_CFG, "in bssinfo channel=[%d]", bss_dscr->st_channel.chan_number);
190 /* 0:1:2:3:数组下标 */
191 oam_warning_log4(0, OAM_SF_CFG, "bssid:%02X:%02X:%02X:%02X:XX:XX", bssid[0], bssid[1], bssid[2], bssid[3]);
192 oam_warning_log1(0, OAM_SF_CFG, "channel=[%d] is invalid", channel);
193 return OAL_SUCC;
194 }
195
196 return OAL_FAIL;
197 }
198
199 return OAL_SUCC;
200 }
201
202 /* 根据接收到的BTM REQ中信息,找出偏好最高的,合适的进行切换 */
hmac_handle_neighbor_list(const hmac_bsst_req_info_stru * bsst_req_info,hmac_vap_stru * hmac_vap,const hmac_user_stru * hmac_user,oal_bool_enum_uint8 * need_roam)203 OAL_STATIC hmac_neighbor_bss_info_stru *hmac_handle_neighbor_list(const hmac_bsst_req_info_stru *bsst_req_info,
204 hmac_vap_stru *hmac_vap, const hmac_user_stru *hmac_user, oal_bool_enum_uint8 *need_roam)
205 {
206 /* 根据终端需求实现11v漫游 */
207 osal_u32 ret;
208 osal_u8 index;
209 hmac_neighbor_bss_info_stru *best_neighbor_bss = OAL_PTR_NULL;
210
211 if ((bsst_req_info->neighbor_bss_list == OAL_PTR_NULL) || (bsst_req_info->bss_list_num == 0)) {
212 return OAL_PTR_NULL;
213 }
214
215 /* 遍历list 找出偏好值最高的作为切换 */
216 for (index = 0; index < bsst_req_info->bss_list_num; index++) {
217 /* 广播地址 无需处理 */
218 if (ETHER_IS_BROADCAST(bsst_req_info->neighbor_bss_list[index].auc_mac_addr)) {
219 oam_warning_log0(0, OAM_SF_ANY, "{hmac_handle_neighbor_list::bsst req candidate bssid is broadcast}");
220 continue;
221 }
222 /* 关联AP BSSID 无需处理 */
223 if (osal_memcmp(hmac_user->user_mac_addr,
224 bsst_req_info->neighbor_bss_list[index].auc_mac_addr, WLAN_MAC_ADDR_LEN) == 0) {
225 oam_warning_log0(0, OAM_SF_ANY,
226 "{hmac_handle_neighbor_list::bsst req candidate bssid is the same with the associated AP}");
227 continue;
228 }
229
230 oam_warning_log4(0, OAM_SF_ANY,
231 "{hmac_handle_neighbor_list::candidate bssid=%02x:%02x:%02x:%02x:xx:xx.}",
232 bsst_req_info->neighbor_bss_list[index].auc_mac_addr[0], /* 打印数组元素0 */
233 bsst_req_info->neighbor_bss_list[index].auc_mac_addr[1], /* 打印数组元素1 */
234 bsst_req_info->neighbor_bss_list[index].auc_mac_addr[2], /* 打印数组元素2 */
235 bsst_req_info->neighbor_bss_list[index].auc_mac_addr[3]); /* 打印数组元素3 */
236
237 oam_warning_log3(0, OAM_SF_ANY, "{hmac_handle_neighbor_list::index[%u] candidate_perf[%u], dst AP's chan=%u}",
238 index, bsst_req_info->neighbor_bss_list[index].candidate_perf,
239 bsst_req_info->neighbor_bss_list[index].chl_num);
240
241 /* 检查channel num 是否有效 */
242 ret = hmac_rx_bsst_req_candidate_info_check(hmac_vap,
243 bsst_req_info->neighbor_bss_list[index].chl_num,
244 bsst_req_info->neighbor_bss_list[index].auc_mac_addr);
245 if (ret != OAL_SUCC) {
246 continue;
247 }
248
249 if (best_neighbor_bss == OAL_PTR_NULL) {
250 best_neighbor_bss = &(bsst_req_info->neighbor_bss_list[index]);
251 continue;
252 }
253
254 /* 比较ap所给的偏好值,偏好越高,信号越好 */
255 if (best_neighbor_bss->candidate_perf < bsst_req_info->neighbor_bss_list[index].candidate_perf) {
256 oam_warning_log2(0, OAM_SF_ANY, "hmac_handle_neighbor_list::old perf[%d] -> new[%d]\n",
257 best_neighbor_bss->candidate_perf, bsst_req_info->neighbor_bss_list[index].candidate_perf);
258 best_neighbor_bss = &(bsst_req_info->neighbor_bss_list[index]);
259 }
260 }
261
262 *need_roam = (best_neighbor_bss == OAL_PTR_NULL) ? OAL_FALSE : OAL_TRUE;
263 oam_warning_log1(0, OAM_SF_ANY, "hmac_handle_neighbor_list::need_roam[%d]", *need_roam);
264 return best_neighbor_bss;
265 }
266
hmac_11v_free_url_and_bsslist(hmac_bsst_req_info_stru * bsst_req_info)267 OAL_STATIC osal_void hmac_11v_free_url_and_bsslist(hmac_bsst_req_info_stru *bsst_req_info)
268 {
269 if (bsst_req_info->session_url != OAL_PTR_NULL) {
270 oal_mem_free(bsst_req_info->session_url, OAL_TRUE);
271 bsst_req_info->session_url = OAL_PTR_NULL;
272 }
273 if (bsst_req_info->neighbor_bss_list != OAL_PTR_NULL) {
274 oal_mem_free(bsst_req_info->neighbor_bss_list, OAL_TRUE);
275 bsst_req_info->neighbor_bss_list = OAL_PTR_NULL;
276 }
277 frw_util_notifier_notify(WLAN_UTIL_NOTIFIER_EVENT_11V_FREE_BSS_LIST, OSAL_NULL);
278 }
279
280 /*****************************************************************************
281 函 数 名 : hmac_rx_bsst_req_action
282 功能描述 : STA接收AP发送的bss transition request帧
283 输出参数 : osal_u32
284 返 回 值 : 0:成功,其他:失败
285 调用函数 : 无
286 被调函数 : 无
287 *****************************************************************************/
hmac_rx_bsst_req_action(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,oal_netbuf_stru * pst_netbuf)288 OAL_STATIC osal_u32 hmac_rx_bsst_req_action(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
289 oal_netbuf_stru *pst_netbuf)
290 {
291 dmac_rx_ctl_stru *pst_rx_ctrl = OAL_PTR_NULL;
292 mac_rx_ctl_stru *rx_info = OAL_PTR_NULL;
293 osal_u16 frame_len;
294 osal_u8 *data = OAL_PTR_NULL;
295 hmac_bsst_req_info_stru bsst_req_info;
296 hmac_user_11v_ctrl_stru *pst_11v_ctrl_info = OAL_PTR_NULL;
297 hmac_user_stru *hmac_other_user = OAL_PTR_NULL;
298 osal_u32 ret;
299
300 if ((hmac_vap == OAL_PTR_NULL) || (hmac_user == OAL_PTR_NULL) || (pst_netbuf == OAL_PTR_NULL)) {
301 oam_error_log0(0, OAM_SF_ANY, "{hmac_rx_bsst_req_action::null param.}");
302 return OAL_ERR_CODE_PTR_NULL;
303 }
304
305 /* 开关未打开不处理 */
306 if (mac_mib_get_mgmt_option_bss_transition_activated(hmac_vap) == OAL_FALSE) {
307 oam_warning_log0(0, OAM_SF_ANY, "{hmac_rx_bsst_req_action:: BSSTransitionActivated is disabled}");
308 return OAL_SUCC;
309 }
310
311 hmac_other_user = mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
312 if (hmac_other_user == OAL_PTR_NULL) {
313 oam_error_log0(0, OAM_SF_ANY, "{hmac_rx_bsst_req_action::hmac_user is NULL}");
314 return OAL_ERR_CODE_ROAM_INVALID_USER;
315 }
316
317 pst_11v_ctrl_info = hmac_11v_get_user_info((osal_u8)hmac_user->assoc_id);
318 if (pst_11v_ctrl_info == OSAL_NULL) {
319 return OAL_ERR_CODE_PTR_NULL;
320 }
321 memset_s(pst_11v_ctrl_info, OAL_SIZEOF(hmac_user_11v_ctrl_stru), 0, OAL_SIZEOF(hmac_user_11v_ctrl_stru));
322
323 pst_rx_ctrl = (dmac_rx_ctl_stru *)oal_netbuf_cb(pst_netbuf);
324 rx_info = (mac_rx_ctl_stru *)(&(pst_rx_ctrl->rx_info));
325 /* 获取帧体指针 */
326 data = mac_get_rx_payload_addr(rx_info, pst_netbuf);
327 frame_len = mac_get_rx_cb_payload_len(rx_info); /* 帧体长度 */
328 /* 帧体的最小长度为7 小于7则格式异常 */
329 if (frame_len < HMAC_11V_REQUEST_FRAME_BODY_FIX) {
330 oam_error_log1(0, OAM_SF_ANY, "{hmac_rx_bsst_req_action:: frame length error %d.}", frame_len);
331 return OAL_FAIL;
332 }
333
334 /* 将帧的各种参数解析出来 供上层调用 */
335 /* 解析Token 如果与当前用户下不一致 刷新Token */
336 if (data[2] != pst_11v_ctrl_info->user_bsst_token) { /* 2 索引 */
337 pst_11v_ctrl_info->user_bsst_token = data[2]; /* 2 索引 */
338 }
339 /* 解析request mode */
340 memset_s(&bsst_req_info, sizeof(bsst_req_info), 0, sizeof(bsst_req_info));
341 ret = hmac_rx_bsst_req_action_parses(&bsst_req_info, data, frame_len, hmac_other_user);
342 if (ret != OAL_CONTINUE) {
343 return ret;
344 }
345
346 /* 获取合适的最佳bssid,rsp返回 */
347 hmac_rx_bsst_req_action_handle(hmac_vap, &bsst_req_info, pst_11v_ctrl_info, hmac_other_user);
348
349 /* 释放指针 */
350 hmac_11v_free_url_and_bsslist(&bsst_req_info);
351
352 return OAL_SUCC;
353 }
354
hmac_rx_bsst_req_action_parses(hmac_bsst_req_info_stru * bsst_req_info,osal_u8 * data,const osal_u16 frame_len,const hmac_user_stru * hmac_user)355 OAL_STATIC osal_u32 hmac_rx_bsst_req_action_parses(hmac_bsst_req_info_stru *bsst_req_info,
356 osal_u8 *data, const osal_u16 frame_len, const hmac_user_stru *hmac_user)
357 {
358 osal_u16 handle_len;
359 osal_u16 url_count;
360
361 bsst_req_info->request_mode.candidate_list_include = data[3] & BIT0; /* 3 索引 */
362 bsst_req_info->request_mode.abridged = ((data[3] & BIT1) != 0) ? OSAL_TRUE : OSAL_FALSE; /* 3 索引 */
363 bsst_req_info->request_mode.bss_disassoc_imminent = \
364 ((data[3] & BIT2) != 0) ? OSAL_TRUE : OSAL_FALSE; /* 3 索引 */
365 bsst_req_info->request_mode.termination_include = ((data[3] & BIT3) != 0) ? \
366 OSAL_TRUE : OSAL_FALSE; /* 3 索引 */
367 bsst_req_info->request_mode.ess_disassoc_imminent = \
368 ((data[3] & BIT4) != 0) ? OSAL_TRUE : OSAL_FALSE; /* 3 索引 */
369
370 bsst_req_info->disassoc_time = ((osal_u16)(data[5]) << 8) | data[4]; /* 4,5 索引, 左移8位 */
371 bsst_req_info->validity_interval = data[6]; /* 6 索引 */
372 handle_len = 7; /* 前面7个字节已被处理完 */
373 /* 12字节的termination duration 如果有的话 */
374 if (bsst_req_info->request_mode.termination_include != 0 &&
375 frame_len >= handle_len + HMAC_11V_TERMINATION_TSF_LENGTH + 2) { /* 2 长度 */
376 handle_len += MAC_IE_HDR_LEN; /* 去掉元素头 */
377 (osal_void)memcpy_s(bsst_req_info->term_duration.termination_tsf, HMAC_11V_TERMINATION_TSF_LENGTH,
378 data + handle_len, HMAC_11V_TERMINATION_TSF_LENGTH);
379 handle_len += HMAC_11V_TERMINATION_TSF_LENGTH;
380 /* 左移8位 */
381 bsst_req_info->term_duration.duration_min = (((osal_u16)data[handle_len + 1]) << 8) | (data[handle_len]);
382 handle_len += 2; /* 2 长度 */
383 }
384 /* 解析URL */
385 /* URL字段 如果有的话 URL第一个字节为URL长度 申请动态内存保存 */
386 bsst_req_info->session_url = OAL_PTR_NULL;
387 if (bsst_req_info->request_mode.ess_disassoc_imminent != 0 && frame_len >= handle_len + 1 + data[handle_len]) {
388 if (data[handle_len] != 0) {
389 /* 申请内存数量加1 用于存放字符串结束符 */
390 url_count = data[handle_len] * OAL_SIZEOF(osal_u8) + 1;
391 bsst_req_info->session_url = (osal_u8 *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, url_count,
392 OAL_TRUE);
393 if (bsst_req_info->session_url == OAL_PTR_NULL) {
394 oam_error_log0(0, OAM_SF_ANY, "{hmac_rx_bsst_req_action_parses:: session_url alloc fail.}");
395 return OAL_FAIL;
396 }
397 (void)memcpy_s(bsst_req_info->session_url, data[handle_len], data + (handle_len + 1), data[handle_len]);
398 /* 转化成字符串 */
399 bsst_req_info->session_url[data[handle_len]] = '\0';
400 }
401 handle_len += (data[handle_len] + 1);
402 }
403 /* Candidate bss list由于STA的Response frame为可选 需要解析出来放在此结构体中 供上层处理 */
404 bsst_req_info->neighbor_bss_list = OAL_PTR_NULL;
405 if ((bsst_req_info->request_mode.candidate_list_include != 0) && (frame_len >= handle_len)) {
406 data += handle_len;
407 bsst_req_info->neighbor_bss_list = hmac_get_neighbor_ie(data, frame_len - handle_len,
408 &(bsst_req_info->bss_list_num));
409 }
410
411 oam_warning_log4(0, OAM_SF_ANY, "{hmac_rx_bsst_req_action_parses:: associated address=%02x:%02x:%02x:%02x:xx:xx}",
412 hmac_user->user_mac_addr[0], hmac_user->user_mac_addr[1], hmac_user->user_mac_addr[2], /* 1,2 MAC地址 */
413 hmac_user->user_mac_addr[3]); /* 3 MAC地址 */
414 oam_warning_log1(0, OAM_SF_ANY, "{hmac_rx_bsst_req_action_parses: bss_list_num=%d}", bsst_req_info->bss_list_num);
415 return OAL_CONTINUE;
416 }
417
hmac_rx_bsst_req_action_handle(hmac_vap_stru * hmac_vap,const hmac_bsst_req_info_stru * bsst_req_info,hmac_user_11v_ctrl_stru * pst_11v_ctrl_info,const hmac_user_stru * hmac_user)418 OAL_STATIC osal_void hmac_rx_bsst_req_action_handle(hmac_vap_stru *hmac_vap,
419 const hmac_bsst_req_info_stru *bsst_req_info, hmac_user_11v_ctrl_stru *pst_11v_ctrl_info,
420 const hmac_user_stru *hmac_user)
421 {
422 hmac_bsst_rsp_info_stru bsst_rsp_info;
423 oal_bool_enum_uint8 need_roam = OAL_TRUE;
424 hmac_neighbor_bss_info_stru *best_neighbor_bss = OAL_PTR_NULL;
425 hmac_11v_vap_roam_info_stru *roam_info_11v = hmac_11v_get_roam_info(hmac_vap->vap_id);
426 osal_void *fhook = OSAL_NULL;
427
428 if (roam_info_11v == OSAL_NULL) {
429 return;
430 }
431
432 best_neighbor_bss = hmac_handle_neighbor_list(bsst_req_info, hmac_vap, hmac_user, &need_roam);
433 if (best_neighbor_bss != OAL_PTR_NULL) {
434 memset_s(&bsst_rsp_info, sizeof(bsst_rsp_info), 0, sizeof(bsst_rsp_info));
435 bsst_rsp_info.status_code = 0; /* 默认设置为同意切换 */
436 bsst_rsp_info.termination_delay = 0; /* 仅当状态码为5时有效,此次无意义设为0 */
437 bsst_rsp_info.chl_num = best_neighbor_bss->chl_num;
438 (osal_void)memcpy_s(bsst_rsp_info.target_bss_addr, WLAN_MAC_ADDR_LEN,
439 best_neighbor_bss->auc_mac_addr, WLAN_MAC_ADDR_LEN);
440
441 /* register BSS Transition Response callback function:
442 * so that check roaming scan results firstly, and then send bsst rsp frame with right status code */
443 pst_11v_ctrl_info->mac_11v_callback_fn = hmac_tx_bsst_rsp_action;
444
445 fhook = hmac_get_feature_fhook(HMAC_FHOOK_MBO_STA_SET_DELAY_PARAM);
446 if (fhook != OSAL_NULL) {
447 ((hmac_set_bss_re_assoc_delay_params_cb)fhook)(bsst_req_info, hmac_user, hmac_vap, need_roam);
448 }
449
450 memcpy_s(&(roam_info_11v->bsst_rsp_info), sizeof(bsst_rsp_info), &bsst_rsp_info, sizeof(bsst_rsp_info));
451 oam_warning_log2(0, OAM_SF_ANY, "{hmac_rx_bsst_req_action:: triger roam, need_roam[%d], bss_list_num[%d]}",
452 need_roam, bsst_req_info->bss_list_num);
453 if ((need_roam == OAL_TRUE) && (bsst_req_info->bss_list_num == 1)) {
454 pst_11v_ctrl_info->uc_11v_roam_scan_times = 1;
455 hmac_roam_start_etc(hmac_vap, ROAM_SCAN_CHANNEL_ORG_1, OAL_FALSE, ROAM_TRIGGER_11V);
456 } else if (need_roam == OAL_TRUE) {
457 hmac_roam_start_etc(hmac_vap, ROAM_SCAN_CHANNEL_ORG_BUTT, OAL_FALSE, ROAM_TRIGGER_11V);
458 }
459 } else {
460 oam_warning_log0(0, OAM_SF_ANY, "{hmac_rx_bsst_req_action:: not find best bss sending BTM rsp}");
461 }
462
463 return;
464 }
465
hmac_tx_bsst_add_user_token(hmac_user_stru * hmac_user)466 OSAL_STATIC osal_void hmac_tx_bsst_add_user_token(hmac_user_stru *hmac_user)
467 {
468 hmac_user_11v_ctrl_stru *ctrl_info_11v = hmac_11v_get_user_info((osal_u8)hmac_user->assoc_id);
469
470 if (ctrl_info_11v == OSAL_NULL) {
471 return;
472 }
473
474 if (ctrl_info_11v->user_bsst_token == HMAC_11V_TOKEN_MAX_VALUE) {
475 ctrl_info_11v->user_bsst_token = 1;
476 } else {
477 ctrl_info_11v->user_bsst_token++;
478 }
479 }
480
481 /*****************************************************************************
482 函 数 名 : hmac_encap_bsst_rsp_action
483 功能描述 : 组装BSS TRANSITION RESPONSE帧
484 输入参数 : 无
485 输出参数 : 无
486 *****************************************************************************/
hmac_encap_bsst_rsp_action(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,hmac_bsst_rsp_info_stru * bsst_rsp_info,oal_netbuf_stru * buffer)487 OAL_STATIC osal_u16 hmac_encap_bsst_rsp_action(hmac_vap_stru *hmac_vap,
488 hmac_user_stru *hmac_user,
489 hmac_bsst_rsp_info_stru *bsst_rsp_info,
490 oal_netbuf_stru *buffer)
491 {
492 osal_u16 us_index;
493 osal_u8 *mac_header = OAL_PTR_NULL;
494 osal_u8 *payload_addr = OAL_PTR_NULL;
495 hmac_user_11v_ctrl_stru *pst_11v_ctrl_info;
496
497 if ((hmac_vap == OAL_PTR_NULL) || (hmac_user == OAL_PTR_NULL) || (bsst_rsp_info == OAL_PTR_NULL) ||
498 (buffer == OAL_PTR_NULL)) {
499 oam_error_log0(0, OAM_SF_ANY, "{hmac_encap_bsst_rsp_action::null param.}");
500 return 0;
501 }
502
503 pst_11v_ctrl_info = hmac_11v_get_user_info((osal_u8)hmac_user->assoc_id);
504 if (pst_11v_ctrl_info == OSAL_NULL) {
505 return OAL_ERR_CODE_PTR_NULL;
506 }
507
508 mac_header = oal_netbuf_header(buffer);
509 payload_addr = mac_netbuf_get_payload(buffer);
510 /*************************************************************************/
511 /* Management Frame Format */
512 /* -------------------------------------------------------------------- */
513 /* |Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS| */
514 /* -------------------------------------------------------------------- */
515 /* | 2 |2 |6 |6 |6 |2 |0 - 2312 |4 | */
516 /* -------------------------------------------------------------------- */
517 /* */
518 /*************************************************************************/
519
520 /*************************************************************************/
521 /* Set the fields in the frame header */
522 /*************************************************************************/
523
524 /* Frame Control Field 中只需要设置Type/Subtype值,其他设置为0 */
525 mac_hdr_set_frame_control(mac_header, WLAN_PROTOCOL_VERSION | WLAN_FC0_TYPE_MGT | WLAN_FC0_SUBTYPE_ACTION);
526 /* DA is address of STA addr */
527 oal_set_mac_addr(mac_header + WLAN_HDR_ADDR1_OFFSET, hmac_user->user_mac_addr);
528 /* SA的值为本身的MAC地址 */
529 oal_set_mac_addr(mac_header + WLAN_HDR_ADDR2_OFFSET, mac_mib_get_station_id(hmac_vap));
530 /* TA的值为VAP的BSSID */
531 oal_set_mac_addr(mac_header + WLAN_HDR_ADDR3_OFFSET, hmac_vap->bssid);
532 /* 设置分片序号为0 */
533 mac_hdr_set_fragment_number(mac_header, 0);
534
535 /*************************************************************************************************************/
536 /* Set the contents of the frame body */
537 /*************************************************************************************************************/
538 /*************************************************************************************************************/
539 /* BSS Transition Response Frame - Frame Body */
540 /* ----------------------------------------------------------------------------------------------------------*/
541 /* |Category |Action | Token| Status Code | Termination Delay | Target BSSID | BSS Candidate List Entry */
542 /* --------------------------------------------------------------------------------------------------------- */
543 /* |1 |1 | 1 | 1 | 1 | 0-6 | Optional */
544 /* --------------------------------------------------------------------------------------------------------- */
545 /* */
546 /*************************************************************************************************************/
547
548 /* 将索引指向frame body起始位置 */
549 us_index = 0;
550 /* 设置Category */
551 payload_addr[us_index] = MAC_ACTION_CATEGORY_WNM;
552 us_index++;
553 /* 设置Action */
554 payload_addr[us_index] = MAC_WNM_ACTION_BSS_TRANSITION_MGMT_RESPONSE;
555 us_index++;
556 /* 设置Dialog Token */
557 payload_addr[us_index] = pst_11v_ctrl_info->user_bsst_token;
558 us_index++;
559 /* 设置Status Code */
560 payload_addr[us_index] = bsst_rsp_info->status_code;
561 us_index++;
562 /* 设置Termination Delay */
563 payload_addr[us_index] = bsst_rsp_info->termination_delay;
564 us_index++;
565 /* 设置Target BSSID */
566 if (bsst_rsp_info->status_code == 0) {
567 (osal_void)memcpy_s(payload_addr + us_index, WLAN_MAC_ADDR_LEN,
568 bsst_rsp_info->target_bss_addr, WLAN_MAC_ADDR_LEN);
569 us_index += WLAN_MAC_ADDR_LEN;
570 }
571 /* 可选的候选AP列表 不添加 减少带宽占用 */
572 return (osal_u16)(us_index + MAC_80211_FRAME_LEN);
573 }
574
575 /*****************************************************************************
576 函 数 名 : hmac_tx_bsst_rsp_action
577 功能描述 : STA发送bss transition response帧
578 输入参数 : 无
579 输出参数 : 无
580 *****************************************************************************/
hmac_tx_bsst_rsp_action(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,hmac_bsst_rsp_info_stru * bsst_rsp_info)581 osal_u32 hmac_tx_bsst_rsp_action(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
582 hmac_bsst_rsp_info_stru *bsst_rsp_info)
583 {
584 oal_netbuf_stru *bsst_rsp_buf;
585 osal_u16 frame_len;
586 mac_tx_ctl_stru *tx_ctl;
587 osal_u32 ret;
588
589 if ((hmac_vap == OAL_PTR_NULL) || (hmac_user == OAL_PTR_NULL) || (bsst_rsp_info == OAL_PTR_NULL)) {
590 oam_error_log0(0, OAM_SF_ANY, "{hmac_tx_bsst_rsp_action::null param.}");
591 return OAL_ERR_CODE_PTR_NULL;
592 }
593
594 /* 申请bss transition request管理帧内存 */
595 bsst_rsp_buf = OAL_MEM_NETBUF_ALLOC(OAL_MGMT_NETBUF, WLAN_MGMT_NETBUF_SIZE, OAL_NETBUF_PRIORITY_HIGH);
596 if (bsst_rsp_buf == OAL_PTR_NULL) {
597 oam_error_log1(0, OAM_SF_ANY, "vap_id[%d] {hmac_tx_bsst_rsp_action::bsst_rsq_buf null.}", hmac_vap->vap_id);
598 return OAL_ERR_CODE_PTR_NULL;
599 }
600
601 oal_set_netbuf_prev(bsst_rsp_buf, OAL_PTR_NULL);
602 oal_set_netbuf_next(bsst_rsp_buf, OAL_PTR_NULL);
603
604 /* 调用封装管理帧接口 */
605 frame_len = hmac_encap_bsst_rsp_action(hmac_vap, hmac_user, bsst_rsp_info, bsst_rsp_buf);
606 if (frame_len == 0) {
607 hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, OAL_PTR_NULL);
608 oal_netbuf_free(bsst_rsp_buf);
609 oam_error_log1(0, OAM_SF_ANY, "vap_id[%d] {hmac_tx_bsst_rsp_action::encap frame failed.}", hmac_vap->vap_id);
610 return OAL_FAIL;
611 }
612 /* 初始化CB */
613 memset_s(oal_netbuf_cb(bsst_rsp_buf), OAL_NETBUF_CB_SIZE(), 0, OAL_NETBUF_CB_SIZE());
614 tx_ctl = (mac_tx_ctl_stru *)oal_netbuf_cb(bsst_rsp_buf);
615 mac_get_cb_tx_user_idx(tx_ctl) = (osal_u8)hmac_user->assoc_id;
616 mac_get_cb_wme_ac_type(tx_ctl) = WLAN_WME_AC_MGMT;
617 mac_get_cb_mpdu_len(tx_ctl) = frame_len;
618
619 oal_netbuf_put(bsst_rsp_buf, frame_len);
620
621 oam_warning_log3(0, OAM_SF_ANY, "vap_id[%d]{hmac_tx_bsst_rsp_action:11v bsst rsp frame,frame_len=%d frametype=%d}",
622 hmac_vap->vap_id, frame_len, mac_get_cb_frame_type(tx_ctl));
623
624 /* 抛事件让dmac将该帧发送 */
625 ret = hmac_tx_mgmt_send_event_etc(hmac_vap, bsst_rsp_buf, frame_len);
626 if (ret != OAL_SUCC) {
627 oal_netbuf_free(bsst_rsp_buf);
628 oam_error_log1(0, OAM_SF_ANY, "vap_id[%d] {hmac_tx_bsst_rsp_action::send failed.}", hmac_vap->vap_id);
629 return ret;
630 }
631
632 /* STA发送完Response后 一次交互流程就完成了 需要将user下的Token值加1 供下次发送使用 */
633 hmac_tx_bsst_add_user_token(hmac_user);
634
635 return OAL_SUCC;
636 }
637
638 /*****************************************************************************
639 函 数 名 : hmac_get_neighbor_ie
640 功能描述 : 从数据中解析出Neighbor Report IE
641 输入参数 : bss_list: Neighbor Report IE结构体地址指针
642 输出参数 : buffer : 帧体指针
643 bss_num : 帧体包含的BSS数量
644 返 回 值 : OAL_SUCC或其它错误码
645 *****************************************************************************/
hmac_get_neighbor_ie(osal_u8 * data,osal_u16 len,osal_u8 * bss_num)646 hmac_neighbor_bss_info_stru *hmac_get_neighbor_ie(osal_u8 *data, osal_u16 len, osal_u8 *bss_num)
647 {
648 osal_u8 *ie_data_find = OAL_PTR_NULL;
649 osal_u16 len_find = len;
650 osal_u8 bss_number = 0;
651 osal_u8 *ie_data = OAL_PTR_NULL;
652 hmac_neighbor_bss_info_stru *bss_list_alloc = OAL_PTR_NULL;
653
654 if ((data == OAL_PTR_NULL) || (bss_num == OAL_PTR_NULL)) {
655 oam_warning_log0(0, OAM_SF_ANY, "{hmac_get_neighbor_ie::null pointer.}");
656 if (bss_num != OAL_PTR_NULL) {
657 *bss_num = 0;
658 }
659 return OAL_PTR_NULL;
660 }
661 /* 传入的帧长度为0,则不需要进行解析了 */
662 if (len == 0) {
663 *bss_num = 0;
664 return OAL_PTR_NULL;
665 }
666 ie_data_find = data;
667
668 /* 先确认含有多少个neighbor list */
669 while (ie_data_find != OAL_PTR_NULL) {
670 ie_data = mac_find_ie_etc(MAC_EID_NEIGHBOR_REPORT, ie_data_find, len_find);
671 /* 没找到则退出循环 */
672 if (ie_data == OAL_PTR_NULL) {
673 break;
674 }
675 bss_number++; /* Neighbor Report IE 数量加1 */
676 if (len_find >= ie_data[1] + MAC_IE_HDR_LEN) {
677 ie_data_find += (ie_data[1] + MAC_IE_HDR_LEN);
678 len_find -= (ie_data[1] + MAC_IE_HDR_LEN);
679 } else {
680 oam_warning_log2(0, OAM_SF_ANY, "{hmac_get_neighbor_ie::ie len[%d] greater than remain frame len[%d]!}",
681 ie_data[1] + MAC_IE_HDR_LEN, len_find);
682 return OAL_PTR_NULL;
683 }
684 }
685
686 /* 如果neighbor ie 长度为0 直接返回 */
687 if (bss_number == 0) {
688 *bss_num = 0;
689 return OAL_PTR_NULL;
690 }
691 /* 数据还原后再次从头解析数据 */
692 bss_list_alloc = (hmac_neighbor_bss_info_stru *) oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL,
693 bss_number * OAL_SIZEOF(hmac_neighbor_bss_info_stru), OAL_TRUE);
694 if (bss_list_alloc == OAL_PTR_NULL) {
695 oam_warning_log0(0, OAM_SF_ANY, "{hmac_get_neighbor_ie::bss_list null pointer.}");
696 *bss_num = 0;
697 return OAL_PTR_NULL;
698 }
699
700 hmac_get_neighbor_parses_all(bss_list_alloc, data, len, bss_number);
701 *bss_num = bss_number;
702
703 frw_util_notifier_notify(WLAN_UTIL_NOTIFIER_EVENT_11V_NEW_BSS_LIST, &bss_number);
704
705 return bss_list_alloc;
706 }
707
708 /*****************************************************************************
709 功能描述 : Neighbor Report Element子信息元素(Subelement)解析处理
710 *****************************************************************************/
hmac_neighbor_sub_element_porc(osal_u8 ** ie_data,hmac_neighbor_bss_info_stru * bss_list_alloc,osal_u8 * sub_ie_len,osal_u8 bss_list_index)711 OAL_STATIC osal_u32 hmac_neighbor_sub_element_porc(osal_u8 **ie_data, hmac_neighbor_bss_info_stru *bss_list_alloc,
712 osal_u8 *sub_ie_len, osal_u8 bss_list_index)
713 {
714 osal_u8 type = (osal_u8)(*ie_data)[0];
715 osal_void *fhook = hmac_get_feature_fhook(HMAC_FHOOK_MBO_STA_HANDLE_MBO_IE);
716
717 if (((type == HMAC_NEIGH_SUB_ID_BSS_CANDIDATE_PERF) &&
718 (*sub_ie_len < HMAC_11V_PERFERMANCE_ELEMENT_LEN + MAC_IE_HDR_LEN)) ||
719 ((type == HMAC_NEIGH_SUB_ID_TERM_DURATION) &&
720 (*sub_ie_len < HMAC_11V_TERMINATION_ELEMENT_LEN + MAC_IE_HDR_LEN)) ||
721 ((fhook != OSAL_NULL) && (type == HMAC_NEIGH_SUB_ID_VENDOR_SPECIFIC) &&
722 (*sub_ie_len < (*ie_data)[1] + MAC_IE_HDR_LEN))) {
723 oam_warning_log1(0, OAM_SF_ANY, "{hmac_neighbor_sub_element_porc sub_ie_len invalid, type[%d]}", type);
724 return OAL_FAIL;
725 } else if (*sub_ie_len < (*ie_data)[1] + MAC_IE_HDR_LEN) {
726 oam_warning_log0(0, OAM_SF_ANY, "{hmac_neighbor_sub_element_porc sub_ie_len invalid}");
727 return OAL_FAIL;
728 }
729
730 switch (type) {
731 case HMAC_NEIGH_SUB_ID_BSS_CANDIDATE_PERF: /* 占用3个字节 */
732 bss_list_alloc[bss_list_index].candidate_perf = (*ie_data)[2]; /* 2 索引 */
733 (*sub_ie_len) -= (HMAC_11V_PERFERMANCE_ELEMENT_LEN + MAC_IE_HDR_LEN);
734 (*ie_data) += (HMAC_11V_PERFERMANCE_ELEMENT_LEN + MAC_IE_HDR_LEN);
735 break;
736
737 case HMAC_NEIGH_SUB_ID_TERM_DURATION: /* 占用12个字节 */
738 memcpy_s(bss_list_alloc[bss_list_index].term_duration.termination_tsf,
739 HMAC_11V_TERMINATION_TSF_LENGTH, (*ie_data) + 2, 8); /* 2 偏移, 8/8 长度 */
740 bss_list_alloc[bss_list_index].term_duration.duration_min =
741 (((osal_u16)(*ie_data)[11]) << 8) | ((*ie_data)[10]); /* 10,11 索引,左移8位 */
742 (*sub_ie_len) -= (HMAC_11V_TERMINATION_ELEMENT_LEN + MAC_IE_HDR_LEN);
743 (*ie_data) += (HMAC_11V_TERMINATION_ELEMENT_LEN + MAC_IE_HDR_LEN);
744 break;
745
746 case HMAC_NEIGH_SUB_ID_VENDOR_SPECIFIC:
747 if (fhook != OSAL_NULL) {
748 ((hmac_handle_ie_specific_mbo_cb)fhook)((*ie_data), bss_list_alloc, bss_list_index);
749 (*sub_ie_len) -= (osal_u8)((*ie_data)[1] + MAC_IE_HDR_LEN);
750 (*ie_data) += ((*ie_data)[1] + MAC_IE_HDR_LEN);
751 }
752 break;
753
754 /* 其他IE跳过 不处理 */
755 default:
756 (*sub_ie_len) -= ((*ie_data)[1] + MAC_IE_HDR_LEN);
757 (*ie_data) += ((*ie_data)[1] + MAC_IE_HDR_LEN);
758 break;
759 }
760 return OAL_SUCC;
761 }
762
hmac_get_neighbor_parses_all(hmac_neighbor_bss_info_stru * bss_list_alloc,osal_u8 * data,const osal_u16 len,const osal_u8 bss_number)763 OAL_STATIC osal_void hmac_get_neighbor_parses_all(hmac_neighbor_bss_info_stru *bss_list_alloc,
764 osal_u8 *data, const osal_u16 len, const osal_u8 bss_number)
765 {
766 osal_u16 len_find;
767 osal_u8 bss_list_index;
768 osal_u8 minmum_ie_len = 13;
769 osal_u8 sub_ie_len;
770 osal_u8 neighbor_ie_len;
771 osal_u8 *ie_data = OAL_PTR_NULL;
772 osal_u8 *ie_data_find = OAL_PTR_NULL;
773 osal_u32 ret;
774
775 ie_data_find = data;
776 len_find = len;
777
778 for (bss_list_index = 0; bss_list_index < bss_number; bss_list_index++) {
779 /* 前面已经查询过一次,这里不会返回空,所以不作判断 */
780 ie_data = mac_find_ie_etc(MAC_EID_NEIGHBOR_REPORT, ie_data_find, len_find);
781 neighbor_ie_len = ie_data[1]; // 元素长度
782 hmac_get_neighbor_parses_bssid(bss_list_alloc, bss_list_index, ie_data);
783
784 if (neighbor_ie_len <= minmum_ie_len) {
785 ie_data_find += (ie_data[1] + MAC_IE_HDR_LEN);
786 len_find -= (ie_data[1] + MAC_IE_HDR_LEN);
787 continue;
788 }
789
790 /* 解析Subelement 长度大于最小ie长度才存在subelement 只处理3 4 subelement */
791 sub_ie_len = neighbor_ie_len - minmum_ie_len; /* subelement长度 */
792 ie_data += (minmum_ie_len + MAC_IE_HDR_LEN); /* 帧体数据移动到subelement处 */
793 while (sub_ie_len > 0) {
794 if ((ie_data[0] == HMAC_NEIGH_SUB_ID_TERM_DURATION) &&
795 (memcpy_s(bss_list_alloc[bss_list_index].term_duration.termination_tsf,
796 HMAC_11V_TERMINATION_TSF_LENGTH, ie_data + 2, 8) != EOK)) { /* 2 偏移, 8/8 长度 */
797 oam_error_log0(0, OAM_SF_ANY, "{hmac_get_neighbor_parses_all:: memcpy_s failed}");
798 return;
799 }
800 if (ie_data[0] == HMAC_NEIGH_SUB_ID_VENDOR_SPECIFIC && sub_ie_len < 10) { // 子ie至少包含10个字节
801 oam_error_log1(0, OAM_SF_ANY, "hmac_get_neighbor_parses_all::MBO len[%d]", sub_ie_len);
802 return;
803 }
804 ret = hmac_neighbor_sub_element_porc(&ie_data, bss_list_alloc, &sub_ie_len, bss_list_index);
805 if (ret != OAL_SUCC) {
806 return;
807 }
808 }
809 ie_data_find += (ie_data[1] + MAC_IE_HDR_LEN);
810 len_find -= (ie_data[1] + MAC_IE_HDR_LEN);
811 }
812
813 return;
814 }
815
hmac_get_neighbor_parses_bssid(hmac_neighbor_bss_info_stru * bss_list_alloc,const osal_u8 bss_list_index,const osal_u8 * ie_data)816 OAL_STATIC osal_void hmac_get_neighbor_parses_bssid(hmac_neighbor_bss_info_stru *bss_list_alloc,
817 const osal_u8 bss_list_index, const osal_u8 *ie_data)
818 {
819 /* 解析Neighbor Report IE结构体 帧中只含有subelement 3 4,其他subelement已被过滤掉 */
820 (osal_void)memcpy_s(bss_list_alloc[bss_list_index].auc_mac_addr, WLAN_MAC_ADDR_LEN,
821 ie_data + 2, WLAN_MAC_ADDR_LEN); // 加2取数据部分
822 /* 解析BSSID Information */
823 bss_list_alloc[bss_list_index].bssid_info.ap_reachability =
824 (osal_u8)((osal_u32)((ie_data[8] & BIT1) != 0) | (ie_data[8] & BIT0)); /* bit0-1, 8 索引 */
825 bss_list_alloc[bss_list_index].bssid_info.security =
826 ((ie_data[8] & BIT2) != 0) ? OAL_TRUE : OAL_FALSE; /* bit2, 8 索引 */
827 bss_list_alloc[bss_list_index].bssid_info.key_scope =
828 ((ie_data[8] & BIT3) != 0) ? OAL_TRUE : OAL_FALSE; /* bit3, 8 索引 */
829 bss_list_alloc[bss_list_index].bssid_info.spectrum_mgmt =
830 ((ie_data[8] & BIT4) != 0) ? OAL_TRUE : OAL_FALSE; /* bit4, 8 索引 */
831 bss_list_alloc[bss_list_index].bssid_info.qos =
832 ((ie_data[8] & BIT5) != 0) ? OAL_TRUE : OAL_FALSE; /* bit5, 8 索引 */
833 bss_list_alloc[bss_list_index].bssid_info.apsd =
834 ((ie_data[8] & BIT6) != 0) ? OAL_TRUE : OAL_FALSE; /* bit6, 8 索引 */
835 bss_list_alloc[bss_list_index].bssid_info.radio_meas =
836 ((ie_data[8] & BIT7) != 0) ? OAL_TRUE : OAL_FALSE; /* bit7, 8 索引 */
837 bss_list_alloc[bss_list_index].bssid_info.delay_block_ack =
838 ((ie_data[9] & BIT0) != 0) ? OAL_TRUE : OAL_FALSE; /* bit0, 9 索引 */
839 bss_list_alloc[bss_list_index].bssid_info.immediate_block_ack =
840 ((ie_data[9] & BIT1) != 0) ? OAL_TRUE : OAL_FALSE; /* bit1, 9 索引 */
841 bss_list_alloc[bss_list_index].bssid_info.mobility_domain =
842 ((ie_data[9] & BIT2) != 0) ? OAL_TRUE : OAL_FALSE; /* bit2, 9 索引 */
843 bss_list_alloc[bss_list_index].bssid_info.high_throughput =
844 ((ie_data[9] & BIT3) != 0) ? OAL_TRUE : OAL_FALSE; /* bit3, 9 索引 */
845 /* 保留字段不解析 */
846 bss_list_alloc[bss_list_index].opt_class = ie_data[12]; /* 12 索引 */
847 bss_list_alloc[bss_list_index].chl_num = ie_data[13]; /* 13 索引 */
848 bss_list_alloc[bss_list_index].phy_type = ie_data[14]; /* 14 索引 */
849
850 return;
851 }
852
853 /*****************************************************************************
854 函 数 名 : hmac_set_neighbor_ie
855 功能描述 : 设置Neighbor Report IE
856 *****************************************************************************/
hmac_set_neighbor_ie(hmac_neighbor_bss_info_stru * neighbor_bss,osal_u8 bss_num,osal_u8 * buffer,osal_u16 * total_ie_len)857 OAL_STATIC osal_void hmac_set_neighbor_ie(hmac_neighbor_bss_info_stru *neighbor_bss, osal_u8 bss_num, osal_u8 *buffer,
858 osal_u16 *total_ie_len)
859 {
860 osal_u8 bss_list_num;
861 osal_u8 ie_fix_len = 13; /* 不含可选子元素 则Neighbor Report IE长度为13个字节 */
862 osal_u16 total_ie_len_temp = 0;
863 osal_u8 ie_len;
864 osal_u8 bss_list_index;
865 oal_bssid_infomation_stru *bss_info = OSAL_NULL;
866
867 if ((buffer == OSAL_NULL) || (total_ie_len == OSAL_NULL) || (neighbor_bss == OSAL_NULL)) {
868 if (total_ie_len != OSAL_NULL) {
869 *total_ie_len = 0;
870 }
871 oam_error_log0(0, OAM_SF_ANY, "{hmac_set_neighbor_ie::null param.buf ie_len bss}");
872 return;
873 }
874 /* Neighbor Report Information Element Format */
875 /* ---------------------------------------------------------------------------------------------------------- */
876 /* | Element ID | Length | BSSID | BSSID Info | Operating Class | Chnl Num | PHY TYPE | Optional Subelement | */
877 /* ---------------------------------------------------------------------------------------------------------- */
878 /* | 1 | 1 | 6 | 4 | 1 | 1 | 1 | Variable | */
879 /* ---------------------------------------------------------------------------------------------------------- */
880 /* 设置Neighbor Report Element */
881 bss_list_num = bss_num; /* 用户邻近的BSS数量 */
882
883 if (bss_list_num > HMAC_MAX_BSS_NEIGHBOR_LIST) {
884 bss_list_num = HMAC_MAX_BSS_NEIGHBOR_LIST; /* 数量限制为最大值 超过的IE将被丢弃 */
885 }
886 for (bss_list_index = 0; bss_list_index < bss_list_num; bss_list_index++) {
887 ie_len = 0;
888 buffer[0] = MAC_EID_NEIGHBOR_REPORT;
889 /* 由于只截取了IE元素的一部分,长度变量信息将失效,需要重新计算 */
890 /* Neighbor BSSID Adress */
891 /* BSSID偏移地址为2 */
892 (osal_void)memcpy_s(buffer + 2, WLAN_MAC_ADDR_LEN, neighbor_bss[bss_list_index].auc_mac_addr,
893 WLAN_MAC_ADDR_LEN);
894 /* Neighbor BSSID informatin */
895 bss_info = (oal_bssid_infomation_stru *)(buffer + 8); /* BSSID Info偏移地址为8 */
896 (osal_void)memcpy_s((osal_void *)bss_info, sizeof(oal_bssid_infomation_stru),
897 (osal_void *)&(neighbor_bss[bss_list_index].bssid_info), sizeof(oal_bssid_infomation_stru));
898
899 buffer[12] = neighbor_bss[bss_list_index].opt_class; /* 12 index */
900 buffer[13] = neighbor_bss[bss_list_index].chl_num; /* 13 index */
901 buffer[14] = neighbor_bss[bss_list_index].phy_type; /* 14 index */
902 ie_len = ie_fix_len + MAC_IE_HDR_LEN;
903 /* candidate perference子元素 添加子元素 默认必须存在该子元素 */
904 buffer[ie_len++] = HMAC_NEIGH_SUB_ID_BSS_CANDIDATE_PERF;
905 buffer[ie_len++] = 1;
906 buffer[ie_len++] = neighbor_bss[bss_list_index].candidate_perf;
907 /* 存在terminatin duration子元素 则添加子元素 */
908 if (neighbor_bss[bss_list_index].term_duration.sub_ie_id == HMAC_NEIGH_SUB_ID_TERM_DURATION) {
909 buffer[ie_len++] = HMAC_NEIGH_SUB_ID_TERM_DURATION;
910 buffer[ie_len++] = HMAC_11V_TERMINATION_ELEMENT_LEN;
911 (osal_void)memcpy_s(buffer + ie_len, HMAC_11V_TERMINATION_TSF_LENGTH,
912 neighbor_bss[bss_list_index].term_duration.termination_tsf, HMAC_11V_TERMINATION_TSF_LENGTH);
913 ie_len += HMAC_11V_TERMINATION_TSF_LENGTH;
914 buffer[ie_len++] = neighbor_bss[bss_list_index].term_duration.duration_min & 0x00FF;
915 buffer[ie_len++] = (neighbor_bss[bss_list_index].term_duration.duration_min >> 0x8) & 0x00FF;
916 }
917 /* 计算IE length值 等于总长度减去IE 头长度 */
918 buffer[1] = ie_len - MAC_IE_HDR_LEN;
919
920 /* 处理完一个IE 增减相应的指针和长度 */
921 buffer += ie_len;
922 /* 将此IE长度增加到总数据长度上 */
923 total_ie_len_temp += ie_len;
924 }
925
926 *total_ie_len = total_ie_len_temp;
927 }
928
929 /*****************************************************************************
930 函 数 名 : hmac_encap_bsst_query_action
931 功能描述 : 封装bss transition management action 管理帧
932 *****************************************************************************/
hmac_encap_bsst_query_action(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,hmac_bsst_query_info_stru * bsst_query_info,oal_netbuf_stru * buffer)933 OAL_STATIC osal_u16 hmac_encap_bsst_query_action(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
934 hmac_bsst_query_info_stru *bsst_query_info, oal_netbuf_stru *buffer)
935 {
936 osal_u16 len = 0;
937 osal_u8 *mac_header = OSAL_NULL;
938 osal_u8 *payload_addr = OSAL_NULL;
939 osal_u8 *payload_addr_origin = OSAL_NULL;
940 osal_u16 frame_length;
941 osal_u8 frame_index = 0;
942 hmac_user_11v_ctrl_stru *ctrl_info_11v = hmac_11v_get_user_info((osal_u8)hmac_user->assoc_id);
943
944 if (ctrl_info_11v == OSAL_NULL) {
945 oam_error_log0(0, OAM_SF_ANY, "{hmac_encap_bsst_query_action::null param ctrl_info_11v}");
946 return len;
947 }
948
949 mac_header = oal_netbuf_header(buffer);
950 payload_addr = mac_netbuf_get_payload(buffer);
951 if (payload_addr == OSAL_NULL) {
952 return len;
953 }
954
955 payload_addr_origin = payload_addr;
956 /*************************************************************************/
957 /* Management Frame Format */
958 /* -------------------------------------------------------------------- */
959 /* |Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS| */
960 /* -------------------------------------------------------------------- */
961 /* | 2 |2 |6 |6 |6 |2 |0 - 2312 |4 | */
962 /* -------------------------------------------------------------------- */
963 /* */
964 /*************************************************************************/
965 /*************************************************************************/
966 /* Set the fields in the frame header */
967 /*************************************************************************/
968 /* 帧控制字段全为0,除了type和subtype */
969 mac_hdr_set_frame_control(mac_header, WLAN_PROTOCOL_VERSION | WLAN_FC0_TYPE_MGT | WLAN_FC0_SUBTYPE_ACTION);
970 /* 设置地址1,与STA连接的AP MAC地址 */
971 (osal_void)memcpy_s(mac_header + WLAN_HDR_ADDR1_OFFSET, WLAN_MAC_ADDR_LEN,
972 hmac_user->user_mac_addr, WLAN_MAC_ADDR_LEN);
973 /* 设置地址2为自己的MAC地址 */
974 (osal_void)memcpy_s(mac_header + WLAN_HDR_ADDR2_OFFSET, WLAN_MAC_ADDR_LEN,
975 mac_mib_get_station_id(hmac_vap), WLAN_MAC_ADDR_LEN);
976 /* 地址3,为VAP的MAC地址 */
977 (osal_void)memcpy_s(mac_header + WLAN_HDR_ADDR3_OFFSET, WLAN_MAC_ADDR_LEN,
978 hmac_vap->bssid, WLAN_MAC_ADDR_LEN);
979 /* 设置分片序号为0 */
980 mac_hdr_set_fragment_number(mac_header, 0);
981
982 /*************************************************************************/
983 /* Set the fields in the frame body */
984 /*************************************************************************/
985 /*************************************************************************/
986 /* Channel Switch Announcement Frame - Frame Body */
987 /* --------------------------------------------------------------------- */
988 /* |Category |Action |Dialog Token| BSS Tran Reason|BSS Candidate List Entry */
989 /* --------------------------------------------------------------------- */
990 /* |1 |1 | 1 | 1 |Variable */
991 /* --------------------------------------------------------------------- */
992 /* */
993 /*************************************************************************/
994 /* 设置Action的Category */
995 /* 10: WNM */
996 payload_addr[frame_index++] = MAC_ACTION_CATEGORY_WNM;
997 /* 设置WNM Action Field */
998 /* 6: BSS Transition Query Frame */
999 payload_addr[frame_index++] = MAC_WNM_ACTION_BSS_TRANSITION_MGMT_QUERY;
1000 /* 设置Dialog Token 加1处理要放在接收发送完Response后 或者超时后 */
1001 payload_addr[frame_index++] = ctrl_info_11v->user_bsst_token;
1002 /* 设置Query Reason */
1003 payload_addr[frame_index++] = bsst_query_info->reason;
1004 payload_addr += frame_index;
1005
1006 /* 该信息应通过扫描筛选相关neighbor信息,待11V扫描接口实现后再封装,目前封装可修改BSSID信息用于触发AP回复BTM.req */
1007 /* 设置Neighbor Report IE */
1008 hmac_set_neighbor_ie(bsst_query_info->neighbor_bss_list, bsst_query_info->bss_list_num, payload_addr, &len);
1009 payload_addr += len;
1010 frame_length = (osal_u16)((payload_addr - payload_addr_origin) + MAC_80211_FRAME_LEN);
1011
1012 return frame_length;
1013 }
1014
1015 /*****************************************************************************
1016 函 数 名 : hmac_tx_bsst_query_action
1017 功能描述 : STA发送bss transition query帧到AP
1018 *****************************************************************************/
hmac_tx_bsst_query_action(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,hmac_bsst_query_info_stru * bsst_query_info)1019 OAL_STATIC osal_u32 hmac_tx_bsst_query_action(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
1020 hmac_bsst_query_info_stru *bsst_query_info)
1021 {
1022 oal_netbuf_stru *mgmt_buf = OSAL_NULL;
1023 mac_tx_ctl_stru *tx_ctl = OSAL_NULL;
1024 osal_u16 mgmt_len;
1025 osal_u32 ret;
1026
1027 /* 用户能力位也需要支持方能下发 */
1028 if (hmac_user->cap_info.bss_transition != OSAL_TRUE) {
1029 oam_warning_log0(0, OAM_SF_ANY, "{hmac_tx_bsst_query_action::user not support.}");
1030 return OAL_FAIL;
1031 }
1032
1033 /* 申请管理帧内存 */
1034 mgmt_buf = OAL_MEM_NETBUF_ALLOC(OAL_MGMT_NETBUF, WLAN_MGMT_NETBUF_SIZE, OAL_NETBUF_PRIORITY_HIGH);
1035 if (mgmt_buf == OSAL_NULL) {
1036 oam_error_log0(0, OAM_SF_ANY, "{hmac_tx_bsst_query_action::mgmt_buf null.}");
1037 return OAL_ERR_CODE_PTR_NULL;
1038 }
1039
1040 oal_set_netbuf_prev(mgmt_buf, OSAL_NULL);
1041 oal_set_netbuf_next(mgmt_buf, OSAL_NULL);
1042 /* 封装 BSS Transition Management Query 帧 */
1043 mgmt_len = hmac_encap_bsst_query_action(hmac_vap, hmac_user, bsst_query_info, mgmt_buf);
1044 if (mgmt_len == 0) {
1045 hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, OAL_PTR_NULL);
1046 oal_netbuf_free(mgmt_buf);
1047 oam_error_log1(0, OAM_SF_ANY,
1048 "vap_id[%d] {hmac_tx_bsst_query_action::encap btq action failed.}", hmac_vap->vap_id);
1049 return OAL_FAIL;
1050 }
1051
1052 (osal_void)memset_s(oal_netbuf_cb(mgmt_buf), OAL_NETBUF_CB_SIZE(), 0, OAL_NETBUF_CB_SIZE());
1053 tx_ctl = (mac_tx_ctl_stru *)oal_netbuf_cb(mgmt_buf);
1054 mac_get_cb_tx_user_idx(tx_ctl) = (osal_u8)hmac_user->assoc_id;
1055 mac_get_cb_wme_ac_type(tx_ctl) = WLAN_WME_AC_MGMT;
1056 mac_get_cb_mpdu_len(tx_ctl) = mgmt_len;
1057 oal_netbuf_put(mgmt_buf, mgmt_len);
1058
1059 /* 调用发送管理帧接口 */
1060 ret = hmac_tx_mgmt_send_event_etc(hmac_vap, mgmt_buf, mgmt_len);
1061 if (ret != OAL_SUCC) {
1062 oal_netbuf_free(mgmt_buf);
1063 oam_error_log1(0, OAM_SF_ANY,
1064 "vap_id[%d] {hmac_tx_bsst_query_action::tx btq action failed.}", hmac_vap->vap_id);
1065 return ret;
1066 }
1067 return OAL_SUCC;
1068 }
1069
hmac_tx_bsst_query_update_bss_list(const hmac_vap_stru * hmac_vap,const osal_u8 * param,hmac_neighbor_bss_info_stru * neigbor_bss_list)1070 static osal_u32 hmac_tx_bsst_query_update_bss_list(const hmac_vap_stru *hmac_vap, const osal_u8 *param,
1071 hmac_neighbor_bss_info_stru *neigbor_bss_list)
1072 {
1073 hmac_trigger_11v_msg_stru msg;
1074 const osal_u8 *target_bssid_list_0;
1075
1076 if (osal_unlikely(hmac_vap == OSAL_NULL || param == OSAL_NULL || neigbor_bss_list == OSAL_NULL)) {
1077 oam_error_log0(0, OAM_SF_ANY, "{hmac_tx_bsst_query_update_bss_list::null ptr}");
1078 return OAL_ERR_CODE_PTR_NULL;
1079 }
1080
1081 memcpy_s(&msg, sizeof(hmac_trigger_11v_msg_stru), param, sizeof(hmac_trigger_11v_msg_stru));
1082
1083 if (memcmp(hmac_vap->bssid, msg.mac_addr_list_0, WLAN_MAC_ADDR_LEN) == 0) {
1084 target_bssid_list_0 = msg.mac_addr_list_1;
1085 neigbor_bss_list[0].chl_num = msg.chl_num_list_1;
1086 } else if (memcmp(hmac_vap->bssid, msg.mac_addr_list_1, WLAN_MAC_ADDR_LEN) == 0) {
1087 target_bssid_list_0 = msg.mac_addr_list_0;
1088 neigbor_bss_list[0].chl_num = msg.chl_num_list_0;
1089 } else {
1090 oam_error_log0(0, OAM_SF_ANY, "{hmac_tx_bsst_query_update_bss_list::invalid router bssid}");
1091 return OAL_ERR_CODE_INVALID_CONFIG;
1092 }
1093 /* 预期neigbor_bss_list[0]被选中为漫游目标 */
1094 (osal_void)memcpy_s(neigbor_bss_list[0].auc_mac_addr, WLAN_MAC_ADDR_LEN, target_bssid_list_0, WLAN_MAC_ADDR_LEN);
1095 (osal_void)memcpy_s(neigbor_bss_list[1].auc_mac_addr, WLAN_MAC_ADDR_LEN, hmac_vap->bssid, WLAN_MAC_ADDR_LEN);
1096 neigbor_bss_list[1].chl_num = hmac_vap->channel.chan_number;
1097
1098 return OAL_SUCC;
1099 }
1100
1101 /*****************************************************************************
1102 函 数 名 : hmac_trigger_tx_bsst_query
1103 功能描述 : 调试接口 触发STA发送bss transition query 帧
1104 *****************************************************************************/
hmac_trigger_tx_bsst_query(hmac_vap_stru * hmac_vap,osal_u8 * param)1105 OAL_STATIC osal_u32 hmac_trigger_tx_bsst_query(hmac_vap_stru *hmac_vap, osal_u8 *param)
1106 {
1107 hmac_user_stru *hmac_user = OSAL_NULL;
1108 hmac_neighbor_bss_info_stru *neigbor_bss_list = OSAL_NULL;
1109 hmac_bsst_query_info_stru bsst_query_info;
1110 osal_u8 neighbor_index = 0;
1111 osal_u8 neighbor_num = 2;
1112 osal_u32 ret;
1113
1114 /* 获取用户 */
1115 hmac_user = mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
1116 if (hmac_user == OSAL_NULL) {
1117 oam_error_log0(0, OAM_SF_ANY, "{hmac_trigger_tx_bsst_query::hmac_user is null.}");
1118 return OAL_ERR_CODE_PTR_NULL;
1119 }
1120
1121 (osal_void)memset_s(&bsst_query_info, sizeof(bsst_query_info), 0, sizeof(bsst_query_info));
1122
1123 /* reason 参数应该由上层指定 */
1124 bsst_query_info.reason = 6; // 发送原因设置为6: Better AP found
1125
1126 /* neighbor list应该由上层指向,
1127 暂时封装假信息--否则AP不回 BSST request */
1128 neigbor_bss_list = (hmac_neighbor_bss_info_stru *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL,
1129 neighbor_num * sizeof(hmac_neighbor_bss_info_stru), OAL_TRUE);
1130 if (neigbor_bss_list == OSAL_NULL) {
1131 oam_error_log0(0, OAM_SF_ANY, "{hmac_trigger_tx_bsst_query::neigbor_bss_list NULL}");
1132 return OAL_ERR_CODE_PTR_NULL;
1133 }
1134
1135 ret = hmac_tx_bsst_query_update_bss_list(hmac_vap, param, neigbor_bss_list);
1136 if (ret != OAL_SUCC) {
1137 return ret;
1138 }
1139
1140 for (; neighbor_index < neighbor_num; neighbor_index++) {
1141 /* ap_reachablility初始化为2,表示当前AP是否可达暂不可知 */
1142 neigbor_bss_list[neighbor_index].bssid_info.ap_reachability = 0x2;
1143 neigbor_bss_list[neighbor_index].bssid_info.security = 1;
1144 neigbor_bss_list[neighbor_index].bssid_info.key_scope = 1;
1145 neigbor_bss_list[neighbor_index].bssid_info.spectrum_mgmt = 0;
1146 neigbor_bss_list[neighbor_index].bssid_info.qos = 0;
1147 neigbor_bss_list[neighbor_index].bssid_info.apsd = 0;
1148 neigbor_bss_list[neighbor_index].bssid_info.radio_meas = 1;
1149 neigbor_bss_list[neighbor_index].bssid_info.delay_block_ack = 0;
1150 neigbor_bss_list[neighbor_index].bssid_info.immediate_block_ack = 0;
1151 neigbor_bss_list[neighbor_index].bssid_info.mobility_domain = 1;
1152 neigbor_bss_list[neighbor_index].bssid_info.high_throughput = 1;
1153 neigbor_bss_list[neighbor_index].bssid_info.resv1 = 0;
1154 neigbor_bss_list[neighbor_index].opt_class = 0x12;
1155 neigbor_bss_list[neighbor_index].phy_type = 0x4;
1156 /* perference data BSSID偏好值 */
1157 neigbor_bss_list[neighbor_index].candidate_perf = neighbor_index;
1158 }
1159 bsst_query_info.neighbor_bss_list = neigbor_bss_list;
1160 bsst_query_info.bss_list_num = neighbor_num;
1161 ret = hmac_tx_bsst_query_action(hmac_vap, hmac_user, &bsst_query_info);
1162
1163 /* 使用完成后释放内存 */
1164 oal_mem_free(neigbor_bss_list, OAL_TRUE);
1165 return ret;
1166 }
1167
1168 /*****************************************************************************
1169 函 数 名 : hmac_11v_cfg_bsst_switch
1170 功能描述 : 11v配置接口 用于打开或者关闭11v特性的bss transition mgmt功能
1171 输入参数 : hmac_vap_stru *hmac_vap
1172 osal_u16 len
1173 osal_u8 *param
1174 输出参数 : 无
1175 *****************************************************************************/
hmac_11v_cfg_bsst_switch(hmac_vap_stru * hmac_vap,frw_msg * msg)1176 OAL_STATIC osal_s32 hmac_11v_cfg_bsst_switch(hmac_vap_stru *hmac_vap, frw_msg *msg)
1177 {
1178 oal_bool_enum_uint8 en_11v_cfg_switch = (oal_bool_enum_uint8)(*msg->data);
1179
1180 /* 调用接口配置11v特性开关 */
1181 mac_mib_set_mgmt_option_bss_transition_activated(hmac_vap, en_11v_cfg_switch);
1182
1183 oam_warning_log2(0, OAM_SF_CFG, "vap_id[%d] {hmac_11v_cfg_bsst_switch:: Set BSST_Actived=[%d].}",
1184 hmac_vap->vap_id,
1185 mac_mib_get_mgmt_option_bss_transition_activated(hmac_vap));
1186 return OAL_SUCC;
1187 }
1188
1189 /*****************************************************************************
1190 函 数 名 : hmac_11v_sta_tx_query
1191 功能描述 : 11V 触发接口,触发STA发送bss transition management query 帧
1192 输入参数 : hmac_vap_stru *hmac_vap
1193 osal_u16 len
1194 osal_u8 *param
1195 输出参数 : 无
1196 *****************************************************************************/
hmac_11v_sta_tx_query(hmac_vap_stru * hmac_vap,frw_msg * msg)1197 OAL_STATIC osal_s32 hmac_11v_sta_tx_query(hmac_vap_stru *hmac_vap, frw_msg *msg)
1198 {
1199 osal_u32 ul_ret;
1200 /* ~{=v~}STA~{D#J=OBV'3V4%7"7"KM~}query~{V!~} */
1201 if (hmac_vap->vap_mode != WLAN_VAP_MODE_BSS_STA) {
1202 oam_warning_log2(0, OAM_SF_CFG, "vap_id[%d] {hmac_11v_sta_tx_query::vap mode:[%d] not support this.}",
1203 hmac_vap->vap_id, hmac_vap->vap_mode);
1204 return OAL_ERR_CODE_CONFIG_UNSUPPORT;
1205 }
1206
1207 if (mac_mib_get_mgmt_option_bss_transition_activated(hmac_vap) == OAL_FALSE) {
1208 oam_warning_log1(0, OAM_SF_CFG,
1209 "vap_id[%d] {hmac_11v_sta_tx_query::dot11_mgmt_option_bss_transition_activated is FALSE.}",
1210 hmac_vap->vap_id);
1211 return OAL_ERR_CODE_CONFIG_UNSUPPORT;
1212 }
1213
1214 ul_ret = hmac_trigger_tx_bsst_query(hmac_vap, msg->data);
1215 if (osal_unlikely(ul_ret != OAL_SUCC)) {
1216 oam_warning_log2(0, OAM_SF_CFG, "vap_id[%d] {hmac_11v_sta_tx_query::hmac_config_send_event_etc failed[%d].}",
1217 hmac_vap->vap_id, ul_ret);
1218 }
1219 return OAL_SUCC;
1220 }
1221
hmac_roam_check_11v_scan_result(const hmac_roam_info_stru * roam_info,hmac_vap_stru * hmac_vap,oal_bool_enum_uint8 find_bss)1222 OAL_STATIC osal_u32 hmac_roam_check_11v_scan_result(const hmac_roam_info_stru *roam_info,
1223 hmac_vap_stru *hmac_vap, oal_bool_enum_uint8 find_bss)
1224 {
1225 hmac_user_stru *hmac_user = OAL_PTR_NULL;
1226 hmac_user_11v_ctrl_stru *pst_11v_ctrl_info = OAL_PTR_NULL;
1227 hmac_device_stru *hmac_device = OAL_PTR_NULL;
1228 hmac_11v_vap_roam_info_stru *roam_info_11v = hmac_11v_get_roam_info(hmac_vap->vap_id);
1229
1230 /* 获取发送端的用户指针 */
1231 hmac_user = mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
1232 if (hmac_user == OAL_PTR_NULL) {
1233 oam_warning_log1(0, OAM_SF_RX,
1234 "vap_id[%d] {hmac_roam_check_11v_scan_result::mac_res_get_hmac_user_etc failed.}", hmac_vap->vap_id);
1235 return OAL_ERR_CODE_ROAM_INVALID_USER;
1236 }
1237
1238 hmac_device = hmac_res_get_mac_dev_etc(hmac_vap->device_id);
1239 if (hmac_device == OAL_PTR_NULL) {
1240 return OAL_ERR_CODE_ROAM_INVALID_USER;
1241 }
1242
1243 pst_11v_ctrl_info = hmac_11v_get_user_info((osal_u8)hmac_user->assoc_id);
1244 if (pst_11v_ctrl_info == OSAL_NULL || roam_info_11v == OSAL_NULL) {
1245 return OAL_ERR_CODE_PTR_NULL;
1246 }
1247
1248 oam_warning_log3(0, OAM_SF_RX,
1249 "vap_id[%d] {hmac_roam_check_11v_scan_result::find_bss=[%d],uc_11v_roam_scan_times=[%d].}",
1250 hmac_vap->vap_id, find_bss, pst_11v_ctrl_info->uc_11v_roam_scan_times);
1251
1252 if (find_bss == OAL_TRUE) {
1253 roam_info_11v->bsst_rsp_info.status_code = WNM_BSS_TM_ACCEPT;
1254 if (roam_info->config.scan_orthogonal == ROAM_SCAN_CHANNEL_ORG_1) {
1255 /* 找到指定bss,本次11v漫游结束 */
1256 pst_11v_ctrl_info->uc_11v_roam_scan_times = MAC_11V_ROAM_SCAN_FULL_CHANNEL_LIMIT;
1257 }
1258 } else {
1259 hmac_vap->roam_scan_valid_rslt = OAL_FALSE;
1260 if (roam_info->config.scan_orthogonal == ROAM_SCAN_CHANNEL_ORG_1) {
1261 if (pst_11v_ctrl_info->uc_11v_roam_scan_times <= MAC_11V_ROAM_SCAN_ONE_CHANNEL_LIMIT) {
1262 /* 还需要再次触发漫游扫描 */
1263 hmac_device->scan_mgmt.is_scanning = OAL_FALSE;
1264 return OAL_ERR_CODE_ROAM_NO_VALID_BSS;
1265 }
1266 }
1267 /* When candidate BSSID is not in scan results, bss transition rsp with status code = 7 */
1268 roam_info_11v->bsst_rsp_info.status_code = WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES;
1269 }
1270
1271 if (pst_11v_ctrl_info->mac_11v_callback_fn) {
1272 oam_warning_log1(0, OAM_SF_RX, "vap_id[%d] {hmac_roam_check_11v_scan_result send bsst rsp.}", hmac_vap->vap_id);
1273 pst_11v_ctrl_info->mac_11v_callback_fn(hmac_vap, hmac_user, &(roam_info_11v->bsst_rsp_info));
1274 pst_11v_ctrl_info->mac_11v_callback_fn = OAL_PTR_NULL;
1275 }
1276
1277 if (find_bss == OAL_FALSE) {
1278 roam_info_11v->roam_11v_scan_fail++;
1279 oam_warning_log1(0, OAM_SF_ROAM, "hmac_roam_check_11v_scan_result::candidate list no bss valid, scan fail=%d",
1280 roam_info_11v->roam_11v_scan_fail);
1281
1282 return OAL_ERR_CODE_ROAM_NO_VALID_BSS;
1283 }
1284
1285 return OAL_SUCC;
1286 }
1287
hmac_11v_set_bss_transition(mac_user_cap_info_stru * cap_info,const osal_u8 * cap)1288 OAL_STATIC osal_void hmac_11v_set_bss_transition(mac_user_cap_info_stru *cap_info, const osal_u8 *cap)
1289 {
1290 if (cap_info == OSAL_NULL || cap == OSAL_NULL) {
1291 return;
1292 }
1293
1294 /* 提取 BIT19: 支持bss transition */
1295 cap_info->bss_transition = ((cap[2] & BIT3) == 0) ? OAL_FALSE : OAL_TRUE; /* ext cap IE的第2字节 */
1296 }
1297
hmac_11v_set_ext_cap_bss_transition(hmac_vap_stru * hmac_vap,mac_ext_cap_ie_stru * ext_cap)1298 OAL_STATIC osal_void hmac_11v_set_ext_cap_bss_transition(hmac_vap_stru *hmac_vap, mac_ext_cap_ie_stru *ext_cap)
1299 {
1300 if (hmac_vap == OSAL_NULL || ext_cap == OSAL_NULL) {
1301 return;
1302 }
1303
1304 /* 目前只有sta,非p2p的端口,才支持11v,需要填充11v能力 */
1305 if (is_legacy_sta(hmac_vap)) {
1306 /* 首先需先使能wirelessmanagerment标志 */
1307 /* 然后如果是站点本地能力位和扩展控制变量均支持BSS TRANSITION 设置扩展能力bit位 */
1308 if ((mac_mib_get_wireless_management_implemented(hmac_vap) == OSAL_TRUE) &&
1309 (mac_mib_get_mgmt_option_bss_transition_implemented(hmac_vap) == OSAL_TRUE) &&
1310 (mac_mib_get_mgmt_option_bss_transition_activated(hmac_vap) == OSAL_TRUE)) {
1311 ext_cap->bss_transition = 1;
1312 }
1313 }
1314 }
1315
hmac_11v_set_scan_params(mac_scan_req_stru * scan_params,hmac_roam_info_stru * roam_info)1316 OAL_STATIC osal_void hmac_11v_set_scan_params(mac_scan_req_stru *scan_params, hmac_roam_info_stru *roam_info)
1317 {
1318 osal_u32 ul_ret;
1319 hmac_11v_vap_roam_info_stru *roam_info_11v = OSAL_NULL;
1320
1321 if (scan_params == OSAL_NULL || roam_info == OSAL_NULL) {
1322 return;
1323 }
1324
1325 roam_info_11v = hmac_11v_get_roam_info(roam_info->hmac_vap->vap_id);
1326 if (roam_info_11v == OSAL_NULL) {
1327 return;
1328 }
1329
1330 scan_params->channel_list[0].chan_number = roam_info_11v->bsst_rsp_info.chl_num;
1331 scan_params->channel_list[0].band = mac_get_band_by_channel_num(roam_info_11v->bsst_rsp_info.chl_num);
1332 ul_ret = hmac_get_channel_idx_from_num_etc(scan_params->channel_list[0].band,
1333 scan_params->channel_list[0].chan_number, &(scan_params->channel_list[0].chan_idx));
1334 if (ul_ret != OAL_SUCC) {
1335 oam_warning_log1(0, OAM_SF_SCAN, "hmac_11v_set_scan_params:: get_channel_idx fail=%d", ul_ret);
1336 }
1337 scan_params->channel_nums = 1;
1338 }
1339
hmac_11v_check_bss_dscr(hmac_roam_info_stru * roam_info,mac_bss_dscr_stru * bss_dscr)1340 OAL_STATIC osal_bool hmac_11v_check_bss_dscr(hmac_roam_info_stru *roam_info, mac_bss_dscr_stru *bss_dscr)
1341 {
1342 hmac_11v_vap_roam_info_stru *roam_info_11v = OSAL_NULL;
1343
1344 if (roam_info == OSAL_NULL || bss_dscr == OSAL_NULL) {
1345 return OSAL_FALSE;
1346 }
1347
1348 roam_info_11v = hmac_11v_get_roam_info(roam_info->hmac_vap->vap_id);
1349 if (roam_info_11v == OSAL_NULL) {
1350 return OSAL_FALSE;
1351 }
1352
1353 if (roam_info->roam_trigger == ROAM_TRIGGER_11V) {
1354 if (osal_memcmp(roam_info_11v->bsst_rsp_info.target_bss_addr, bss_dscr->bssid, WLAN_MAC_ADDR_LEN) == 0) {
1355 return OSAL_TRUE;
1356 }
1357 }
1358 return OSAL_FALSE;
1359 }
1360
hmac_11v_check_scan_result(hmac_roam_info_stru * roam_info,oal_bool_enum_uint8 flag_in_scan_rslts)1361 OAL_STATIC osal_bool hmac_11v_check_scan_result(hmac_roam_info_stru *roam_info, oal_bool_enum_uint8 flag_in_scan_rslts)
1362 {
1363 osal_u32 ret;
1364
1365 if (roam_info == OSAL_NULL) {
1366 return OSAL_FALSE;
1367 }
1368
1369 if (roam_info->roam_trigger == ROAM_TRIGGER_11V) {
1370 ret = hmac_roam_check_11v_scan_result(roam_info, roam_info->hmac_vap, flag_in_scan_rslts);
1371 if (ret != OAL_SUCC) {
1372 return OSAL_FALSE;
1373 }
1374 }
1375
1376 return OSAL_TRUE;
1377 }
1378
hmac_11v_trigger_roam_check(const hmac_roam_info_stru * roam_info,hmac_vap_stru * hmac_vap)1379 OAL_STATIC osal_void hmac_11v_trigger_roam_check(const hmac_roam_info_stru *roam_info, hmac_vap_stru *hmac_vap)
1380 {
1381 if (roam_info == OSAL_NULL || hmac_vap == OSAL_NULL) {
1382 return;
1383 }
1384
1385 /* 重新触发漫游检查 */
1386 if (roam_info->roam_trigger == ROAM_TRIGGER_11V) {
1387 hmac_11v_roam_scan_check(hmac_vap);
1388 }
1389 }
1390
hmac_sta_up_rx_action_bsst_req_action(oal_netbuf_stru ** netbuf,hmac_vap_stru * hmac_vap)1391 OAL_STATIC osal_u32 hmac_sta_up_rx_action_bsst_req_action(oal_netbuf_stru **netbuf, hmac_vap_stru *hmac_vap)
1392 {
1393 dmac_rx_ctl_stru *rx_ctl = OSAL_NULL;
1394 mac_ieee80211_frame_stru *frame_hdr = OSAL_NULL;
1395 osal_u8 *data = OSAL_NULL;
1396 hmac_user_stru *hmac_user = OSAL_NULL;
1397
1398 if (netbuf == OSAL_NULL || hmac_vap == OSAL_NULL) {
1399 return OAL_CONTINUE;
1400 }
1401
1402 rx_ctl = (dmac_rx_ctl_stru *)oal_netbuf_cb(*netbuf); /* 获取帧头信息 */
1403 frame_hdr = (mac_ieee80211_frame_stru *)mac_get_rx_cb_mac_hdr(&(rx_ctl->rx_info));
1404 data = oal_netbuf_rx_data(*netbuf);
1405
1406 if (!is_legacy_sta(hmac_vap)) {
1407 return OAL_CONTINUE;
1408 }
1409
1410 if (frame_hdr->frame_control.type != WLAN_MANAGEMENT || frame_hdr->frame_control.sub_type != WLAN_ACTION) {
1411 return OAL_CONTINUE;
1412 }
1413
1414 if ((data[MAC_ACTION_OFFSET_CATEGORY]) != MAC_ACTION_CATEGORY_WNM ||
1415 data[MAC_ACTION_OFFSET_ACTION] != MAC_WNM_ACTION_BSS_TRANSITION_MGMT_REQUEST) {
1416 return OAL_CONTINUE;
1417 }
1418
1419 hmac_user = mac_vap_get_hmac_user_by_addr_etc(hmac_vap, frame_hdr->address2);
1420 if (hmac_user == OAL_PTR_NULL) {
1421 return OAL_CONTINUE;
1422 }
1423
1424 oam_warning_log0(0, OAM_SF_ANY, "hmac_sta_up_rx_action_bsst_req_action::recv btm request");
1425 hmac_rx_bsst_req_action(hmac_vap, hmac_user, *netbuf);
1426
1427 return OAL_CONTINUE;
1428 }
1429
hmac_get_11v_cap(hmac_vap_stru * hmac_vap,osal_s32 * val)1430 OAL_STATIC osal_void hmac_get_11v_cap(hmac_vap_stru *hmac_vap, osal_s32 *val)
1431 {
1432 osal_u8 vap_id;
1433 osal_u32 value = 0;
1434
1435 if (hmac_vap == OSAL_NULL || val == OSAL_NULL) {
1436 return;
1437 }
1438 value = (osal_u32)(*val);
1439
1440 if (!is_legacy_sta(hmac_vap)) {
1441 return;
1442 }
1443
1444 vap_id = hmac_vap->vap_id;
1445 if (hmac_vap_id_param_check(vap_id) != OSAL_TRUE) {
1446 return;
1447 }
1448
1449 if (g_11v_vap_info[vap_id] != OSAL_NULL && g_11v_vap_info[vap_id]->enable_11v == OAL_TRUE) {
1450 value |= BIT(WAL_WIFI_FEATURE_SUPPORT_11V);
1451 *val = (osal_s32)value;
1452 }
1453
1454 return;
1455 }
1456
hmac_11v_vap_roam_info_init(osal_void * notify_data)1457 OAL_STATIC osal_bool hmac_11v_vap_roam_info_init(osal_void *notify_data)
1458 {
1459 hmac_vap_stru *hmac_vap = (hmac_vap_stru *)notify_data;
1460 hmac_11v_vap_info_stru *hmac_11v_vap_info = OSAL_NULL;
1461 osal_void *mem_ptr = OSAL_NULL;
1462
1463 if (hmac_vap_mode_param_check(hmac_vap) != OSAL_TRUE) {
1464 return OSAL_FALSE;
1465 }
1466
1467 if (!is_legacy_sta(hmac_vap)) {
1468 return OSAL_TRUE;
1469 }
1470
1471 hmac_11v_vap_info = hmac_11v_get_vap_info(hmac_vap->vap_id);
1472 if (hmac_11v_vap_info == OSAL_NULL) {
1473 oam_warning_log0(0, OAM_SF_ANY, "vap_id[%d] hmac_11v_vap_roam_info_init hmac_11v_vap_info null!");
1474 return OSAL_FALSE;
1475 }
1476
1477 if (hmac_11v_vap_info->roam_info_11v != OSAL_NULL) {
1478 oam_warning_log1(0, OAM_SF_ANY, "vap_id[%d] hmac_11v_vap_roam_info_init mem already malloc!", hmac_vap->vap_id);
1479 return OSAL_FALSE;
1480 }
1481
1482 mem_ptr = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(hmac_11v_vap_roam_info_stru), OAL_TRUE);
1483 if (mem_ptr == OSAL_NULL) {
1484 oam_error_log0(0, OAM_SF_ANY, "hmac_11v_vap_roam_info_init mem alloc fail");
1485 return OSAL_FALSE;
1486 }
1487
1488 (osal_void)memset_s(mem_ptr, sizeof(hmac_11v_vap_roam_info_stru), 0, sizeof(hmac_11v_vap_roam_info_stru));
1489 hmac_11v_vap_info->roam_info_11v = mem_ptr;
1490
1491 return OAL_TRUE;
1492 }
1493
hmac_11v_vap_roam_info_deinit(osal_void * notify_data)1494 OAL_STATIC osal_bool hmac_11v_vap_roam_info_deinit(osal_void *notify_data)
1495 {
1496 hmac_vap_stru *hmac_vap = (hmac_vap_stru *)notify_data;
1497 hmac_11v_vap_info_stru *hmac_11v_vap_info = OSAL_NULL;
1498
1499 if (hmac_vap_mode_param_check(hmac_vap) != OSAL_TRUE) {
1500 return OSAL_FALSE;
1501 }
1502
1503 if (!is_legacy_sta(hmac_vap)) {
1504 return OSAL_TRUE;
1505 }
1506
1507 hmac_11v_vap_info = hmac_11v_get_vap_info(hmac_vap->vap_id);
1508 if (hmac_11v_vap_info == OSAL_NULL) {
1509 return OSAL_FALSE;
1510 }
1511
1512 if (hmac_11v_vap_info->roam_info_11v != OSAL_NULL) {
1513 oal_mem_free(hmac_11v_vap_info->roam_info_11v, OAL_TRUE);
1514 hmac_11v_vap_info->roam_info_11v = OSAL_NULL;
1515 }
1516
1517 return OAL_TRUE;
1518 }
1519
hmac_11v_add_vap(osal_void * notify_data)1520 OAL_STATIC osal_bool hmac_11v_add_vap(osal_void *notify_data)
1521 {
1522 osal_u8 vap_id;
1523 osal_void *mem_ptr = OSAL_NULL;
1524 hmac_vap_stru *hmac_vap = (hmac_vap_stru *)notify_data;
1525 mac_device_voe_custom_stru *mac_voe_custom_param = mac_get_pst_mac_voe_custom_param();
1526
1527 if (hmac_vap_mode_param_check(hmac_vap) != OSAL_TRUE) {
1528 return OSAL_FALSE;
1529 }
1530
1531 if (!is_legacy_sta(hmac_vap)) {
1532 return OSAL_TRUE;
1533 }
1534
1535 vap_id = hmac_vap->vap_id;
1536 if (g_11v_vap_info[vap_id] != OSAL_NULL) {
1537 oam_warning_log1(0, OAM_SF_ANY, "vap_id[%d] hmac_11v_vap_info_init mem already malloc!", vap_id);
1538 return OSAL_TRUE;
1539 }
1540
1541 mem_ptr = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(hmac_11v_vap_info_stru), OAL_TRUE);
1542 if (mem_ptr == OSAL_NULL) {
1543 oam_error_log0(0, OAM_SF_ANY, "hmac_11v_vap_info_init mem alloc fail");
1544 return OSAL_FALSE;
1545 }
1546
1547 (osal_void)memset_s(mem_ptr, sizeof(hmac_11v_vap_info_stru), 0, sizeof(hmac_11v_vap_info_stru));
1548 g_11v_vap_info[vap_id] = (hmac_11v_vap_info_stru *)mem_ptr;
1549 g_11v_vap_info[vap_id]->enable_11v = mac_voe_custom_param->en_11v;
1550 mac_mib_set_mgmt_option_bss_transition_implemented(hmac_vap, OAL_TRUE);
1551 mac_mib_set_wireless_management_implemented(hmac_vap, OAL_TRUE);
1552 mac_mib_set_mgmt_option_bss_transition_activated(hmac_vap, mac_voe_custom_param->en_11v);
1553
1554 return OAL_TRUE;
1555 }
1556
hmac_11v_del_vap(osal_void * notify_data)1557 OAL_STATIC osal_bool hmac_11v_del_vap(osal_void *notify_data)
1558 {
1559 hmac_vap_stru *hmac_vap = (hmac_vap_stru *)notify_data;
1560 osal_u8 vap_id_11v;
1561
1562 if (hmac_vap_mode_param_check(hmac_vap) != OSAL_TRUE) {
1563 return OSAL_FALSE;
1564 }
1565
1566 if (!is_legacy_sta(hmac_vap)) {
1567 return OSAL_TRUE;
1568 }
1569
1570 vap_id_11v = hmac_vap->vap_id;
1571 if (g_11v_vap_info[vap_id_11v] != OSAL_NULL) {
1572 hmac_11v_vap_roam_info_deinit(notify_data);
1573 oal_mem_free(g_11v_vap_info[vap_id_11v], OAL_TRUE);
1574 g_11v_vap_info[vap_id_11v] = OSAL_NULL;
1575 }
1576
1577 return OAL_TRUE;
1578 }
1579
hmac_11v_add_user(osal_void * notify_data)1580 OAL_STATIC osal_bool hmac_11v_add_user(osal_void *notify_data)
1581 {
1582 hmac_user_stru *hmac_user = (hmac_user_stru *)notify_data;
1583 osal_u8 *mem_ptr = OSAL_NULL;
1584 osal_u8 user_idx;
1585
1586 if (osal_unlikely(hmac_user == OSAL_NULL || hmac_user->assoc_id >= WLAN_USER_MAX_USER_LIMIT)) {
1587 return OSAL_FALSE;
1588 }
1589
1590 user_idx = (osal_u8)hmac_user->assoc_id;
1591 if (g_11v_user_info[user_idx] != OSAL_NULL) {
1592 oam_warning_log1(0, OAM_SF_CSA, "user_idx[%d] hmac_11v_add_user mem already malloc!", user_idx);
1593 return OSAL_TRUE;
1594 }
1595
1596 mem_ptr = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(hmac_user_11v_ctrl_stru), OAL_TRUE);
1597 if (mem_ptr == OSAL_NULL) {
1598 oam_error_log1(0, OAM_SF_ANY, "user_idx[%d] hmac_11v_add_user mem alloc fail.", user_idx);
1599 return OSAL_FALSE;
1600 }
1601
1602 (osal_void)memset_s(mem_ptr, sizeof(hmac_user_11v_ctrl_stru), 0, sizeof(hmac_user_11v_ctrl_stru));
1603 /* 注册特性数据结构 */
1604 g_11v_user_info[user_idx] = (hmac_user_11v_ctrl_stru *)mem_ptr;
1605
1606 return OSAL_TRUE;
1607 }
1608
hmac_11v_del_user(osal_void * notify_data)1609 OAL_STATIC osal_bool hmac_11v_del_user(osal_void *notify_data)
1610 {
1611 hmac_user_stru *hmac_user = (hmac_user_stru *)notify_data;
1612 hmac_user_11v_ctrl_stru *hmac_11v_user_info = OSAL_NULL;
1613 osal_u8 user_idx;
1614
1615 if (osal_unlikely(hmac_user == OSAL_NULL || hmac_user->assoc_id >= WLAN_USER_MAX_USER_LIMIT)) {
1616 return OSAL_FALSE;
1617 }
1618
1619 user_idx = (osal_u8)hmac_user->assoc_id;
1620 hmac_11v_user_info = hmac_11v_get_user_info(user_idx);
1621 if (hmac_11v_user_info == OSAL_NULL) {
1622 oam_warning_log1(0, OAM_SF_ANY, "user_idx[%d] hmac_11v_del_user mem already free!", user_idx);
1623 return OSAL_TRUE;
1624 }
1625
1626 oal_mem_free(hmac_11v_user_info, OAL_TRUE);
1627 g_11v_user_info[user_idx] = OAL_PTR_NULL;
1628
1629 return OSAL_TRUE;
1630 }
1631
1632 hmac_netbuf_hook_stru g_11v_netbuf_hook = {
1633 .hooknum = HMAC_FRAME_MGMT_RX_EVENT_FEATURE,
1634 .priority = HMAC_HOOK_PRI_MIDDLE,
1635 .hook_func = hmac_sta_up_rx_action_bsst_req_action,
1636 };
1637
hmac_11v_init(osal_void)1638 osal_u32 hmac_11v_init(osal_void)
1639 {
1640 osal_u32 ret;
1641
1642 /* 注册监听 */
1643 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_ADD_VAP, hmac_11v_add_vap);
1644 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_DEL_VAP, hmac_11v_del_vap);
1645 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_ADD_USER, hmac_11v_add_user);
1646 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_11v_del_user);
1647 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_11V_VAP_ROAM_INFO_INIT, hmac_11v_vap_roam_info_init);
1648 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_11V_VAP_ROAM_INFO_DEINIT, hmac_11v_vap_roam_info_deinit);
1649 /* 注册消息 */
1650 frw_msg_hook_register(WLAN_MSG_W2H_CFG_11V_TX_QUERY, hmac_11v_sta_tx_query);
1651 frw_msg_hook_register(WLAN_MSG_W2H_CFG_11V_BSST_SWITCH, hmac_11v_cfg_bsst_switch);
1652 /* 注册对外接口 */
1653 hmac_feature_hook_register(HMAC_FHOOK_11V_SET_BSS_TRANSITION, hmac_11v_set_bss_transition);
1654 hmac_feature_hook_register(HMAC_FHOOK_11V_SET_EXT_CAP_BSS_TRANSITION, hmac_11v_set_ext_cap_bss_transition);
1655 hmac_feature_hook_register(HMAC_FHOOK_11V_SET_SCAN_PARAMS, hmac_11v_set_scan_params);
1656 hmac_feature_hook_register(HMAC_FHOOK_11V_CHECK_BSS_DSCR, hmac_11v_check_bss_dscr);
1657 hmac_feature_hook_register(HMAC_FHOOK_11V_CHECK_SCAN_RESULT, hmac_11v_check_scan_result);
1658 hmac_feature_hook_register(HMAC_FHOOK_11V_TRIGGER_ROAM_CHECK, hmac_11v_trigger_roam_check);
1659 hmac_feature_hook_register(HMAC_FHOOK_GET_11V_CAP, hmac_get_11v_cap);
1660 /* 注册转发Hook */
1661 ret = hmac_register_netbuf_hook(&g_11v_netbuf_hook);
1662 if (ret != OAL_SUCC) {
1663 oam_error_log0(0, OAM_SF_RX, "{hmac_11k_init:: MGMT RX IN register_netbuf_hooks error!");
1664 return ret;
1665 }
1666
1667 return OAL_SUCC;
1668 }
1669
hmac_11v_deinit(osal_void)1670 osal_void hmac_11v_deinit(osal_void)
1671 {
1672 /* 去注册监听 */
1673 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_ADD_VAP, hmac_11v_add_vap);
1674 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_DEL_VAP, hmac_11v_del_vap);
1675 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_ADD_USER, hmac_11v_add_user);
1676 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_11v_del_user);
1677 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_11V_VAP_ROAM_INFO_INIT, hmac_11v_vap_roam_info_init);
1678 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_11V_VAP_ROAM_INFO_DEINIT, hmac_11v_vap_roam_info_deinit);
1679 /* 去注册消息 */
1680 frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_11V_TX_QUERY);
1681 frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_11V_BSST_SWITCH);
1682 /* 去注册对外接口 */
1683 hmac_feature_hook_unregister(HMAC_FHOOK_11V_SET_BSS_TRANSITION);
1684 hmac_feature_hook_unregister(HMAC_FHOOK_11V_SET_EXT_CAP_BSS_TRANSITION);
1685 hmac_feature_hook_unregister(HMAC_FHOOK_11V_SET_SCAN_PARAMS);
1686 hmac_feature_hook_unregister(HMAC_FHOOK_11V_CHECK_BSS_DSCR);
1687 hmac_feature_hook_unregister(HMAC_FHOOK_11V_CHECK_SCAN_RESULT);
1688 hmac_feature_hook_unregister(HMAC_FHOOK_11V_TRIGGER_ROAM_CHECK);
1689 hmac_feature_hook_unregister(HMAC_FHOOK_GET_11V_CAP);
1690 /* 去注册转发Hook */
1691 hmac_unregister_netbuf_hook(&g_11v_netbuf_hook);
1692
1693 return;
1694 }
1695
1696 #ifdef __cplusplus
1697 #if __cplusplus
1698 }
1699 #endif
1700 #endif
1701
1702