• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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