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_11k.c
15 * 生成日期 : 2017年3月15日
16 * 功能描述 : 11K
17 */
18
19 /*****************************************************************************
20 1 头文件包含
21 *****************************************************************************/
22 #include "hmac_11k.h"
23 #include "oal_ext_if.h"
24 #include "oal_netbuf_ext.h"
25 #include "oal_netbuf_data.h"
26 #include "oal_mem_hcm.h"
27 #include "mac_frame.h"
28 #include "mac_resource_ext.h"
29 #include "hmac_resource.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 "hmac_mgmt_bss_comm.h"
36 #include "hmac_device.h"
37 #include "mac_device_ext.h"
38 #include "hmac_scan.h"
39 #include "hmac_config.h"
40 #include "hmac_feature_interface.h"
41 #include "frw_util_notifier.h"
42 #include "hmac_feature_dft.h"
43 #include "hmac_mbo.h"
44 #include "hmac_feature_interface.h"
45 #include "hmac_hook.h"
46 #include "hal_common_ops.h"
47
48 #ifdef __cplusplus
49 #if __cplusplus
50 extern "C" {
51 #endif
52 #endif
53
54 #undef THIS_FILE_ID
55 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_11K_C
56
57 #undef THIS_MOD_ID
58 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
59
60 /*****************************************************************************
61 2 全局变量定义
62 *****************************************************************************/
63 hmac_11k_vap_info_stru *g_11k_vap_info[WLAN_VAP_MAX_NUM_PER_DEVICE_LIMIT] = {
64 OSAL_NULL, OSAL_NULL, OSAL_NULL, OSAL_NULL
65 };
66
67 hmac_11k_user_info_stru *g_11k_user_info[WLAN_USER_MAX_USER_LIMIT];
68
69 osal_u8 guc_dialog_token = 0;
70 osal_u8 guc_meas_token = 0;
71
72 OAL_STATIC osal_u32 hmac_wait_meas_rsp_timeout(osal_void *p_arg);
73 OAL_STATIC osal_u32 hmac_rrm_bcn_scan_do(hmac_vap_stru *hmac_vap, mac_bcn_req_stru *bcn_req,
74 mac_scan_req_stru *scan_req);
75 OAL_STATIC osal_u32 hmac_rrm_fill_basic_rm_rpt_action(hmac_vap_stru *hmac_vap);
76 OAL_STATIC osal_u32 hmac_rrm_send_rm_rpt_action(hmac_vap_stru *hmac_vap);
77 OAL_STATIC osal_void hmac_rrm_parse_beacon_req(hmac_vap_stru *hmac_vap, mac_meas_req_ie_stru *meas_req_ie);
78 OAL_STATIC osal_void hmac_rrm_encap_meas_rpt_reject(hmac_vap_stru *hmac_vap, mac_meas_rpt_mode_stru *rptmode);
79 OAL_STATIC osal_u32 hmac_rrm_bcn_rpt_filter(hmac_vap_stru *hmac_vap, mac_bss_dscr_stru *bss_dscr,
80 const mac_scan_req_stru *scan_params);
81 OAL_STATIC osal_u32 hmac_rrm_encap_meas_rpt_refuse_new_req(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
82 mac_action_rm_req_stru *rm_req);
83 OAL_STATIC osal_u32 hmac_rrm_check_user_cap(mac_rrm_enabled_cap_ie_stru *rrm_enabled_cap,
84 mac_rrm_req_cfg_stru *req_cfg);
85 OAL_STATIC osal_void hmac_rrm_beacon_measure_free_all_mem(mac_vap_rrm_info_stru *rrm_info);
86 OAL_STATIC osal_void hmac_rrm_free_rpt_list(hmac_user_stru *hmac_user, mac_rrm_type_enum reqtype);
87
88 /*****************************************************************************
89 3 函数实现
90 *****************************************************************************/
hmac_11k_get_vap_info(const hmac_vap_stru * hmac_vap)91 OAL_STATIC hmac_11k_vap_info_stru *hmac_11k_get_vap_info(const hmac_vap_stru *hmac_vap)
92 {
93 if (hmac_vap_id_param_check(hmac_vap->vap_id) != OSAL_TRUE) {
94 return OSAL_NULL;
95 }
96
97 return g_11k_vap_info[hmac_vap->vap_id];
98 }
99
hmac_11k_get_vap_rrm_info(const hmac_vap_stru * hmac_vap)100 OAL_STATIC mac_vap_rrm_info_stru *hmac_11k_get_vap_rrm_info(const hmac_vap_stru *hmac_vap)
101 {
102 if (hmac_11k_get_vap_info(hmac_vap) == OSAL_NULL) {
103 return OSAL_NULL;
104 }
105
106 return g_11k_vap_info[hmac_vap->vap_id]->rrm_info;
107 }
108
hmac_11k_get_user_info(osal_u8 user_idx)109 OAL_STATIC hmac_11k_user_info_stru *hmac_11k_get_user_info(osal_u8 user_idx)
110 {
111 if (osal_unlikely(user_idx >= WLAN_USER_MAX_USER_LIMIT)) {
112 return OSAL_NULL;
113 }
114
115 return g_11k_user_info[user_idx];
116 }
117
118 /*
119 * 功能描述 : 删除rrm 扫描结果链表的一个节点项
120 */
hmac_rrm_beacon_measure_free_one_rpt_bcn_item(mac_meas_rpt_bcn_stru * meas_rpt_bcn)121 OAL_STATIC osal_void hmac_rrm_beacon_measure_free_one_rpt_bcn_item(mac_meas_rpt_bcn_stru *meas_rpt_bcn)
122 {
123 if (meas_rpt_bcn == NULL) {
124 return;
125 }
126
127 /* free mac_meas_rpt_bcn_item_stru内存 */
128 if (meas_rpt_bcn->meas_rpt_bcn_item != NULL) {
129 oal_mem_free(meas_rpt_bcn->meas_rpt_bcn_item, OSAL_TRUE);
130 meas_rpt_bcn->meas_rpt_bcn_item = NULL;
131 }
132
133 /* free prt_detail_data */
134 if (meas_rpt_bcn->rpt_detail_data != NULL) {
135 oal_mem_free(meas_rpt_bcn->rpt_detail_data, OSAL_TRUE);
136 meas_rpt_bcn->rpt_detail_data = NULL;
137 meas_rpt_bcn->rpt_detail_act_len = 0;
138 }
139
140 oal_mem_free(meas_rpt_bcn, OSAL_TRUE);
141 }
142
143 /*
144 * 功能描述 : 删除rrm ssdi和reqinfo内存
145 */
hmac_rrm_free_ssid_and_reqinfo_ieid_item(mac_vap_rrm_info_stru * rrm_info)146 OAL_STATIC osal_void hmac_rrm_free_ssid_and_reqinfo_ieid_item(mac_vap_rrm_info_stru *rrm_info)
147 {
148 if (rrm_info->bcn_req_info.ssid != NULL) {
149 oal_mem_free(rrm_info->bcn_req_info.ssid, OSAL_TRUE);
150 rrm_info->bcn_req_info.ssid = NULL;
151 rrm_info->bcn_req_info.ssid_len = 0;
152 }
153
154 if (rrm_info->bcn_req_info.reqinfo_ieid != NULL) {
155 oal_mem_free(rrm_info->bcn_req_info.reqinfo_ieid, OSAL_TRUE);
156 rrm_info->bcn_req_info.reqinfo_ieid = NULL;
157 rrm_info->bcn_req_info.req_ie_num = 0;
158 }
159 }
160
161 /*
162 * 功能描述 : 一次Beacon req失败,释放之前申请内存
163 */
hmac_rrm_beacon_measure_free_all_mem(mac_vap_rrm_info_stru * rrm_info)164 OAL_STATIC osal_void hmac_rrm_beacon_measure_free_all_mem(mac_vap_rrm_info_stru *rrm_info)
165 {
166 struct osal_list_head *meas_rpt_node = OSAL_NULL;
167 mac_meas_rpt_bcn_stru *meas_rpt_bcn = OSAL_NULL;
168
169 /* 查找链表删除各个表项内容 */
170 while (osal_list_empty(&(rrm_info->meas_rpt_list)) == 0) {
171 meas_rpt_node = rrm_info->meas_rpt_list.next;
172 meas_rpt_bcn = osal_list_entry(meas_rpt_node, mac_meas_rpt_bcn_stru, dlist_head);
173
174 /* 删除链表 */
175 osal_dlist_delete_entry(meas_rpt_node);
176 hmac_rrm_beacon_measure_free_one_rpt_bcn_item(meas_rpt_bcn);
177 };
178 }
179
180 /*****************************************************************************
181 重置数据结构rrm_info
182 *****************************************************************************/
reset_rrm_info(mac_vap_rrm_info_stru * rrm_info)183 OAL_STATIC osal_void reset_rrm_info(mac_vap_rrm_info_stru *rrm_info)
184 {
185 hmac_rrm_beacon_measure_free_all_mem(rrm_info);
186 hmac_rrm_free_ssid_and_reqinfo_ieid_item(rrm_info);
187 (osal_void)memset_s(rrm_info, sizeof(mac_vap_rrm_info_stru), 0, sizeof(mac_vap_rrm_info_stru));
188 }
189
hmac_11k_vap_info_init(hmac_vap_stru * hmac_vap)190 OAL_STATIC osal_bool hmac_11k_vap_info_init(hmac_vap_stru *hmac_vap)
191 {
192 mac_device_voe_custom_stru *mac_voe_custom_param = mac_get_pst_mac_voe_custom_param();
193 hmac_11k_vap_info_stru *hmac_11k_vap_info = hmac_11k_get_vap_info(hmac_vap);
194 oal_bool_enum_uint8 en_11k = mac_voe_custom_param->en_11k;
195
196 hmac_11k_vap_info->enable_11k = en_11k;
197 hmac_11k_vap_info->bcn_table_switch = en_11k;
198 mac_mib_set_dot11_radio_measurement_activated(hmac_vap, en_11k);
199 mac_mib_set_dot11RMBeaconTableMeasurementActivated(hmac_vap, en_11k);
200
201 if (en_11k == OAL_TRUE) {
202 hmac_11k_vap_info->rrm_info = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, OAL_SIZEOF(mac_vap_rrm_info_stru), OAL_TRUE);
203 if (hmac_11k_vap_info->rrm_info == OAL_PTR_NULL) {
204 oam_error_log1(0, OAM_SF_ANY, "vap_id[%d] {hmac_11k_vap_info_init::rrm_info null.}", hmac_vap->vap_id);
205 return OAL_FALSE;
206 }
207 memset_s(hmac_11k_vap_info->rrm_info, OAL_SIZEOF(mac_vap_rrm_info_stru), 0, OAL_SIZEOF(mac_vap_rrm_info_stru));
208 OSAL_INIT_LIST_HEAD(&((hmac_11k_vap_info->rrm_info)->meas_rpt_list));
209 }
210
211 return OAL_TRUE;
212 }
213
214 /*****************************************************************************
215 函 数 名 : hmac_11k_init_vap
216 功能描述 : 创建vap时,初始化11k vap结构体;
217 输入参数 : hmac_vap
218 输出参数 : 无
219 返 回 值 : 无
220 *****************************************************************************/
hmac_11k_add_vap(osal_void * notify_data)221 OAL_STATIC osal_bool hmac_11k_add_vap(osal_void *notify_data)
222 {
223 hmac_vap_stru *hmac_vap = (hmac_vap_stru *)notify_data;
224 osal_void *mem_ptr = OSAL_NULL;
225 osal_u8 vap_id;
226 oal_bool_enum_uint8 ret;
227
228 if (hmac_vap_mode_param_check(hmac_vap) != OSAL_TRUE) {
229 return OSAL_FALSE;
230 }
231
232 if (!is_legacy_sta(hmac_vap)) {
233 return OSAL_TRUE;
234 }
235
236 vap_id = hmac_vap->vap_id;
237 if (g_11k_vap_info[vap_id] != OSAL_NULL) {
238 oam_warning_log1(0, OAM_SF_ANY, "vap_id[%d] hmac_11k_add_vap mem already malloc!", vap_id);
239 return OSAL_TRUE;
240 }
241
242 mem_ptr = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(hmac_11k_vap_info_stru), OAL_TRUE);
243 if (mem_ptr == OSAL_NULL) {
244 oam_error_log0(0, OAM_SF_ANY, "hmac_11k_add_vap mem alloc fail");
245 return OSAL_FALSE;
246 }
247
248 (osal_void)memset_s(mem_ptr, sizeof(hmac_11k_vap_info_stru), 0, sizeof(hmac_11k_vap_info_stru));
249 /* 注册特性数据结构 */
250 g_11k_vap_info[vap_id] = (hmac_11k_vap_info_stru *)mem_ptr;
251
252 ret = hmac_11k_vap_info_init(hmac_vap);
253 if (ret != OAL_TRUE) {
254 oal_mem_free(mem_ptr, OAL_TRUE);
255 g_11k_vap_info[vap_id] = OSAL_NULL;
256 return ret;
257 }
258
259 return OAL_TRUE;
260 }
261
262 /*****************************************************************************
263 函 数 名 : hmac_11k_down_vap
264 功能描述 :down vap时,释放11k vap的rrm info结构体;
265 输入参数 : notify_data
266 输出参数 : 无
267 返 回 值 : 无
268 *****************************************************************************/
hmac_11k_down_vap(osal_void * notify_data)269 OAL_STATIC osal_bool hmac_11k_down_vap(osal_void *notify_data)
270 {
271 hmac_vap_stru *hmac_vap = (hmac_vap_stru *)notify_data;
272 hmac_11k_vap_info_stru *hmac_11k_vap_info;
273
274 if (hmac_vap_mode_param_check(hmac_vap) != OSAL_TRUE) {
275 return OSAL_FALSE;
276 }
277
278 if (!is_legacy_sta(hmac_vap)) {
279 return OSAL_TRUE;
280 }
281
282 hmac_11k_vap_info = hmac_11k_get_vap_info(hmac_vap);
283 if (hmac_11k_vap_info == OSAL_NULL) {
284 return OSAL_FALSE;
285 }
286
287 if (hmac_11k_vap_info->rrm_info != OSAL_NULL) {
288 reset_rrm_info(hmac_11k_vap_info->rrm_info);
289 oal_mem_free(hmac_11k_vap_info->rrm_info, OAL_TRUE);
290 hmac_11k_vap_info->rrm_info = OSAL_NULL;
291 }
292
293 return OAL_TRUE;
294 }
295
hmac_11k_del_vap(osal_void * notify_data)296 OAL_STATIC osal_bool hmac_11k_del_vap(osal_void *notify_data)
297 {
298 hmac_vap_stru *hmac_vap = (hmac_vap_stru *)notify_data;
299 osal_u8 vap_id_11k;
300
301 if (hmac_vap_mode_param_check(hmac_vap) != OSAL_TRUE) {
302 return OSAL_FALSE;
303 }
304
305 if (!is_legacy_sta(hmac_vap)) {
306 return OSAL_TRUE;
307 }
308
309 vap_id_11k = hmac_vap->vap_id;
310 if (g_11k_vap_info[vap_id_11k] != OSAL_NULL) {
311 hmac_11k_down_vap(notify_data);
312 oal_mem_free(g_11k_vap_info[vap_id_11k], OAL_TRUE);
313 g_11k_vap_info[vap_id_11k] = OSAL_NULL;
314 }
315
316 return OAL_TRUE;
317 }
318
hmac_11k_add_user(osal_void * notify_data)319 OAL_STATIC osal_bool hmac_11k_add_user(osal_void *notify_data)
320 {
321 hmac_user_stru *hmac_user = (hmac_user_stru *)notify_data;
322 osal_u8 *mem_ptr = OSAL_NULL;
323 osal_u8 user_idx;
324
325 if (osal_unlikely(hmac_user == OSAL_NULL || hmac_user->assoc_id >= WLAN_USER_MAX_USER_LIMIT)) {
326 return OSAL_FALSE;
327 }
328
329 user_idx = (osal_u8)hmac_user->assoc_id;
330 if (g_11k_user_info[user_idx] != OSAL_NULL) {
331 oam_warning_log1(0, OAM_SF_CSA, "user_idx[%d] hmac_11k_add_user mem already malloc!", user_idx);
332 return OSAL_TRUE;
333 }
334
335 mem_ptr = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(hmac_11k_user_info_stru), OAL_TRUE);
336 if (mem_ptr == OSAL_NULL) {
337 oam_error_log1(0, OAM_SF_ANY, "user_idx[%d] hmac_11k_add_user mem alloc fail.", user_idx);
338 return OSAL_FALSE;
339 }
340
341 (osal_void)memset_s(mem_ptr, sizeof(hmac_11k_user_info_stru), 0, sizeof(hmac_11k_user_info_stru));
342 /* 注册特性数据结构 */
343 g_11k_user_info[user_idx] = (hmac_11k_user_info_stru *)mem_ptr;
344
345 return OSAL_TRUE;
346 }
347
348 /*****************************************************************************
349 函 数 名 : hmac_11k_init_user
350 功能描述 : 创建user时,初始化11k user结构体;
351 输入参数 : hmac_user
352 输出参数 : 无
353 返 回 值 : 无
354 *****************************************************************************/
hmac_11k_init_rrm_info(hmac_user_stru * hmac_user)355 OAL_STATIC osal_void hmac_11k_init_rrm_info(hmac_user_stru *hmac_user)
356 {
357 hmac_11k_user_info_stru *hmac_11k_user_info = hmac_11k_get_user_info((osal_u8)hmac_user->assoc_id);
358 mac_user_rrm_info_stru *user_rrm_info = OSAL_NULL;
359
360 if (hmac_11k_user_info == OSAL_NULL) {
361 return;
362 }
363
364 /* 关联时申请用户结构体空间 */
365 if (hmac_11k_user_info->user_rrm_info == OAL_PTR_NULL) {
366 user_rrm_info = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, OAL_SIZEOF(mac_user_rrm_info_stru), OAL_TRUE);
367 if (user_rrm_info == OAL_PTR_NULL) {
368 oam_error_log1(0, OAM_SF_ANY, "vap_id[%d] {hmac_11k_init_rrm_info::user_rrm_info null.}",
369 hmac_user->vap_id);
370 return;
371 }
372
373 memset_s(user_rrm_info, OAL_SIZEOF(mac_user_rrm_info_stru), 0, OAL_SIZEOF(mac_user_rrm_info_stru));
374 OSAL_INIT_LIST_HEAD(&(user_rrm_info->meas_rpt_list));
375 hmac_11k_user_info->user_rrm_info = user_rrm_info;
376 }
377
378 return;
379 }
380
381 /*****************************************************************************
382 函 数 名 : hmac_11k_init_user
383 功能描述 : 销毁user时,释放11k user结构体;
384 输入参数 : hmac_user
385 输出参数 : 无
386 返 回 值 : 无
387 *****************************************************************************/
hmac_11k_del_user(osal_void * notify_data)388 OAL_STATIC osal_bool hmac_11k_del_user(osal_void *notify_data)
389 {
390 hmac_user_stru *hmac_user = (hmac_user_stru *)notify_data;
391 hmac_11k_user_info_stru *hmac_11k_user_info = OSAL_NULL;
392 mac_user_rrm_info_stru *user_rrm_info = OSAL_NULL;
393 osal_u8 user_idx;
394
395 if (osal_unlikely(hmac_user == OSAL_NULL || hmac_user->assoc_id >= WLAN_USER_MAX_USER_LIMIT)) {
396 return OSAL_FALSE;
397 }
398
399 user_idx = (osal_u8)hmac_user->assoc_id;
400 hmac_11k_user_info = hmac_11k_get_user_info(user_idx);
401 if (hmac_11k_user_info == OSAL_NULL) {
402 oam_warning_log1(0, OAM_SF_ANY, "user_idx[%d] hmac_11k_del_user mem already free!", user_idx);
403 return OSAL_TRUE;
404 }
405
406 user_rrm_info = hmac_11k_user_info->user_rrm_info;
407 if (user_rrm_info != OAL_PTR_NULL) {
408 if (user_rrm_info->timer.is_registerd == OAL_TRUE) {
409 frw_destroy_timer_entry(&user_rrm_info->timer);
410 }
411
412 /* 释放链表和恢复状态 */
413 hmac_rrm_free_rpt_list(hmac_user, user_rrm_info->reqtype);
414
415 oal_mem_free(user_rrm_info, OAL_TRUE);
416 hmac_11k_user_info->user_rrm_info = OAL_PTR_NULL;
417 }
418
419 oal_mem_free(hmac_11k_user_info, OAL_TRUE);
420 g_11k_user_info[user_idx] = OAL_PTR_NULL;
421
422 return OSAL_TRUE;
423 }
424
425 /***************************************************************************
426 函 数 名 : hmac_rrm_proc_action_ie_head
427 功能描述 : 处理rrm帧的ie头部信息
428 输入参数 : hmac_vap、hmac_user、framebody_len、rm_req
429 输出参数 : rrm_info
430 ****************************************************************************/
hmac_rrm_proc_action_ie_head(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,osal_u16 framebody_len,mac_action_rm_req_stru * rm_req,mac_vap_rrm_info_stru * rrm_info)431 OAL_STATIC osal_u32 hmac_rrm_proc_action_ie_head(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
432 osal_u16 framebody_len, mac_action_rm_req_stru *rm_req, mac_vap_rrm_info_stru *rrm_info)
433 {
434 mac_meas_req_ie_stru *meas_req_ie = OSAL_NULL;
435 mac_meas_rpt_mode_stru rptmode;
436
437 memset_s(&rptmode, OAL_SIZEOF(mac_meas_rpt_mode_stru), 0, OAL_SIZEOF(mac_meas_rpt_mode_stru));
438
439 /* 判断VAP是否正在进行测量 */
440 if (rrm_info->is_measuring == OAL_TRUE) {
441 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_proc_rm_request::vap is handling one request now.}");
442 hmac_rrm_encap_meas_rpt_refuse_new_req(hmac_vap, hmac_user, rm_req);
443 return OAL_FAIL;
444 }
445
446 /* 保存req */
447 rrm_info->action_code = rm_req->action_code;
448 rrm_info->dialog_token = rm_req->dialog_token;
449 rrm_info->req_user_id = hmac_user->assoc_id;
450
451 /* 是否有Meas Req */
452 if (framebody_len <= MAC_RADIO_MEAS_ACTION_REQ_FIX_LEN) {
453 /* 如果没有MR IE,也回一个不带Meas Rpt的Radio Meas Rpt */
454 /* 申请管理帧内存并填充头部信息 */
455 if (hmac_rrm_fill_basic_rm_rpt_action(hmac_vap) != OAL_SUCC) {
456 return OAL_FAIL;
457 }
458 (osal_void)hmac_rrm_send_rm_rpt_action(hmac_vap);
459 return OAL_FAIL;
460 }
461
462 meas_req_ie = (mac_meas_req_ie_stru *)&(rm_req->req_ies[0]);
463 rrm_info->meas_req_ie = meas_req_ie;
464
465 /* 重复测试次数暂不处理,如果对端要求重复测试,则回复incapable bit */
466 oam_warning_log4(0, OAM_SF_RRM,
467 "{hmac_rrm_proc_rm_request::framebody::Category[%d],Action[%d],Dialog Token[%d],Number of Repetitions[%d].}",
468 rm_req->category, rm_req->action_code, rm_req->dialog_token, rm_req->num_rpt);
469
470 if (rm_req->num_rpt != 0) {
471 rptmode.incapable = 1;
472 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
473 oam_warning_log2(0, OAM_SF_RRM,
474 "{vap_id[%d] hmac_rrm_proc_rm_request::RepeatedMeasurements not support, num_rpt[%u].}",
475 hmac_vap->vap_id, rm_req->num_rpt);
476 return OAL_FAIL;
477 }
478
479 /**************************************************************************/
480 /* Measurement Request IE */
481 /* ---------------------------------------------------------------------- */
482 /* |Element ID |Length |Meas Token| Meas Req Mode|Meas Type | Meas Req | */
483 /* ---------------------------------------------------------------------- */
484 /* |1 |1 | 1 | 1 |1 |var | */
485 /* ---------------------------------------------------------------------- */
486 /* */
487 /**************************************************************************/
488 oam_warning_log4(0, OAM_SF_RRM,
489 "hmac_rrm_proc_rm_request::framebody::Element ID[%d],Length[%d],Meas Token[%d],Meas Req Mode[%d].",
490 meas_req_ie->eid, meas_req_ie->len, meas_req_ie->token, *((osal_u8*)(&(meas_req_ie->reqmode))));
491 oam_warning_log2(0, OAM_SF_RRM, "vap_id[%d] hmac_rrm_proc_rm_request::framebody::Meas Type[%d].",
492 hmac_vap->vap_id, meas_req_ie->reqtype);
493
494 return OAL_SUCC;
495 }
496
497 /***************************************************************************
498 函 数 名 : hmac_rrm_proc_action_ie_body
499 功能描述 : 处理rrm帧的ie帧体信息
500 输入参数 : hmac_vap、hmac_user、meas_req_ie、rm_req
501 输出参数 : rrm_info
502 ****************************************************************************/
hmac_rrm_proc_action_ie_body(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,mac_meas_req_ie_stru * meas_req_ie,mac_vap_rrm_info_stru * rrm_info,const mac_action_rm_req_stru * rm_req)503 OAL_STATIC osal_u32 hmac_rrm_proc_action_ie_body(hmac_vap_stru *hmac_vap,
504 hmac_user_stru *hmac_user, mac_meas_req_ie_stru *meas_req_ie, mac_vap_rrm_info_stru *rrm_info,
505 const mac_action_rm_req_stru *rm_req)
506 {
507 mac_meas_rpt_mode_stru rptmode;
508 hmac_11k_user_info_stru *hmac_11k_user_info = hmac_11k_get_user_info((osal_u8)hmac_user->assoc_id);
509
510 if (hmac_11k_user_info == OSAL_NULL) {
511 return OAL_ERR_CODE_PTR_NULL;
512 }
513
514 memset_s(&rptmode, OAL_SIZEOF(mac_meas_rpt_mode_stru), 0, OAL_SIZEOF(mac_meas_rpt_mode_stru));
515
516 if (meas_req_ie->eid == MAC_EID_MEASREQ) {
517 if (meas_req_ie->reqmode.enable == 1) {
518 /* Req中拒绝某种类型的测量,一旦对端拒绝,在当前关联状态无法恢复测量能力位,需要重新关联 */
519 if (meas_req_ie->reqmode.request == 0 && meas_req_ie->reqtype == RM_RADIO_MEAS_BCN) {
520 oam_warning_log1(0, OAM_SF_RRM,
521 "{hmac_rrm_proc_action_ie_body::update user rrm capability,reqtype[%d] not support!}",
522 meas_req_ie->reqtype);
523 hmac_11k_user_info->rrm_enabled_cap.bcn_active_cap = 0;
524 hmac_11k_user_info->rrm_enabled_cap.bcn_passive_cap = 0;
525 hmac_11k_user_info->rrm_enabled_cap.bcn_table_cap = 0;
526 hmac_11k_user_info->rrm_enabled_cap.bcn_meas_rpt_cond_cap = 0;
527 }
528
529 /* Req中不允许发送对应的report */
530 if (meas_req_ie->reqmode.rpt == 0) {
531 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_proc_action_ie_body::user not expect rpt!}");
532 return OAL_FAIL;
533 }
534 }
535
536 /* 并行测试暂不处理,如果对端要求则回复incapable bit */
537 if (meas_req_ie->reqmode.parallel != 0) {
538 rptmode.incapable = 1;
539 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
540 oam_warning_log0(0, OAM_SF_RRM, "hmac_rrm_proc_action_ie_body::ParallelMeasurement not support.");
541 return OAL_FAIL;
542 }
543
544 /* 处理Beacon req */
545 if (meas_req_ie->reqtype == RM_RADIO_MEAS_BCN) {
546 rrm_info->bcn_req_info.meas_token = meas_req_ie->token;
547 rrm_info->bcn_req_info.meas_type = meas_req_ie->reqtype;
548 rrm_info->bcn_req_info.repetition = OAL_NTOH_16(rm_req->num_rpt);
549 rrm_info->bcn_req_info.dialog_token = rm_req->dialog_token;
550 rrm_info->bcn_req_info.rpt_frag_type = MAC_BCN_RPT_NO_FRAG;
551 hmac_rrm_parse_beacon_req(hmac_vap, meas_req_ie);
552 } else {
553 rptmode.incapable = 1;
554 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
555 oam_warning_log1(0, OAM_SF_RRM, "{Error Request, Expect Measurement Request, but got reqtype[%d]!}",
556 meas_req_ie->reqtype);
557 return OAL_FAIL;
558 }
559 } else { /* MR IE错误,不回,报错 */
560 oam_warning_log1(0, OAM_SF_RRM, "{Error, Expect Measurement Request, but got EID[%d]!}", meas_req_ie->eid);
561 return OAL_FAIL;
562 }
563
564 return OAL_SUCC;
565 }
566
567 /*****************************************************************************
568 函 数 名 : hmac_rrm_proc_rm_request
569 功能描述 : 解析Radio Measurement Request,并处理Beacon Request
570 输入参数 : hmac_vap : dmac vap结构体指针
571 pst_netbuf : RM Request的netbuf
572 输出参数 : 无
573 *****************************************************************************/
hmac_rrm_proc_rm_request(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,oal_netbuf_stru * netbuf)574 OAL_STATIC osal_u32 hmac_rrm_proc_rm_request(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
575 oal_netbuf_stru *netbuf)
576 {
577 mac_action_rm_req_stru *rm_req = OSAL_NULL;
578 mac_meas_req_ie_stru *meas_req_ie = OSAL_NULL;
579 dmac_rx_ctl_stru *rx_ctrl = OSAL_NULL;
580 osal_u16 framebody_len;
581 mac_vap_rrm_info_stru *rrm_info = OSAL_NULL;
582 osal_u16 framebody_len_tmp;
583 osal_u16 measurement_ie_len;
584 osal_u8 *data = OSAL_NULL;
585 osal_u32 ret;
586
587 rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
588 rx_ctrl = (dmac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
589 if (rrm_info == OAL_PTR_NULL || rx_ctrl == OAL_PTR_NULL) {
590 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_proc_rm_request:: parma is NULL! rrm_info, pst_rx_ctrl}");
591 return OAL_ERR_CODE_PTR_NULL;
592 }
593
594 framebody_len = mac_get_rx_cb_payload_len(&(rx_ctrl->rx_info));
595 data = mac_netbuf_get_payload(netbuf);
596 rm_req = (mac_action_rm_req_stru *)data;
597
598 ret = hmac_rrm_proc_action_ie_head(hmac_vap, hmac_user, framebody_len, rm_req, rrm_info);
599 if (ret != OAL_SUCC) {
600 oam_warning_log1(0, OAM_SF_RRM, "{hmac_rrm_proc_rm_request::hmac_rrm_pre_proc_request fail! ret[%d]}", ret);
601 return OAL_FAIL;
602 }
603 /**************************************************************************/
604 /* Radio Measurement Request Frame - Frame Body */
605 /* ---------------------------------------------------------------------- */
606 /* |Category |Action |Dialog Token| Number of Repetitions|Meas Req Eles | */
607 /* ---------------------------------------------------------------------- */
608 /* |1 |1 | 1 | 2 |var */
609 /* ---------------------------------------------------------------------- */
610 /* */
611 /**************************************************************************/
612
613 /* 可能有多个Measurement Req IEs */
614 framebody_len_tmp = framebody_len - MAC_MEASUREMENT_REQUEST_IE_OFFSET;
615 while (framebody_len_tmp > MAC_IE_HDR_LEN) {
616 meas_req_ie = (mac_meas_req_ie_stru *)&(data[framebody_len - framebody_len_tmp]);
617 rrm_info->meas_req_ie = meas_req_ie;
618 measurement_ie_len = meas_req_ie->len;
619
620 if ((framebody_len_tmp >= measurement_ie_len + MAC_IE_HDR_LEN) &&
621 (measurement_ie_len >= OAL_OFFSET_OF(mac_meas_req_ie_stru, meas_req) - MAC_IE_HDR_LEN)) {
622 framebody_len_tmp = framebody_len_tmp - measurement_ie_len - MAC_IE_HDR_LEN;
623 } else {
624 oam_warning_log2(0, OAM_SF_RRM, "{invalid Measurement_ie_len= [%d] framebody_len_tmp=[%d]!}",
625 measurement_ie_len, framebody_len_tmp);
626 break;
627 }
628
629 ret = hmac_rrm_proc_action_ie_body(hmac_vap, hmac_user, meas_req_ie, rrm_info, rm_req);
630 if (ret != OAL_SUCC) {
631 oam_warning_log1(0, OAM_SF_RRM, "{hmac_rrm_proc_rm_request::hmac_rrm_handle_meas_req fail! ret[%d]}", ret);
632 return OAL_FAIL;
633 }
634 }
635 return OAL_SUCC;
636 }
637
hmac_config_encap_mgmt_frame(osal_u8 ** buffer,oal_netbuf_stru * mgmt_buf,hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user)638 OAL_STATIC osal_void hmac_config_encap_mgmt_frame(osal_u8** buffer, oal_netbuf_stru *mgmt_buf,
639 hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user)
640 {
641 osal_u8 *tmpbuf = OAL_PTR_NULL;
642
643 tmpbuf = (osal_u8 *)oal_netbuf_header(mgmt_buf);
644
645 /*************************************************************************/
646 /* Management Frame Format */
647 /* -------------------------------------------------------------------- */
648 /* |Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS| */
649 /* -------------------------------------------------------------------- */
650 /* | 2 |2 |6 |6 |6 |2 |0 - 2312 |4 | */
651 /* -------------------------------------------------------------------- */
652 /* */
653 /*************************************************************************/
654
655 /* All the fields of the Frame Control Field are set to zero. Only the */
656 /* Type/Subtype field is set. */
657 mac_hdr_set_frame_control(tmpbuf, WLAN_PROTOCOL_VERSION | WLAN_FC0_TYPE_MGT | WLAN_FC0_SUBTYPE_ACTION);
658
659 /* duration */
660 tmpbuf[2] = 0; /* 2 索引 */
661 tmpbuf[3] = 0; /* 3 索引 */
662
663 /* DA is address of STA requesting association */
664 oal_set_mac_addr(tmpbuf + WLAN_HDR_ADDR1_OFFSET, hmac_user->user_mac_addr);
665
666 /* SA */
667 oal_set_mac_addr(tmpbuf + WLAN_HDR_ADDR2_OFFSET, mac_mib_get_station_id(hmac_vap));
668 oal_set_mac_addr(tmpbuf + WLAN_HDR_ADDR3_OFFSET, hmac_vap->bssid);
669
670 /* seq control */
671 tmpbuf[22] = 0; /* 22 索引 */
672 tmpbuf[23] = 0; /* 23 索引 */
673
674 /**************************************************************************/
675 /* Radio Measurement Request Frame - Frame Body */
676 /* ---------------------------------------------------------------------- */
677 /* |Category |Action |Dialog Token| Number of Repetitions|Meas Req Eles | */
678 /* ---------------------------------------------------------------------- */
679 /* |1 |1 | 1 | 2 |var */
680 /* ---------------------------------------------------------------------- */
681 /* */
682 /**************************************************************************/
683 tmpbuf += MAC_80211_FRAME_LEN;
684 *buffer = tmpbuf;
685 return;
686 }
687
hmac_config_encap_radio_meas_req(mac_rrm_req_cfg_stru * req_cfg,osal_u8 * buffer,hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user)688 OAL_STATIC osal_u32 hmac_config_encap_radio_meas_req(mac_rrm_req_cfg_stru *req_cfg, osal_u8 *buffer,
689 hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user)
690 {
691 osal_u8 *req_mode = OAL_PTR_NULL;
692 mac_meas_req_ie_stru *meas_req_ie = OAL_PTR_NULL;
693 mac_action_rm_req_stru *rm_req = OAL_PTR_NULL;
694 osal_u8 *reporting_detail = OAL_PTR_NULL;
695 mac_bcn_req_stru *bcn_req = OAL_PTR_NULL;
696
697 unref_param(hmac_vap);
698 unref_param(hmac_user);
699
700 rm_req = (mac_action_rm_req_stru *)buffer;
701 rm_req->category = MAC_ACTION_CATEGORY_RADIO_MEASURMENT;
702 rm_req->action_code = MAC_RM_ACTION_RADIO_MEASUREMENT_REQUEST;
703 rm_req->dialog_token = guc_dialog_token;
704 rm_req->num_rpt = req_cfg->rpt_num;
705 meas_req_ie = (mac_meas_req_ie_stru *)rm_req->req_ies;
706
707 /**************************************************************************/
708 /* Measurement Request IE */
709 /* ---------------------------------------------------------------------- */
710 /* |Element ID |Length |Meas Token| Meas Req Mode|Meas Type | Meas Req | */
711 /* ---------------------------------------------------------------------- */
712 /* |1 |1 | 1 | 1 |1 |var | */
713 /* ---------------------------------------------------------------------- */
714 /* */
715 /**************************************************************************/
716 meas_req_ie->eid = MAC_EID_MEASREQ;
717 meas_req_ie->token = guc_meas_token;
718 req_mode = (osal_u8 *)(&(meas_req_ie->reqmode));
719 *req_mode = req_cfg->req_mode;
720
721 if (req_cfg->reqtype == MAC_RRM_TYPE_BCN) {
722 meas_req_ie->len = 16; /* 16 数据长度 */
723 meas_req_ie->reqtype = RM_RADIO_MEAS_BCN;
724 if (memcpy_s(meas_req_ie->meas_req, OAL_SIZEOF(mac_bcn_req_stru),
725 (mac_bcn_req_stru *)(req_cfg->p_arg), OAL_SIZEOF(mac_bcn_req_stru)) != EOK) {
726 oam_warning_log0(0, OAM_SF_CFG, "{hmac_config_encap_radio_meas_req data::memcpy err.}");
727 }
728 /* optional subelement */
729 bcn_req = (mac_bcn_req_stru *)meas_req_ie->meas_req;
730 reporting_detail = bcn_req->subelm;
731 /* 2,Reporting Detail */
732 *reporting_detail = MAC_RRM_BCN_EID_REPORTING_DATAIL;
733 *(reporting_detail + 1) = MAC_RRM_BCN_REPORTING_DETAIL_LEN;
734 *(reporting_detail + 2) = MAC_BCN_REPORTING_DETAIL_FIXED_FILELD_AND_ANY_ELEM; /* 2 偏移 */
735 meas_req_ie->len += MAC_IE_HDR_LEN + MAC_RRM_BCN_REPORTING_DETAIL_LEN;
736 } else if (req_cfg->reqtype == MAC_RRM_TYPE_CHANNEL_LOAD) {
737 meas_req_ie->len = 9; /* 9 数据长度 */
738 meas_req_ie->reqtype = RM_RADIO_MEAS_CHANNEL_LOAD;
739 if (memcpy_s(meas_req_ie->meas_req, OAL_SIZEOF(mac_chn_load_req_stru),
740 (mac_chn_load_req_stru *)(req_cfg->p_arg), OAL_SIZEOF(mac_chn_load_req_stru)) != EOK) {
741 oam_warning_log0(0, OAM_SF_CFG, "{hmac_config_encap_radio_meas_req data:: p2 memcpy err.}");
742 }
743 }
744
745 return MAC_80211_FRAME_LEN + 5 + MAC_IE_HDR_LEN + meas_req_ie->len; /* 5 长度 */
746 }
747
hmac_config_encap_neighbor_report_req(osal_u16 * frame_len,osal_u8 * buffer)748 OAL_STATIC osal_void hmac_config_encap_neighbor_report_req(osal_u16 *frame_len, osal_u8 *buffer)
749 {
750 mac_action_neighbor_req_stru *neighbor_req = OAL_PTR_NULL;
751 /* Neighbor Report Request */
752 /*************************************************************************/
753 /* Neighbor Report Request Frame - Frame Body */
754 /* --------------------------------------------------------------------- */
755 /* |Category |Action |Dialog Token| Optional subs | */
756 /* --------------------------------------------------------------------- */
757 /* |1 |1 | 1 | var */
758 /* --------------------------------------------------------------------- */
759 /* */
760 /*************************************************************************/
761 neighbor_req = (mac_action_neighbor_req_stru *)buffer;
762 neighbor_req->category = MAC_ACTION_CATEGORY_RADIO_MEASURMENT;
763 neighbor_req->action_code = MAC_RM_ACTION_NEIGHBOR_REPORT_REQUEST;
764 neighbor_req->dialog_token = guc_dialog_token;
765 *frame_len = MAC_80211_FRAME_LEN + 3; /* 3 长度 */
766 }
767
hmac_config_send_meas_req_send_event(oal_netbuf_stru * mgmt_buf,osal_u16 frame_len,hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user)768 OAL_STATIC osal_u32 hmac_config_send_meas_req_send_event(oal_netbuf_stru *mgmt_buf, osal_u16 frame_len,
769 hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user)
770 {
771 osal_u32 ul_ret;
772 mac_tx_ctl_stru *tx_ctl = OAL_PTR_NULL;
773
774 tx_ctl = (mac_tx_ctl_stru *)oal_netbuf_cb(mgmt_buf);
775 mac_get_cb_mpdu_len(tx_ctl) = frame_len;
776 mac_get_cb_tx_user_idx(tx_ctl) = (osal_u8)hmac_user->assoc_id;
777 oal_netbuf_put(mgmt_buf, frame_len);
778 ul_ret = hmac_tx_mgmt_send_event_etc(hmac_vap, mgmt_buf, frame_len);
779 if (ul_ret != OAL_SUCC) {
780 oam_warning_log2(0, OAM_SF_RRM,
781 "vap_id[%d] {hmac_config_send_meas_req::hmac_tx_mgmt_send_event_etc failed[%d].}", hmac_vap->vap_id,
782 ul_ret);
783 }
784 return ul_ret;
785 }
786
hmac_config_do_send_meas_req(mac_rrm_req_cfg_stru * req_cfg,oal_netbuf_stru * mgmt_buf,osal_u8 * buffer,hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user)787 OAL_STATIC osal_u32 hmac_config_do_send_meas_req(mac_rrm_req_cfg_stru *req_cfg, oal_netbuf_stru *mgmt_buf,
788 osal_u8 *buffer, hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user)
789 {
790 osal_u32 ul_ret;
791 oal_bool_enum_uint8 timer_en = OAL_TRUE;
792 osal_u16 frame_len = 0;
793 mac_meas_req_ie_stru *meas_req_ie = OAL_PTR_NULL;
794 mac_action_rm_req_stru *rm_req = OAL_PTR_NULL;
795 hmac_11k_user_info_stru *hmac_11k_user_info = hmac_11k_get_user_info((osal_u8)hmac_user->assoc_id);
796
797 if (hmac_11k_user_info == OSAL_NULL) {
798 return OAL_ERR_CODE_PTR_NULL;
799 }
800
801 /* Radio Measurement Request */
802 if (req_cfg->reqtype <= MAC_RRM_TYPE_BCN) {
803 if (req_cfg->p_arg == OAL_PTR_NULL) {
804 oam_warning_log1(0, OAM_SF_RRM, "vap_id[%d] {hmac_config_send_meas_req::radio meas req element null.}",
805 hmac_vap->vap_id);
806 hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, OAL_PTR_NULL);
807 return OAL_ERR_CODE_PTR_NULL;
808 }
809
810 frame_len = (osal_u16)hmac_config_encap_radio_meas_req(req_cfg, buffer, hmac_vap, hmac_user);
811 rm_req = (mac_action_rm_req_stru *)buffer;
812 meas_req_ie = (mac_meas_req_ie_stru *)rm_req->req_ies;
813
814 /* Radio Measurement Req中不允许对端发送report,则不起定时器 */
815 if ((meas_req_ie->reqmode.enable == 1) && (meas_req_ie->reqmode.rpt == 0)) {
816 oam_warning_log1(0, OAM_SF_RRM, "vap_id[%d] {hmac_config_send_meas_req::not expect report.}",
817 hmac_user->vap_id);
818 timer_en = OAL_FALSE;
819 }
820 } else if (req_cfg->reqtype == MAC_RRM_TYPE_NEIGHBOR_RPT) {
821 hmac_config_encap_neighbor_report_req(&frame_len, buffer);
822 } else {
823 hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, OAL_PTR_NULL);
824 return OAL_FAIL;
825 }
826
827 ul_ret = hmac_config_send_meas_req_send_event(mgmt_buf, frame_len, hmac_vap, hmac_user);
828 if (ul_ret != OAL_SUCC) {
829 return ul_ret;
830 }
831
832 /* Radio Measurement Req中不允许对端发送report,则不起定时器 */
833 if (timer_en != OAL_FALSE) {
834 /* 更改状态 */
835 hmac_11k_user_info->user_rrm_info->meas_status = MAC_RRM_STATE_WAIT_RSP;
836 /* 启动measurement超时定时器, 如果超时没回rsp则启动超时处理 */
837 hmac_11k_user_info->user_rrm_info->timer.timeout = 5000; // 5000: 5s
838
839 frw_create_timer_entry(&(hmac_11k_user_info->user_rrm_info->timer), hmac_wait_meas_rsp_timeout,
840 hmac_11k_user_info->user_rrm_info->timer.timeout,
841 (osal_void *)((osal_ulong)(hmac_user->assoc_id)), OAL_FALSE);
842 }
843
844 return OAL_SUCC;
845 }
846
hmac_config_send_meas_req_check(hmac_user_stru * hmac_user,mac_rrm_req_cfg_stru * req_cfg)847 OAL_STATIC osal_u32 hmac_config_send_meas_req_check(hmac_user_stru *hmac_user, mac_rrm_req_cfg_stru *req_cfg)
848 {
849 osal_u32 ul_ret;
850 hmac_11k_user_info_stru *hmac_11k_user_info = OSAL_NULL;
851
852 /* 获取USER结构体 */
853 if (hmac_user == OAL_PTR_NULL) {
854 oam_error_log0(0, OAM_SF_RRM, "{hmac_config_send_meas_req::hmac_user null.}");
855 return OAL_ERR_CODE_PTR_NULL;
856 }
857
858 /* 检测用户是否支持11K */
859 if (hmac_user->cap_info.enable_11k == OAL_FALSE) {
860 oam_warning_log1(0, OAM_SF_RRM, "vap_id[%d] {hmac_config_send_meas_req::user not support 11k.}",
861 hmac_user->vap_id);
862 return OAL_SUCC;
863 }
864
865 hmac_11k_user_info = hmac_11k_get_user_info((osal_u8)hmac_user->assoc_id);
866 if (hmac_11k_user_info == OAL_PTR_NULL || hmac_11k_user_info->user_rrm_info == OAL_PTR_NULL) {
867 oam_error_log1(0, OAM_SF_RRM, "vap_id[%d] {hmac_config_send_meas_req::11k_user_info/user_rrm_info null.}",
868 hmac_user->vap_id);
869 return OAL_ERR_CODE_PTR_NULL;
870 }
871
872 /* 检查用户11k具体能力 */
873 ul_ret = hmac_rrm_check_user_cap(&(hmac_11k_user_info->rrm_enabled_cap), req_cfg);
874 if (ul_ret != OAL_SUCC) {
875 return ul_ret;
876 }
877
878 return OAL_CONTINUE;
879 }
880
881 /*****************************************************************************
882 发起测量请求
883 *****************************************************************************/
hmac_config_send_meas_req(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,mac_rrm_req_cfg_stru * req_cfg)884 OAL_STATIC osal_u32 hmac_config_send_meas_req(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
885 mac_rrm_req_cfg_stru *req_cfg)
886 {
887 osal_u32 ul_ret;
888 oal_netbuf_stru *mgmt_buf = OAL_PTR_NULL;
889 osal_u8 *buffer = OAL_PTR_NULL;
890 hmac_11k_user_info_stru *hmac_11k_user_info = hmac_11k_get_user_info((osal_u8)hmac_user->assoc_id);
891
892 ul_ret = hmac_config_send_meas_req_check(hmac_user, req_cfg);
893 if (ul_ret != OAL_CONTINUE) {
894 return ul_ret;
895 }
896
897 /* 清除rpt mode记录 */
898 memset_s(&(hmac_11k_user_info->user_rrm_info->rptmode), OAL_SIZEOF(mac_meas_rpt_mode_stru), 0,
899 OAL_SIZEOF(mac_meas_rpt_mode_stru));
900
901 /* 记录测试模式 */
902 hmac_11k_user_info->user_rrm_info->reqtype = req_cfg->reqtype;
903 hmac_11k_user_info->user_rrm_info->rpt_notify_id = req_cfg->rpt_notify_id;
904
905 /* 检查该用户是否正在进行测量 */
906 if (hmac_11k_user_info->user_rrm_info->meas_status != MAC_RRM_STATE_INIT) {
907 oam_warning_log2(0, OAM_SF_RRM,
908 "vap_id[%d] {hmac_config_send_meas_req::meas_status[%d] not allow new req.}",
909 hmac_user->vap_id, hmac_11k_user_info->user_rrm_info->meas_status);
910 /* 通知模块 */
911 return OAL_SUCC;
912 }
913
914 /* 申请管理帧BUF */
915 mgmt_buf = (oal_netbuf_stru *)OAL_MEM_NETBUF_ALLOC(OAL_NORMAL_NETBUF, WLAN_MEM_NETBUF_SIZE2,
916 OAL_NETBUF_PRIORITY_MID);
917 if (mgmt_buf == OAL_PTR_NULL) {
918 oam_error_log1(0, OAM_SF_RRM, "vap_id[%d] {hmac_config_send_meas_req::mgmt_buf null.}",
919 hmac_vap->vap_id);
920 return OAL_PTR_NULL;
921 }
922
923 memset_s(oal_netbuf_cb(mgmt_buf), OAL_NETBUF_CB_SIZE(), 0, OAL_NETBUF_CB_SIZE());
924 // 封装基础帧
925 hmac_config_encap_mgmt_frame(&buffer, mgmt_buf, hmac_vap, hmac_user);
926 /* dialog_token记录 */
927 guc_dialog_token++;
928 guc_meas_token++;
929 hmac_11k_user_info->user_rrm_info->dialog_token = guc_dialog_token;
930 hmac_11k_user_info->user_rrm_info->meas_token = guc_meas_token;
931
932 // 封装测量内容并发送报文
933 ul_ret = hmac_config_do_send_meas_req(req_cfg, mgmt_buf, buffer, hmac_vap, hmac_user);
934 if (ul_ret != OAL_SUCC) {
935 oal_netbuf_free(mgmt_buf);
936 }
937 return ul_ret;
938 }
939
940 /*****************************************************************************
941 函 数 名 : hmac_rrm_check_user_cap
942 功能描述 : 检查用户是否支持测量方式
943 输入参数 : osal_void
944 输出参数 : 无
945 *****************************************************************************/
hmac_rrm_check_user_cap(mac_rrm_enabled_cap_ie_stru * rrm_enabled_cap,mac_rrm_req_cfg_stru * req_cfg)946 OAL_STATIC osal_u32 hmac_rrm_check_user_cap(mac_rrm_enabled_cap_ie_stru *rrm_enabled_cap,
947 mac_rrm_req_cfg_stru *req_cfg)
948 {
949 osal_u32 ul_ret = OAL_SUCC;
950 mac_bcn_req_stru *bcn_req;
951
952 /* Neighbor report Request */
953 if (req_cfg->reqtype == MAC_RRM_TYPE_NEIGHBOR_RPT &&
954 rrm_enabled_cap->neighbor_rpt_cap == OAL_FALSE) {
955 oam_warning_log2(0, OAM_SF_RRM,
956 "{hmac_rrm_check_user_cap::reqtype[%d],neighbor_rpt_cap[%d] not support.}",
957 req_cfg->reqtype, rrm_enabled_cap->neighbor_rpt_cap);
958 return OAL_FAIL;
959 }
960
961 /* Channel Load Request */
962 if (req_cfg->reqtype == MAC_RRM_TYPE_CHANNEL_LOAD &&
963 rrm_enabled_cap->chn_load_cap == OAL_FALSE) {
964 oam_warning_log2(0, OAM_SF_RRM, "{hmac_rrm_check_user_cap::reqtype[%d],chn_load_cap[%d] not support.}",
965 req_cfg->reqtype, rrm_enabled_cap->chn_load_cap);
966 return OAL_FAIL;
967 }
968
969 /* Beacon Report */
970 if (req_cfg->reqtype == MAC_RRM_TYPE_BCN) {
971 if (req_cfg->p_arg == OAL_PTR_NULL) {
972 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_check_user_cap::bcn req p_arg null.}");
973 return OAL_ERR_CODE_PTR_NULL;
974 }
975 bcn_req = (mac_bcn_req_stru *)(req_cfg->p_arg);
976
977 if (bcn_req->mode == RM_BCN_REQ_MEAS_MODE_PASSIVE &&
978 rrm_enabled_cap->bcn_passive_cap == OAL_FALSE) {
979 oam_warning_log1(0, OAM_SF_RRM, "{hmac_rrm_check_user_cap::bcn::bcn_passive_cap[%d] not support.}",
980 rrm_enabled_cap->bcn_passive_cap);
981 return OAL_FAIL;
982 }
983
984 if (bcn_req->mode == RM_BCN_REQ_MEAS_MODE_ACTIVE &&
985 rrm_enabled_cap->bcn_active_cap == OAL_FALSE) {
986 oam_warning_log1(0, OAM_SF_RRM, "{hmac_rrm_check_user_cap::bcn::bcn_active_cap[%d] not support.}",
987 rrm_enabled_cap->bcn_active_cap);
988 return OAL_FAIL;
989 }
990
991 if (bcn_req->mode == RM_BCN_REQ_MEAS_MODE_TABLE &&
992 rrm_enabled_cap->bcn_table_cap == OAL_FALSE) {
993 oam_warning_log1(0, OAM_SF_RRM, "{hmac_rrm_check_user_cap::bcn::bcn_table_cap[%d] not support.}",
994 rrm_enabled_cap->bcn_table_cap);
995 return OAL_FAIL;
996 }
997 }
998
999 return ul_ret;
1000 }
1001
hmac_rrm_free_bcn_rpt(hmac_user_stru * hmac_user)1002 OAL_STATIC osal_void hmac_rrm_free_bcn_rpt(hmac_user_stru *hmac_user)
1003 {
1004 mac_user_rrm_info_stru *rrm_info = OSAL_NULL;
1005 mac_meas_rpt_bcn_stru *bcn = OAL_PTR_NULL;
1006 struct osal_list_head *list = OAL_PTR_NULL;
1007 hmac_11k_user_info_stru *hmac_11k_user_info = hmac_11k_get_user_info((osal_u8)hmac_user->assoc_id);
1008
1009 if (hmac_11k_user_info == OSAL_NULL) {
1010 return;
1011 }
1012
1013 rrm_info = hmac_11k_user_info->user_rrm_info;
1014 do {
1015 /* 获取节点 */
1016 list = rrm_info->meas_rpt_list.next;
1017 bcn = osal_list_entry(list, mac_meas_rpt_bcn_stru, dlist_head);
1018 if (bcn == OAL_PTR_NULL) {
1019 continue;
1020 }
1021
1022 /* 释放节点 */
1023 osal_list_del(list);
1024 hmac_rrm_beacon_measure_free_one_rpt_bcn_item(bcn);
1025 bcn = OAL_PTR_NULL;
1026 } while (osal_list_empty(&(rrm_info->meas_rpt_list)) == 0);
1027
1028 return;
1029 }
1030
hmac_rrm_free_chan_load_rpt(hmac_user_stru * hmac_user)1031 OAL_STATIC osal_void hmac_rrm_free_chan_load_rpt(hmac_user_stru *hmac_user)
1032 {
1033 struct osal_list_head *list = OAL_PTR_NULL;
1034 mac_meas_rpt_chn_load_stru *chn_load = OAL_PTR_NULL;
1035 hmac_11k_user_info_stru *hmac_11k_user_info = hmac_11k_get_user_info((osal_u8)hmac_user->assoc_id);
1036 mac_user_rrm_info_stru *rrm_info = OSAL_NULL;
1037
1038 if (hmac_11k_user_info == OSAL_NULL) {
1039 return;
1040 }
1041
1042 rrm_info = hmac_11k_user_info->user_rrm_info;
1043
1044 do {
1045 /* 获取节点 */
1046 list = rrm_info->meas_rpt_list.next;
1047 chn_load = osal_list_entry(list, mac_meas_rpt_chn_load_stru, dlist_head_chn_load);
1048 if (chn_load == OAL_PTR_NULL) {
1049 continue;
1050 }
1051
1052 if (chn_load->meas_rpt_chn_load_item != OAL_PTR_NULL) {
1053 oal_mem_free(chn_load->meas_rpt_chn_load_item, OAL_TRUE);
1054 chn_load->meas_rpt_chn_load_item = OAL_PTR_NULL;
1055 }
1056
1057 /* 释放节点 */
1058 osal_list_del(list);
1059 oal_mem_free(chn_load, OAL_TRUE);
1060 chn_load = OAL_PTR_NULL;
1061 } while (osal_list_empty(&(rrm_info->meas_rpt_list)) == 0);
1062 return;
1063 }
1064
hmac_rrm_free_neighbor_rpt(hmac_user_stru * hmac_user)1065 OAL_STATIC osal_void hmac_rrm_free_neighbor_rpt(hmac_user_stru *hmac_user)
1066 {
1067 mac_meas_rpt_neighbor_stru *neighbor = OAL_PTR_NULL;
1068 struct osal_list_head *list = OAL_PTR_NULL;
1069 mac_user_rrm_info_stru *rrm_info = OSAL_NULL;
1070 hmac_11k_user_info_stru *hmac_11k_user_info = hmac_11k_get_user_info((osal_u8)hmac_user->assoc_id);
1071
1072 if (hmac_11k_user_info == OSAL_NULL) {
1073 return;
1074 }
1075
1076 rrm_info = hmac_11k_user_info->user_rrm_info;
1077 do {
1078 /* 获取节点 */
1079 list = rrm_info->meas_rpt_list.next;
1080 neighbor = osal_list_entry(list, mac_meas_rpt_neighbor_stru, dlist_head_neighbor);
1081 if (neighbor == OAL_PTR_NULL) {
1082 continue;
1083 }
1084
1085 if (neighbor->meas_rpt_neighbor_item != OAL_PTR_NULL) {
1086 oal_mem_free(neighbor->meas_rpt_neighbor_item, OAL_TRUE);
1087 neighbor->meas_rpt_neighbor_item = OAL_PTR_NULL;
1088 }
1089
1090 /* 释放节点 */
1091 osal_list_del(list);
1092 oal_mem_free(neighbor, OAL_TRUE);
1093 neighbor = OAL_PTR_NULL;
1094 } while (osal_list_empty(&(rrm_info->meas_rpt_list)) == 0);
1095
1096 return;
1097 }
1098
1099 /*****************************************************************************
1100 函 数 名 : hmac_rrm_free_rpt_list
1101 功能描述 : 释放链表
1102 输入参数 : osal_void
1103 输出参数 : 无
1104 *****************************************************************************/
hmac_rrm_free_rpt_list(hmac_user_stru * hmac_user,mac_rrm_type_enum reqtype)1105 OAL_STATIC osal_void hmac_rrm_free_rpt_list(hmac_user_stru *hmac_user, mac_rrm_type_enum reqtype)
1106 {
1107 /* 11K状态恢复 */
1108 hmac_11k_user_info_stru *hmac_11k_user_info = hmac_11k_get_user_info((osal_u8)hmac_user->assoc_id);
1109
1110 if (hmac_11k_user_info == OSAL_NULL || hmac_11k_user_info->user_rrm_info == OSAL_NULL) {
1111 return;
1112 }
1113
1114 hmac_11k_user_info->user_rrm_info->meas_status = MAC_RRM_STATE_INIT;
1115
1116 if (osal_list_empty(&(hmac_11k_user_info->user_rrm_info->meas_rpt_list)) != 0) {
1117 return;
1118 }
1119
1120 /* 遍历扫描到的bss信息 */
1121 /* Beacon Report */
1122 if (reqtype == MAC_RRM_TYPE_BCN) {
1123 hmac_rrm_free_bcn_rpt(hmac_user);
1124 }
1125
1126 /* CHANNEL LOAD Report */
1127 if (reqtype == MAC_RRM_TYPE_CHANNEL_LOAD) {
1128 hmac_rrm_free_chan_load_rpt(hmac_user);
1129 }
1130
1131 /* Neighbor Report */
1132 if (reqtype == MAC_RRM_TYPE_NEIGHBOR_RPT) {
1133 hmac_rrm_free_neighbor_rpt(hmac_user);
1134 }
1135
1136 oam_warning_log0(0, OAM_SF_RRM,
1137 "{hmac_rrm_free_rpt_list: free meas_rpt_list node and set meas_status as MAC_RRM_STATE_INIT.}");
1138
1139 return;
1140 }
1141
1142 /*****************************************************************************
1143 函 数 名 : hmac_wait_meas_rsp_timeout
1144 功能描述 : 发起测量请求
1145 输入参数 : hmac_user_stru *hmac_user;
1146 输出参数 : 无
1147 *****************************************************************************/
hmac_wait_meas_rsp_timeout(osal_void * p_arg)1148 OAL_STATIC osal_u32 hmac_wait_meas_rsp_timeout(osal_void *p_arg)
1149 {
1150 hmac_user_stru *hmac_user;
1151 osal_u16 assoc_id;
1152 hmac_11k_user_info_stru *hmac_11k_user_info = OSAL_NULL;
1153
1154 if (p_arg == OSAL_NULL) {
1155 return OAL_ERR_CODE_PTR_NULL;
1156 }
1157
1158 assoc_id = (osal_u16)(osal_ulong)(p_arg);
1159
1160 /* 获取USER结构体 */
1161 hmac_user = (hmac_user_stru *)mac_res_get_hmac_user_etc(assoc_id);
1162 if (hmac_user == OAL_PTR_NULL) {
1163 oam_warning_log0(0, OAM_SF_RRM, "{hmac_wait_meas_rsp_timeout::hmac_user null.}");
1164 return OAL_ERR_CODE_PTR_NULL;
1165 }
1166
1167 hmac_11k_user_info = hmac_11k_get_user_info((osal_u8)assoc_id);
1168 if (hmac_11k_user_info == OAL_PTR_NULL || hmac_11k_user_info->user_rrm_info == OAL_PTR_NULL) {
1169 oam_warning_log1(0, OAM_SF_RRM,
1170 "vap_id[%d] {hmac_wait_meas_rsp_timeout::hmac_11k_user_info/user_rrm_info null.}",
1171 hmac_user->vap_id);
1172 return OAL_ERR_CODE_PTR_NULL;
1173 }
1174
1175 oam_warning_log2(0, OAM_SF_RRM, "vap_id[%d] {hmac_wait_meas_rsp_timeout::reqtype=%d.}",
1176 hmac_user->vap_id, hmac_11k_user_info->user_rrm_info->reqtype);
1177
1178 /* 更改状态 */
1179 hmac_11k_user_info->user_rrm_info->meas_status = MAC_RRM_STATE_RSP_TIMEOUT;
1180
1181 /* 通知模块 */
1182 /* 释放链表和恢复状态 */
1183 hmac_rrm_free_rpt_list(hmac_user, hmac_11k_user_info->user_rrm_info->reqtype);
1184
1185 return OAL_SUCC;
1186 }
1187
1188 /*****************************************************************************
1189 函 数 名 : hmac_vap_meas_status_timeout
1190 功能描述 : 发起测量请求
1191 输入参数 : hmac_vap_stru *hmac_vap;
1192 输出参数 : 无
1193 *****************************************************************************/
1194
hmac_vap_meas_status_timeout(osal_void * p_arg)1195 OAL_STATIC osal_u32 hmac_vap_meas_status_timeout(osal_void *p_arg)
1196 {
1197 mac_vap_rrm_info_stru *rrm_info;
1198 rrm_info = (mac_vap_rrm_info_stru *)p_arg;
1199
1200 if (rrm_info == OAL_PTR_NULL) {
1201 oam_warning_log0(0, OAM_SF_RRM, "{hmac_vap_meas_status_timeout::rrm_info null.}");
1202 return OAL_ERR_CODE_PTR_NULL;
1203 }
1204
1205 /* 更改状态 */
1206 rrm_info->is_measuring = OAL_FALSE;
1207
1208 reset_rrm_info(rrm_info);
1209 return OAL_SUCC;
1210 }
1211
1212 /*****************************************************************************
1213 函 数 名 : hmac_rrm_get_meas_start_time
1214 功能描述 : hmac接收dmac抛回来的查询应答事件
1215 输入参数 : 无
1216 输出参数 : 无
1217 *****************************************************************************/
hmac_rrm_get_meas_start_time(osal_void * notify_data)1218 OAL_STATIC osal_bool hmac_rrm_get_meas_start_time(osal_void *notify_data)
1219 {
1220 hmac_device_stru *hmac_device = (hmac_device_stru *)notify_data;
1221 hmac_vap_stru *hmac_vap = OSAL_NULL;
1222 osal_u32 meas_start_time[2]; /* 2表示数组大小 */
1223 hmac_11k_vap_info_stru *hmac_11k_vap_info = OSAL_NULL;
1224
1225 hmac_vap = mac_res_get_hmac_vap(hmac_device->scan_params.vap_id);
1226 if (hmac_vap == OAL_PTR_NULL) {
1227 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_get_meas_start_time:: hmac_vap is null.}");
1228 return OAL_FALSE;
1229 }
1230
1231 if (hmac_vap_id_param_check(hmac_vap->vap_id) != OSAL_TRUE) {
1232 return OSAL_TRUE;
1233 }
1234
1235 if (!is_legacy_sta(hmac_vap)) {
1236 return OSAL_TRUE;
1237 }
1238
1239 if (mac_mib_get_dot11_radio_measurement_activated(hmac_vap) != OAL_TRUE) {
1240 return OSAL_TRUE;
1241 }
1242
1243 hmac_11k_vap_info = hmac_11k_get_vap_info(hmac_vap);
1244 if (hmac_11k_vap_info == OSAL_NULL) {
1245 return OSAL_FALSE;
1246 }
1247
1248 if (hmac_11k_vap_info->enable_11k != 0 && hmac_11k_vap_info->rrm_info != OAL_PTR_NULL) {
1249 hal_vap_tsf_get_64bit(hmac_vap->hal_vap, (osal_u32 *)&meas_start_time[1], (osal_u32 *)&meas_start_time[0]);
1250 /* Actual Meas Start Time */
1251 if (memcpy_s(hmac_11k_vap_info->rrm_info->act_meas_start_time, OAL_SIZEOF(osal_u32) * 2, /* 2倍大小 */
1252 meas_start_time, OAL_SIZEOF(osal_u32) * 2) != EOK) { /* 2倍大小 */
1253 oam_warning_log0(0, OAM_SF_CFG, "{hmac_rrm_get_meas_start_time data::memcpy err.}");
1254 }
1255 }
1256
1257 return OAL_TRUE;
1258 }
1259
1260 /*****************************************************************************
1261 函 数 名 : hmac_rrm_fill_basic_rm_rpt_action
1262 功能描述 : 申请管理帧内存,填充管理帧和Radio Measurement Report的固定域
1263 输入参数 : hmac_vap
1264 输出参数 : 无
1265 *****************************************************************************/
hmac_rrm_fill_basic_rm_rpt_action(hmac_vap_stru * hmac_vap)1266 OAL_STATIC osal_u32 hmac_rrm_fill_basic_rm_rpt_action(hmac_vap_stru *hmac_vap)
1267 {
1268 osal_u8 *mac_header;
1269 osal_u8 *payload;
1270 hmac_user_stru *hmac_user = OSAL_NULL;
1271 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
1272
1273 if (rrm_info == OAL_PTR_NULL) {
1274 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_fill_basic_rm_rpt_action::rrm_info NULL!}");
1275 return OAL_ERR_CODE_PTR_NULL;
1276 }
1277
1278 if (rrm_info->rm_rpt_mgmt_buf != OAL_PTR_NULL) {
1279 oal_netbuf_free(rrm_info->rm_rpt_mgmt_buf);
1280 rrm_info->rm_rpt_mgmt_buf = OAL_PTR_NULL;
1281 oam_warning_log1(0, OAM_SF_RRM,
1282 "vap_id[%d] {hmac_rrm_fill_basic_rm_rpt_action::mgmt_buf not be freed in history.}",
1283 hmac_vap->vap_id);
1284 }
1285
1286 /* 申请管理帧内存 */
1287 rrm_info->rm_rpt_mgmt_buf = OAL_MEM_NETBUF_ALLOC(OAL_NORMAL_NETBUF, WLAN_LARGE_NETBUF_SIZE,
1288 OAL_NETBUF_PRIORITY_MID);
1289 if (rrm_info->rm_rpt_mgmt_buf == OAL_PTR_NULL) {
1290 oam_error_log1(0, OAM_SF_RRM, "vap_id[%d] {hmac_rrm_fill_basic_rm_rpt_action::mgmt_buf null.}",
1291 hmac_vap->vap_id);
1292 return OAL_ERR_CODE_PTR_NULL;
1293 }
1294 oal_set_netbuf_prev(rrm_info->rm_rpt_mgmt_buf, OAL_PTR_NULL);
1295 oal_set_netbuf_next(rrm_info->rm_rpt_mgmt_buf, OAL_PTR_NULL);
1296
1297 /*************************************************************************/
1298 /* Management Frame Format */
1299 /* -------------------------------------------------------------------- */
1300 /* |Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS| */
1301 /* -------------------------------------------------------------------- */
1302 /* | 2 |2 |6 |6 |6 |2 |0 - 2312 |4 | */
1303 /* -------------------------------------------------------------------- */
1304 /* */
1305 /*************************************************************************/
1306
1307 /*************************************************************************/
1308 /* Set the fields in the frame header */
1309 /*************************************************************************/
1310 mac_header = oal_netbuf_header(rrm_info->rm_rpt_mgmt_buf);
1311
1312 /* 帧控制字段全为0,除了type和subtype */
1313 mac_hdr_set_frame_control(mac_header, WLAN_PROTOCOL_VERSION | WLAN_FC0_TYPE_MGT | WLAN_FC0_SUBTYPE_ACTION);
1314
1315 /* 设置分片序号为0 */
1316 mac_hdr_set_fragment_number(mac_header, 0);
1317
1318 hmac_user = mac_res_get_hmac_user_etc(rrm_info->req_user_id);
1319 if (hmac_user == OAL_PTR_NULL) {
1320 /* ERROR to Warning */
1321 oam_warning_log1(0, OAM_SF_TX, "{hmac_rrm_fill_basic_rm_rpt_action::hmac_user[%d] null.",
1322 rrm_info->req_user_id);
1323 oal_netbuf_free(rrm_info->rm_rpt_mgmt_buf);
1324 rrm_info->rm_rpt_mgmt_buf = OAL_PTR_NULL;
1325 return OAL_ERR_CODE_PTR_NULL;
1326 }
1327
1328 /* 设置地址1,用户地址 */
1329 oal_set_mac_addr(mac_header + WLAN_HDR_ADDR1_OFFSET, hmac_user->user_mac_addr);
1330
1331 /* 设置地址2为自己的MAC地址 */
1332 oal_set_mac_addr(mac_header + WLAN_HDR_ADDR2_OFFSET, mac_mib_get_station_id(hmac_vap));
1333
1334 /* 地址3,为VAP自己的MAC地址 */
1335 oal_set_mac_addr(mac_header + WLAN_HDR_ADDR3_OFFSET, hmac_vap->bssid);
1336
1337 /*************************************************************************/
1338 /* Radio Measurement Report Frame - Frame Body */
1339 /* --------------------------------------------------------------------- */
1340 /* |Category |Action |Dialog Token| Measurement Report Elements | */
1341 /* --------------------------------------------------------------------- */
1342 /* |1 |1 | 1 | var */
1343 /* --------------------------------------------------------------------- */
1344 /* */
1345 /*************************************************************************/
1346 payload = mac_netbuf_get_payload(rrm_info->rm_rpt_mgmt_buf);
1347
1348 rrm_info->rm_rpt_action = (mac_action_rm_rpt_stru *)payload;
1349 rrm_info->rm_rpt_action->category = MAC_ACTION_CATEGORY_RADIO_MEASURMENT;
1350 rrm_info->rm_rpt_action->action_code = rrm_info->action_code + 1; // radio or neighbor reponse
1351 rrm_info->rm_rpt_action->dialog_token = rrm_info->dialog_token;
1352
1353 rrm_info->rm_rpt_action_len = MAC_ACTION_RPT_FIX_LEN + MAC_80211_FRAME_LEN;
1354 return OAL_SUCC;
1355 }
1356
hmac_rrm_send_rm_rpt_action_check(hmac_vap_stru * hmac_vap)1357 OAL_STATIC osal_u32 hmac_rrm_send_rm_rpt_action_check(hmac_vap_stru *hmac_vap)
1358 {
1359 oal_netbuf_stru *mgmt_buf = OAL_PTR_NULL;
1360 hmac_user_stru *hmac_user = OAL_PTR_NULL;
1361 mac_vap_rrm_info_stru *rrm_info = OAL_PTR_NULL;
1362
1363 if (hmac_vap == OAL_PTR_NULL) {
1364 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_send_rm_rpt_action_check::hmac_vap NULL!}");
1365 return OAL_ERR_CODE_PTR_NULL;
1366 }
1367
1368 rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
1369 if (rrm_info == OAL_PTR_NULL) {
1370 oam_error_log1(0, OAM_SF_RRM, "vap_id[%d] {hmac_rrm_send_rm_rpt_action_check::rrm_info NULL!}",
1371 hmac_vap->vap_id);
1372 return OAL_ERR_CODE_PTR_NULL;
1373 }
1374
1375 rrm_info->is_measuring = OAL_FALSE;
1376 /* 取消定时器 */
1377 if (rrm_info->meas_status_timer.is_registerd == OAL_TRUE) {
1378 frw_destroy_timer_entry(&(rrm_info->meas_status_timer));
1379 oam_warning_log1(0, OAM_SF_RRM, "vap_id[%d] {hmac_rrm_send_rm_rpt_action_check:: cancel meas_status_timer.}",
1380 hmac_vap->vap_id);
1381 }
1382
1383 mgmt_buf = rrm_info->rm_rpt_mgmt_buf;
1384 if (mgmt_buf == OAL_PTR_NULL) {
1385 oam_error_log1(0, OAM_SF_RRM, "vap_id[%d] {hmac_rrm_send_rm_rpt_action_check::mgmt_buf NULL!}",
1386 hmac_vap->vap_id);
1387 return OAL_ERR_CODE_PTR_NULL;
1388 }
1389
1390 hmac_user = mac_res_get_hmac_user_etc(rrm_info->req_user_id);
1391 if (hmac_user == OAL_PTR_NULL) {
1392 oam_error_log2(0, OAM_SF_RRM, "vap_id[%d] {hmac_rrm_send_rm_rpt_action_check::hmac_user[%d] null.",
1393 hmac_vap->vap_id, rrm_info->req_user_id);
1394 oal_netbuf_free(rrm_info->rm_rpt_mgmt_buf);
1395 rrm_info->rm_rpt_mgmt_buf = OAL_PTR_NULL;
1396 return OAL_ERR_CODE_PTR_NULL;
1397 }
1398 return OAL_SUCC;
1399 }
1400
1401 /*****************************************************************************
1402 发送已经组装好的Radio Measurement Report帧
1403 *****************************************************************************/
hmac_rrm_send_rm_rpt_action(hmac_vap_stru * hmac_vap)1404 OAL_STATIC osal_u32 hmac_rrm_send_rm_rpt_action(hmac_vap_stru *hmac_vap)
1405 {
1406 mac_tx_ctl_stru *tx_ctl = OAL_PTR_NULL;
1407 oal_netbuf_stru *mgmt_buf = OAL_PTR_NULL;
1408 osal_u32 ul_ret;
1409 hmac_user_stru *hmac_user = OAL_PTR_NULL;
1410 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
1411
1412 ul_ret = hmac_rrm_send_rm_rpt_action_check(hmac_vap);
1413 if (ul_ret != OAL_SUCC) {
1414 return ul_ret;
1415 }
1416
1417 mgmt_buf = rrm_info->rm_rpt_mgmt_buf;
1418 hmac_user = mac_res_get_hmac_user_etc(rrm_info->req_user_id);
1419
1420 /* 填写netbuf的cb字段,供发送管理帧和发送完成接口使用 */
1421 tx_ctl = (mac_tx_ctl_stru *)oal_netbuf_cb(mgmt_buf);
1422 memset_s(tx_ctl, sizeof(mac_tx_ctl_stru), 0, sizeof(mac_tx_ctl_stru));
1423
1424 mac_get_cb_tx_user_idx(tx_ctl) = (osal_u8)hmac_user->assoc_id;
1425 mac_get_cb_wme_ac_type(tx_ctl) = WLAN_WME_AC_MGMT;
1426 mac_get_cb_mpdu_len(tx_ctl) = rrm_info->rm_rpt_action_len;
1427 oal_netbuf_put(mgmt_buf, rrm_info->rm_rpt_action_len);
1428
1429 /* 调用发送管理帧接口 */
1430 ul_ret = hmac_tx_mgmt_send_event_etc(hmac_vap, mgmt_buf, rrm_info->rm_rpt_action_len);
1431 if (ul_ret != OAL_SUCC) {
1432 oal_netbuf_free(mgmt_buf);
1433 oam_error_log1(0, OAM_SF_RRM, "vap_id[%d] {hmac_rrm_send_rm_rpt_action::tx link meas rpt action failed.}",
1434 hmac_vap->vap_id);
1435 }
1436
1437 rrm_info->rm_rpt_mgmt_buf = OSAL_NULL;
1438 return ul_ret;
1439 }
1440
1441 /*****************************************************************************
1442 函 数 名 : hmac_rrm_encap_meas_rpt_reject
1443 功能描述 : 发送携带拒绝或者不支持信息的Radio Measurement Report
1444 输入参数 : hmac_vap
1445 rptmode
1446 输出参数 : 无
1447 *****************************************************************************/
hmac_rrm_encap_meas_rpt_reject(hmac_vap_stru * hmac_vap,mac_meas_rpt_mode_stru * rptmode)1448 OAL_STATIC osal_void hmac_rrm_encap_meas_rpt_reject(hmac_vap_stru *hmac_vap, mac_meas_rpt_mode_stru *rptmode)
1449 {
1450 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
1451 mac_meas_rpt_ie_stru *meas_rpt_ie;
1452
1453 if ((hmac_vap == OAL_PTR_NULL) || (rptmode == OAL_PTR_NULL)) {
1454 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_encap_meas_rpt_reject:: null param!}");
1455 return;
1456 }
1457
1458 if (rrm_info == OAL_PTR_NULL) {
1459 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_encap_meas_rpt_reject:: rrm_info null!}");
1460 return;
1461 }
1462
1463 rrm_info->is_measuring = OAL_FALSE;
1464 /* 取消定时器 */
1465 if (rrm_info->meas_status_timer.is_registerd == OAL_TRUE) {
1466 frw_destroy_timer_entry(&(rrm_info->meas_status_timer));
1467 oam_warning_log1(0, OAM_SF_RRM, "vap_id[%d] {hmac_rrm_encap_meas_rpt_reject:: cancel meas_status_timer.}",
1468 hmac_vap->vap_id);
1469 }
1470
1471 if (hmac_rrm_fill_basic_rm_rpt_action(hmac_vap) != OAL_SUCC) {
1472 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_encap_meas_rpt_reject:: hmac_rrm_fill_basic_rm_rpt_action fail!}");
1473 return;
1474 }
1475
1476 if ((rrm_info->rm_rpt_action == OSAL_NULL) || (rrm_info->meas_req_ie == OSAL_NULL)) {
1477 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_encap_meas_rpt_reject::rrm_info has NULL PTR!}");
1478 return;
1479 }
1480
1481 meas_rpt_ie = (mac_meas_rpt_ie_stru *)rrm_info->rm_rpt_action->rpt_ies;
1482
1483 /**************************************************************************/
1484 /* Measurement Report IE - Frame Body */
1485 /* ---------------------------------------------------------------------- */
1486 /* |Element ID |Length |Meas Token| Meas Rpt Mode | Meas Type | Meas Rpt| */
1487 /* ---------------------------------------------------------------------- */
1488 /* |1 |1 | 1 | 1 | 1 | var */
1489 /* ---------------------------------------------------------------------- */
1490 /* */
1491 /**************************************************************************/
1492 meas_rpt_ie->eid = MAC_EID_MEASREP;
1493 meas_rpt_ie->token = rrm_info->meas_req_ie->token;
1494 meas_rpt_ie->rpttype = rrm_info->meas_req_ie->reqtype;
1495 if (memcpy_s(&(meas_rpt_ie->rptmode), OAL_SIZEOF(mac_meas_rpt_mode_stru),
1496 rptmode, OAL_SIZEOF(mac_meas_rpt_mode_stru)) != EOK) {
1497 oam_warning_log0(0, OAM_SF_CFG, "{hmac_rrm_encap_meas_rpt_reject data::memcpy err.}");
1498 }
1499 meas_rpt_ie->len = MAC_MEASUREMENT_RPT_FIX_LEN - MAC_IE_HDR_LEN;
1500
1501 rrm_info->rm_rpt_action_len += MAC_MEASUREMENT_RPT_FIX_LEN;
1502
1503 (osal_void)hmac_rrm_send_rm_rpt_action(hmac_vap);
1504 }
1505
hmac_rrm_fill_meas_frame_body(oal_netbuf_stru * mgmt_buf,hmac_user_stru * hmac_user,hmac_vap_stru * hmac_vap,mac_action_rm_req_stru * rm_req,osal_u16 * frame_len)1506 OAL_STATIC osal_void hmac_rrm_fill_meas_frame_body(oal_netbuf_stru *mgmt_buf, hmac_user_stru *hmac_user,
1507 hmac_vap_stru *hmac_vap, mac_action_rm_req_stru *rm_req, osal_u16 *frame_len)
1508 {
1509 osal_u8 *mac_hdr = OAL_PTR_NULL;
1510 osal_u8 *payload = OAL_PTR_NULL;
1511 mac_meas_rpt_ie_stru *meas_rpt_ie = OAL_PTR_NULL;
1512 mac_action_rm_rpt_stru *rm_rpt_action = OAL_PTR_NULL;
1513 mac_tx_ctl_stru *tx_ctl = OAL_PTR_NULL;
1514 mac_meas_req_ie_stru *meas_req_ie = OAL_PTR_NULL;
1515
1516 meas_req_ie = (mac_meas_req_ie_stru *)&(rm_req->req_ies[0]);
1517
1518 /*************************************************************************/
1519 /* Management Frame Format */
1520 /* -------------------------------------------------------------------- */
1521 /* |Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS| */
1522 /* -------------------------------------------------------------------- */
1523 /* | 2 |2 |6 |6 |6 |2 |0 - 2312 |4 | */
1524 /* -------------------------------------------------------------------- */
1525 /* */
1526 /*************************************************************************/
1527
1528 /*************************************************************************/
1529 /* Set the fields in the frame header */
1530 /*************************************************************************/
1531 mac_hdr = oal_netbuf_header(mgmt_buf);
1532
1533 /* 帧控制字段全为0,除了type和subtype */
1534 mac_hdr_set_frame_control(mac_hdr, WLAN_PROTOCOL_VERSION | WLAN_FC0_TYPE_MGT | WLAN_FC0_SUBTYPE_ACTION);
1535
1536 /* 设置分片序号为0 */
1537 mac_hdr_set_fragment_number(mac_hdr, 0);
1538
1539 /* 设置地址1,用户地址 */
1540 oal_set_mac_addr(mac_hdr + WLAN_HDR_ADDR1_OFFSET, hmac_user->user_mac_addr);
1541
1542 /* 设置地址2为自己的MAC地址 */
1543 oal_set_mac_addr(mac_hdr + WLAN_HDR_ADDR2_OFFSET, mac_mib_get_station_id(hmac_vap));
1544
1545 /* 地址3,为VAP自己的MAC地址 */
1546 oal_set_mac_addr(mac_hdr + WLAN_HDR_ADDR3_OFFSET, hmac_vap->bssid);
1547
1548 /*************************************************************************/
1549 /* Radio Measurement Report Frame - Frame Body */
1550 /* --------------------------------------------------------------------- */
1551 /* |Category |Action |Dialog Token| Measurement Report Elements | */
1552 /* --------------------------------------------------------------------- */
1553 /* |1 |1 | 1 | var */
1554 /* --------------------------------------------------------------------- */
1555 /* */
1556 /*************************************************************************/
1557 payload = mac_netbuf_get_payload(mgmt_buf);
1558
1559 rm_rpt_action = (mac_action_rm_rpt_stru *)payload;
1560 rm_rpt_action->category = MAC_ACTION_CATEGORY_RADIO_MEASURMENT;
1561 rm_rpt_action->action_code = MAC_RM_ACTION_RADIO_MEASUREMENT_REPORT;
1562 rm_rpt_action->dialog_token = rm_req->dialog_token;
1563
1564 *frame_len = MAC_ACTION_RPT_FIX_LEN + MAC_MEASUREMENT_RPT_FIX_LEN + MAC_80211_FRAME_LEN;
1565
1566 meas_rpt_ie = (mac_meas_rpt_ie_stru *)rm_rpt_action->rpt_ies;
1567
1568 /**************************************************************************/
1569 /* Measurement Report IE - Frame Body */
1570 /* ---------------------------------------------------------------------- */
1571 /* |Element ID |Length |Meas Token| Meas Rpt Mode | Meas Type | Meas Rpt| */
1572 /* ---------------------------------------------------------------------- */
1573 /* |1 |1 | 1 | 1 | 1 | var */
1574 /* ---------------------------------------------------------------------- */
1575 /* */
1576 /**************************************************************************/
1577 meas_rpt_ie->eid = MAC_EID_MEASREP;
1578 meas_rpt_ie->token = meas_req_ie->token;
1579 meas_rpt_ie->rpttype = meas_req_ie->reqtype;
1580 meas_rpt_ie->rptmode.refused = 1;
1581 meas_rpt_ie->len = MAC_ACTION_RPT_FIX_LEN;
1582
1583 /* 填写netbuf的cb字段,供发送管理帧和发送完成接口使用 */
1584 tx_ctl = (mac_tx_ctl_stru *)oal_netbuf_cb(mgmt_buf);
1585 memset_s(tx_ctl, sizeof(mac_tx_ctl_stru), 0, sizeof(mac_tx_ctl_stru));
1586
1587 mac_get_cb_tx_user_idx(tx_ctl) = (osal_u8)hmac_user->assoc_id;
1588 mac_get_cb_wme_ac_type(tx_ctl) = WLAN_WME_AC_MGMT;
1589 return;
1590 }
1591
1592 /*****************************************************************************
1593 VAP收到多个测量请求,则拒绝新的测量请求
1594 *****************************************************************************/
hmac_rrm_encap_meas_rpt_refuse_new_req(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,mac_action_rm_req_stru * rm_req)1595 OAL_STATIC osal_u32 hmac_rrm_encap_meas_rpt_refuse_new_req(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
1596 mac_action_rm_req_stru *rm_req)
1597 {
1598 oal_netbuf_stru *mgmt_buf = OAL_PTR_NULL;
1599 osal_u16 action_len = 0;
1600 osal_u32 ul_ret;
1601 mac_meas_req_ie_stru *meas_req_ie = OAL_PTR_NULL;
1602
1603 if (hmac_vap == OAL_PTR_NULL || hmac_user == OAL_PTR_NULL || rm_req == OAL_PTR_NULL) {
1604 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_encap_meas_rpt_refuse_new_req::input is NULL!}");
1605 return OAL_ERR_CODE_PTR_NULL;
1606 }
1607
1608 meas_req_ie = (mac_meas_req_ie_stru *)&(rm_req->req_ies[0]);
1609
1610 /* Req中不允许发送对应的report */
1611 if ((meas_req_ie->reqmode.enable == 1) && (meas_req_ie->reqmode.rpt == 0)) {
1612 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_encap_meas_rpt_refuse_new_req::rpt now allowed!}");
1613 return OAL_SUCC;
1614 }
1615
1616 /* 申请管理帧内存 */
1617 mgmt_buf = OAL_MEM_NETBUF_ALLOC(OAL_NORMAL_NETBUF, WLAN_LARGE_NETBUF_SIZE, OAL_NETBUF_PRIORITY_MID);
1618 if (mgmt_buf == OAL_PTR_NULL) {
1619 oam_error_log1(0, OAM_SF_RRM, "vap_id[%d] {hmac_rrm_encap_meas_rpt_refuse_new_req::mgmt_buf null.}",
1620 hmac_vap->vap_id);
1621 return OAL_ERR_CODE_PTR_NULL;
1622 }
1623
1624 memset_s(oal_netbuf_cb(mgmt_buf), OAL_NETBUF_CB_SIZE(), 0, OAL_NETBUF_CB_SIZE());
1625 hmac_rrm_fill_meas_frame_body(mgmt_buf, hmac_user, hmac_vap, rm_req, &action_len);
1626 oal_netbuf_put(mgmt_buf, action_len);
1627
1628 /* 调用发送管理帧接口 */
1629 ul_ret = hmac_tx_mgmt_send_event_etc(hmac_vap, mgmt_buf, action_len);
1630 if (ul_ret != OAL_SUCC) {
1631 oal_netbuf_free(mgmt_buf);
1632 oam_error_log1(0, OAM_SF_RRM,
1633 "vap_id[%d] {hmac_rrm_encap_meas_rpt_refuse_new_req::tx link meas rpt action failed.}",
1634 hmac_vap->vap_id);
1635 return ul_ret;
1636 }
1637
1638 return OAL_SUCC;
1639 }
1640
1641 /*****************************************************************************
1642 函 数 名 : hmac_rrm_bcn_rpt_filter
1643 功能描述 : bcn_rpt_filter
1644 输入参数 : hmac_vap_stru *hmac_vap,
1645 mac_bss_dscr_stru *bss_dscr
1646 输出参数 : 无
1647 *****************************************************************************/
hmac_rrm_bcn_rpt_filter(hmac_vap_stru * hmac_vap,mac_bss_dscr_stru * bss_dscr,const mac_scan_req_stru * scan_params)1648 OAL_STATIC osal_u32 hmac_rrm_bcn_rpt_filter(hmac_vap_stru *hmac_vap, mac_bss_dscr_stru *bss_dscr,
1649 const mac_scan_req_stru *scan_params)
1650 {
1651 osal_u8 ssid_len;
1652 osal_u8 chan_idx;
1653 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
1654
1655 if (rrm_info == OSAL_NULL) {
1656 return OAL_ERR_CODE_PTR_NULL;
1657 }
1658
1659 /* 遍历信道 */
1660 for (chan_idx = 0; chan_idx < scan_params->channel_nums; chan_idx++) {
1661 if (bss_dscr->st_channel.chan_number ==
1662 scan_params->channel_list[chan_idx].chan_number) {
1663 break;
1664 }
1665 }
1666 if (scan_params->channel_nums == chan_idx) {
1667 return OAL_FAIL;
1668 }
1669
1670 /* BSSID过滤 */
1671 if (!ETHER_IS_BROADCAST(rrm_info->bcn_req_info.bssid)) {
1672 /* 请求中的bssid不是wildcard,则需要bssid匹配,不匹配时不上报 */
1673 if (osal_memcmp(rrm_info->bcn_req_info.bssid, bss_dscr->bssid, WLAN_MAC_ADDR_LEN) != 0) {
1674 return OAL_FAIL;
1675 }
1676 }
1677
1678 /* SSID过滤,若请求中ssid长度为0,则不过滤 */
1679 if (rrm_info->bcn_req_info.ssid_len != 0) {
1680 ssid_len = (osal_u8)osal_strlen(bss_dscr->ac_ssid);
1681 /* ssid不匹配的不处理 */
1682 if ((rrm_info->bcn_req_info.ssid_len != ssid_len) ||
1683 (osal_memcmp(rrm_info->bcn_req_info.ssid, bss_dscr->ac_ssid,
1684 rrm_info->bcn_req_info.ssid_len) != 0)) {
1685 return OAL_FAIL;
1686 }
1687 }
1688
1689 return OAL_SUCC;
1690 }
1691
hmac_rrm_bcn_get_vap(hmac_scan_record_stru * scan_record,mac_meas_rpt_mode_stru * rptmode)1692 OAL_STATIC hmac_vap_stru *hmac_rrm_bcn_get_vap(hmac_scan_record_stru *scan_record, mac_meas_rpt_mode_stru *rptmode)
1693 {
1694 /* 获取hmac VAP */
1695 hmac_vap_stru *hmac_vap = (hmac_vap_stru *)mac_res_get_hmac_vap(scan_record->vap_id);
1696 if ((hmac_vap == OSAL_NULL) || (hmac_11k_get_vap_rrm_info(hmac_vap) == OSAL_NULL)) {
1697 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_bcn_get_vap: hmac_vap or rrm_info is null!}");
1698 return OSAL_NULL;
1699 }
1700
1701 (osal_void)memset_s(rptmode, sizeof(mac_meas_rpt_mode_stru), 0, sizeof(mac_meas_rpt_mode_stru));
1702 /* 判断扫描状态是否成功 */
1703 if (scan_record->scan_rsp_status != MAC_SCAN_SUCCESS) {
1704 rptmode->refused = 1;
1705 hmac_rrm_encap_meas_rpt_reject(hmac_vap, rptmode);
1706 oam_warning_log2(0, OAM_SF_RRM, "vap_id[%d] hmac_rrm_bcn_get_vap::scan fail, status[%d].",
1707 hmac_vap->vap_id, scan_record->scan_rsp_status);
1708 return OSAL_NULL;
1709 }
1710 return hmac_vap;
1711 }
1712
hmac_rrm_fill_meas_sub_elm(hmac_vap_stru * hmac_vap,mac_bcn_rpt_stru * bcn_rpt_item,mac_meas_rpt_bcn_stru * meas_rpt_bcn)1713 OAL_STATIC osal_void hmac_rrm_fill_meas_sub_elm(hmac_vap_stru *hmac_vap, mac_bcn_rpt_stru *bcn_rpt_item,
1714 mac_meas_rpt_bcn_stru *meas_rpt_bcn)
1715 {
1716 /* subElement ID: Reported Frame Body(1) */
1717 mac_meas_sub_ie_stru *meas_sub_ie = (mac_meas_sub_ie_stru *)bcn_rpt_item->subelm;
1718 meas_sub_ie->sub_eid = 1;
1719 meas_sub_ie->len = (osal_u8)meas_rpt_bcn->rpt_detail_act_len;
1720
1721 unref_param(hmac_vap);
1722 if (memcpy_s(meas_sub_ie->meas_sub_data, meas_rpt_bcn->rpt_detail_act_len,
1723 meas_rpt_bcn->rpt_detail_data, meas_rpt_bcn->rpt_detail_act_len) != EOK) {
1724 oam_error_log0(0, OAM_SF_ANY, "hmac_rrm_fill_meas_sub_elm:memcopy fail !");
1725 }
1726 }
1727
hmac_rrm_fill_frame_body_fragment_id(mac_bcn_rpt_stru * bcn_rpt_item,mac_meas_rpt_bcn_stru * meas_rpt_bcn)1728 OAL_STATIC osal_void hmac_rrm_fill_frame_body_fragment_id(
1729 mac_bcn_rpt_stru *bcn_rpt_item, mac_meas_rpt_bcn_stru *meas_rpt_bcn)
1730 {
1731 /* subElement ID: Reported Frame Body Fragment ID(2) */
1732 mac_reported_frame_body_fragment_id_stru *rpt_frame_body_frag_id = NULL;
1733 rpt_frame_body_frag_id = (mac_reported_frame_body_fragment_id_stru *)(bcn_rpt_item->subelm +
1734 2 + meas_rpt_bcn->rpt_detail_act_len); /* 2: frame_body_frag offset */
1735 rpt_frame_body_frag_id->sub_eid = 2; /* subele id: 2 */
1736 rpt_frame_body_frag_id->len = 2; /* Length: 2 */
1737 rpt_frame_body_frag_id->bit_beacon_report_id = meas_rpt_bcn->bit_beacon_report_id;
1738 rpt_frame_body_frag_id->bit_fragment_id_number = meas_rpt_bcn->bit_fragment_id_number;
1739 rpt_frame_body_frag_id->bit_more_frame_body_fragments = meas_rpt_bcn->bit_more_frame_body_fragments;
1740 }
1741
hmac_rrm_get_last_bcn_rpt_indication(mac_bcn_rpt_stru * bcn_rpt_item,mac_meas_rpt_bcn_stru * meas_rpt_bcn)1742 OAL_STATIC mac_last_beacon_report_indication_stru *hmac_rrm_get_last_bcn_rpt_indication(
1743 mac_bcn_rpt_stru *bcn_rpt_item, mac_meas_rpt_bcn_stru *meas_rpt_bcn)
1744 {
1745 mac_last_beacon_report_indication_stru *last_bcn_rpt_indication = NULL;
1746 last_bcn_rpt_indication = (mac_last_beacon_report_indication_stru *)(bcn_rpt_item->subelm +
1747 6 + meas_rpt_bcn->rpt_detail_act_len); /* 6: last ast_beacon_report_indication offset */
1748 last_bcn_rpt_indication->sub_eid = 164; /* subele id: 164 */
1749 last_bcn_rpt_indication->len = 1;
1750 last_bcn_rpt_indication->last_beacon_report_indication = 0;
1751 return last_bcn_rpt_indication;
1752 }
1753
1754 /*
1755 * 函 数 名 : dmac_rrm_extract_bcn_rpt_fix_field
1756 * 功能描述 : 填充Beacon report固定长度域
1757 */
hmac_rrm_extract_bcn_rpt_fix_field(hmac_vap_stru * hmac_vap,mac_meas_rpt_bcn_item_stru * rpt_item,mac_bss_dscr_stru * dscr)1758 OAL_STATIC osal_void hmac_rrm_extract_bcn_rpt_fix_field(hmac_vap_stru *hmac_vap,
1759 mac_meas_rpt_bcn_item_stru *rpt_item, mac_bss_dscr_stru *dscr)
1760 {
1761 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
1762
1763 if (rrm_info == OSAL_NULL) {
1764 return;
1765 }
1766 /**************************************************************************/
1767 /* Beacon Report - Frame Body */
1768 /* ---------------------------------------------------------------------- */
1769 /* |oper class|chn num|Actual Meas Start Time|Meas Duration|Rpt Frm Info| */
1770 /* ---------------------------------------------------------------------- */
1771 /* |1 |1 |8 |2 | 1 | */
1772 /* ---------------------------------------------------------------------- */
1773 /* ---------------------------------------------------------------------- */
1774 /* | RCPI | RSNI | BSSID | Antenna ID | Parent TSF| Optional Subelements| */
1775 /* ---------------------------------------------------------------------- */
1776 /* |1 |1 |6 |1 |4 | Var | */
1777 /* ---------------------------------------------------------------------- */
1778 /* */
1779 /**************************************************************************/
1780
1781 /* fixed bcn rpt */
1782 rpt_item->optclass = rrm_info->bcn_req_info.opt_class;
1783 rpt_item->channum = dscr->st_channel.chan_number;
1784 (osal_void)memcpy_s(rpt_item->act_meas_start_time, sizeof(rpt_item->act_meas_start_time),
1785 rrm_info->act_meas_start_time, sizeof(rrm_info->act_meas_start_time));
1786
1787 /* Meas Duration,参考商用设备, bcn report与req duration填写一致 */
1788 rpt_item->duration = rrm_info->bcn_req_info.meas_duration;
1789
1790 rpt_item->condensed_phy_type = dscr->phy_type;
1791 rpt_item->rpt_frm_type = 0; /* Beacon/Probe rsp */
1792 rpt_item->rcpi = (osal_u8)((dscr->c_rssi + 110) * 2); /* 计算+110, *2 */
1793 rpt_item->rsni = (osal_u8)((dscr->ac_rsni[0] + dscr->ac_rsni[1]) / 2); /* 2 平均 */
1794 (osal_void)memcpy_s(rpt_item->bssid, sizeof(rpt_item->bssid), dscr->bssid, sizeof(dscr->bssid));
1795
1796 rpt_item->antenna_id = 0; // unknown
1797 rpt_item->parent_tsf = dscr->parent_tsf;
1798 return;
1799 }
1800
1801 /*
1802 * 函 数 名 : dmac_rrm_alloc_rpt_detail
1803 * 功能描述 : 申请内存填充Beacon report的frame body
1804 */
hmac_rrm_alloc_rpt_detail(const mac_vap_rrm_info_stru * rrm_info,mac_bss_dscr_stru * dscr,osal_u32 payload_len,mac_meas_rpt_bcn_stru * meas_rpt_bcn)1805 OAL_STATIC osal_u8* hmac_rrm_alloc_rpt_detail(const mac_vap_rrm_info_stru *rrm_info, mac_bss_dscr_stru *dscr,
1806 osal_u32 payload_len, mac_meas_rpt_bcn_stru *meas_rpt_bcn)
1807 {
1808 osal_u8 *rpt_detail_data = OSAL_NULL;
1809 osal_u8 *frame_body = OSAL_NULL;
1810 osal_u8 fix_len;
1811
1812 /* 填充Report Frame Body */
1813 if (rrm_info->bcn_req_info.rpt_detail == 0) {
1814 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_alloc_rpt_detail::rpt detail is 0}");
1815 return OSAL_NULL;
1816 }
1817
1818 /* 定长field拷贝 */
1819 fix_len = MAC_TIME_STAMP_LEN + MAC_BEACON_INTERVAL_LEN + MAC_CAP_INFO_LEN;
1820 if (payload_len <= fix_len) {
1821 return OSAL_NULL;
1822 }
1823
1824 /* report detail内容要放在Meas Rpt中,最长不能超过Meas rpt的长度 */
1825 rpt_detail_data = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, MAC_MAX_RPT_MBO_DETAIL_LEN, OSAL_TRUE);
1826 if (rpt_detail_data == NULL) {
1827 return OSAL_NULL;
1828 }
1829
1830 meas_rpt_bcn->rpt_detail_data = rpt_detail_data;
1831 meas_rpt_bcn->rpt_detail_act_len = fix_len;
1832 frame_body = dscr->mgmt_buff + MAC_80211_FRAME_LEN;
1833 if (memcpy_s(rpt_detail_data, MAC_MAX_RPT_MBO_DETAIL_LEN, frame_body, fix_len) != EOK) {
1834 oal_mem_free(rpt_detail_data, OSAL_TRUE);
1835 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_extract_bcn_rpt_detail::memcpy failed!}");
1836 return OSAL_NULL;
1837 }
1838 rpt_detail_data += fix_len;
1839 return rpt_detail_data;
1840 }
1841
1842 /*
1843 * 函 数 名 : hmac_rrm_extract_bcn_rpt_detail_remaining
1844 * 功能描述 : 填充Beacon report的frame body剩余部分,beacon超长了
1845 */
hmac_rrm_extract_bcn_rpt_detail_remaining(hmac_vap_stru * hmac_vap,osal_u8 * frm_body_part2,osal_u8 ** frame_body_remaining,mac_meas_rpt_bcn_stru * meas_rpt_bcn_remaining,hmac_rrm_rpt_frag_stru * rpt_frag)1846 OAL_STATIC osal_void hmac_rrm_extract_bcn_rpt_detail_remaining(hmac_vap_stru *hmac_vap,
1847 osal_u8 *frm_body_part2, osal_u8 **frame_body_remaining,
1848 mac_meas_rpt_bcn_stru *meas_rpt_bcn_remaining, hmac_rrm_rpt_frag_stru* rpt_frag)
1849 {
1850 osal_u8 *rpt_detail_data = NULL;
1851 int32_t temp_len;
1852 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
1853
1854 if (rrm_info == OSAL_NULL) {
1855 return;
1856 }
1857
1858 /* 填充Report Frame Body */
1859 if (rrm_info->bcn_req_info.rpt_detail == 0) {
1860 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_extract_bcn_rpt_detail_remaining::rpt detail is 0}");
1861 return;
1862 }
1863
1864 /* report detail内容要放在Meas Rpt中,Meas rpt的长度最长255 */
1865 rpt_detail_data = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, MAC_MAX_RPT_MBO_DETAIL_LEN, OSAL_TRUE);
1866 if (rpt_detail_data == NULL) {
1867 return;
1868 }
1869
1870 meas_rpt_bcn_remaining->rpt_detail_data = rpt_detail_data;
1871 temp_len = rpt_frag->frame_len_remaining;
1872 while (temp_len > MAC_IE_HDR_LEN) {
1873 if (meas_rpt_bcn_remaining->rpt_detail_act_len + MAC_IE_HDR_LEN + frm_body_part2[1] >
1874 MAC_MAX_RPT_MBO_DETAIL_LEN) {
1875 *frame_body_remaining = frm_body_part2;
1876 meas_rpt_bcn_remaining->bit_beacon_report_id = rpt_frag->beacon_report_id;
1877 meas_rpt_bcn_remaining->bit_fragment_id_number = rpt_frag->fragment_id_num;
1878 meas_rpt_bcn_remaining->bit_more_frame_body_fragments = 1;
1879 break;
1880 }
1881
1882 if (memcpy_s(rpt_detail_data, MAC_IE_HDR_LEN + frm_body_part2[1],
1883 frm_body_part2, MAC_IE_HDR_LEN + frm_body_part2[1]) != EOK) {
1884 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_extract_bcn_rpt_detail::memcpy failed!}");
1885 oal_mem_free(rpt_detail_data, OSAL_TRUE);
1886 meas_rpt_bcn_remaining->rpt_detail_data = NULL;
1887 break;
1888 }
1889
1890 meas_rpt_bcn_remaining->rpt_detail_act_len += MAC_IE_HDR_LEN + frm_body_part2[1];
1891 rpt_detail_data += MAC_IE_HDR_LEN + frm_body_part2[1];
1892 temp_len -= MAC_IE_HDR_LEN + frm_body_part2[1];
1893 frm_body_part2 += MAC_IE_HDR_LEN + frm_body_part2[1];
1894
1895 if ((temp_len < MAC_IE_HDR_LEN) || (temp_len < (MAC_IE_HDR_LEN + frm_body_part2[1]))) {
1896 *frame_body_remaining = NULL;
1897 meas_rpt_bcn_remaining->bit_beacon_report_id = rpt_frag->beacon_report_id;
1898 meas_rpt_bcn_remaining->bit_fragment_id_number = rpt_frag->fragment_id_num;
1899 meas_rpt_bcn_remaining->bit_more_frame_body_fragments = 0;
1900 break;
1901 }
1902 }
1903 }
1904
1905 /*
1906 * 功能描述 : 从接收的Beacon/Probe Rsp中获取Beacon Req所需信息, Active/Passive模式使用
1907 */
hmac_rrm_get_bcn_frag(hmac_vap_stru * hmac_vap,mac_bss_dscr_stru * dscr,osal_u8 * frame_body_remaining,hmac_rrm_rpt_frag_stru * rpt_frag)1908 OAL_STATIC osal_void hmac_rrm_get_bcn_frag(hmac_vap_stru *hmac_vap, mac_bss_dscr_stru *dscr,
1909 osal_u8 *frame_body_remaining, hmac_rrm_rpt_frag_stru* rpt_frag)
1910 {
1911 osal_u8 *frame_body = dscr->mgmt_buff + MAC_80211_FRAME_LEN;
1912 osal_u32 payload_len = dscr->mgmt_len - MAC_80211_FRAME_LEN;
1913 mac_meas_rpt_bcn_stru *meas_rpt_bcn_remaining = NULL;
1914 mac_meas_rpt_bcn_item_stru *meas_rpt_bcn_item_remaining = NULL;
1915 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
1916
1917 if (rrm_info == OSAL_NULL) {
1918 return;
1919 }
1920
1921 while (frame_body_remaining != NULL) {
1922 rpt_frag->fragment_id_num++;
1923 meas_rpt_bcn_remaining = (mac_meas_rpt_bcn_stru *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL,
1924 sizeof(mac_meas_rpt_bcn_stru), OSAL_TRUE);
1925 if (meas_rpt_bcn_remaining == NULL) {
1926 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_get_bcn_frag::meas_rpt_bcn_remaining NULL}");
1927 return;
1928 }
1929 memset_s(meas_rpt_bcn_remaining, sizeof(mac_meas_rpt_bcn_stru), 0, sizeof(mac_meas_rpt_bcn_stru));
1930
1931 meas_rpt_bcn_item_remaining = (mac_meas_rpt_bcn_item_stru *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL,
1932 sizeof(mac_meas_rpt_bcn_item_stru), OSAL_TRUE);
1933 if (meas_rpt_bcn_item_remaining == NULL) {
1934 oal_mem_free(meas_rpt_bcn_remaining, OSAL_TRUE);
1935 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_get_bcn_frag::meas_rpt_bcn_item_remaining NULL}");
1936 return;
1937 }
1938
1939 meas_rpt_bcn_remaining->meas_rpt_bcn_item = meas_rpt_bcn_item_remaining;
1940 memcpy_s(meas_rpt_bcn_item_remaining, sizeof(mac_meas_rpt_bcn_item_stru),
1941 rpt_frag->meas_rpt_bcn->meas_rpt_bcn_item, sizeof(mac_meas_rpt_bcn_item_stru));
1942
1943 rpt_frag->frame_len_remaining = (osal_u16)(payload_len - (frame_body_remaining - frame_body));
1944
1945 hmac_rrm_extract_bcn_rpt_detail_remaining(hmac_vap, frame_body_remaining, &frame_body_remaining,
1946 meas_rpt_bcn_remaining, rpt_frag);
1947
1948 osal_list_add_tail(&(meas_rpt_bcn_remaining->dlist_head), &(rrm_info->meas_rpt_list));
1949 }
1950 }
1951
hmac_rrm_bcn_rpt_detail_found_ie(mac_vap_rrm_info_stru * rrm_info,const osal_u8 * rx_frame)1952 OAL_STATIC osal_u8 hmac_rrm_bcn_rpt_detail_found_ie(mac_vap_rrm_info_stru *rrm_info,
1953 const osal_u8 *rx_frame)
1954 {
1955 osal_u8 found_ie = OSAL_FALSE;
1956 osal_u8 element_idx;
1957 osal_u8 *req_elements = rrm_info->bcn_req_info.reqinfo_ieid;
1958
1959 if (rrm_info->bcn_req_info.rpt_detail == 1) {
1960 for (element_idx = 0; element_idx < rrm_info->bcn_req_info.req_ie_num; element_idx++) {
1961 if ((req_elements != NULL) && (rx_frame[0] == req_elements[element_idx])) {
1962 found_ie = OSAL_TRUE;
1963 break;
1964 }
1965 }
1966 }
1967
1968 /* MBO认证 rpt detail=2时,beacon帧内容长度超过255 需要分片 */
1969 if (rrm_info->bcn_req_info.rpt_detail == 2) {
1970 found_ie = OSAL_TRUE;
1971 }
1972 return found_ie;
1973 }
1974
hmac_rrm_extract_bcn_rpt_detail(hmac_vap_stru * hmac_vap,mac_meas_rpt_bcn_stru * meas_rpt_bcn,mac_bss_dscr_stru * dscr,osal_u8 ** frm_body_part2,osal_u8 beacon_rpt_id)1975 OAL_STATIC osal_void hmac_rrm_extract_bcn_rpt_detail(hmac_vap_stru *hmac_vap,
1976 mac_meas_rpt_bcn_stru *meas_rpt_bcn, mac_bss_dscr_stru *dscr, osal_u8 **frm_body_part2, osal_u8 beacon_rpt_id)
1977 {
1978 osal_u32 payload_len = dscr->mgmt_len - MAC_80211_FRAME_LEN;
1979 osal_u8 *rx_frame = OSAL_NULL;
1980 osal_s32 tmp_len;
1981 osal_u8 fix_len;
1982 osal_u8 *rpt_detail_data = OSAL_NULL;
1983 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
1984
1985 if (rrm_info == OSAL_NULL) {
1986 return;
1987 }
1988
1989 rpt_detail_data = hmac_rrm_alloc_rpt_detail(rrm_info, dscr, payload_len, meas_rpt_bcn);
1990 if (rpt_detail_data == NULL) {
1991 return;
1992 }
1993
1994 fix_len = MAC_TIME_STAMP_LEN + MAC_BEACON_INTERVAL_LEN + MAC_CAP_INFO_LEN;
1995 rx_frame = dscr->mgmt_buff + MAC_80211_FRAME_LEN + fix_len;
1996 tmp_len = (osal_s32)(payload_len - fix_len);
1997
1998 /* 存在有多个相同IE的场景,要找全 */
1999 while (tmp_len > MAC_IE_HDR_LEN) {
2000 /* 沿着被搜索对象,依次核对是否有被搜索EID */
2001 if (hmac_rrm_bcn_rpt_detail_found_ie(rrm_info, rx_frame) == OSAL_TRUE) {
2002 if (meas_rpt_bcn->rpt_detail_act_len + MAC_IE_HDR_LEN + rx_frame[1] > MAC_MAX_RPT_MBO_DETAIL_LEN) {
2003 meas_rpt_bcn->bit_beacon_report_id = beacon_rpt_id;
2004 meas_rpt_bcn->bit_fragment_id_number = 0;
2005 meas_rpt_bcn->bit_more_frame_body_fragments = 1;
2006 *frm_body_part2 = rx_frame;
2007 break;
2008 }
2009 if (memcpy_s(rpt_detail_data, MAC_IE_HDR_LEN + rx_frame[1],
2010 rx_frame, MAC_IE_HDR_LEN + rx_frame[1]) != EOK) {
2011 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_extract_bcn_rpt_detail::memcpy failed!}");
2012 return;
2013 }
2014 rpt_detail_data += MAC_IE_HDR_LEN + rx_frame[1];
2015 meas_rpt_bcn->rpt_detail_act_len += MAC_IE_HDR_LEN + rx_frame[1];
2016 }
2017
2018 tmp_len -= rx_frame[1] + MAC_IE_HDR_LEN;
2019 rx_frame += rx_frame[1] + MAC_IE_HDR_LEN;
2020
2021 if ((tmp_len < MAC_IE_HDR_LEN) || (tmp_len < (MAC_IE_HDR_LEN + rx_frame[1]))) {
2022 meas_rpt_bcn->bit_beacon_report_id = beacon_rpt_id;
2023 meas_rpt_bcn->bit_fragment_id_number = 0;
2024 meas_rpt_bcn->bit_more_frame_body_fragments = 0;
2025 break;
2026 }
2027 }
2028 }
2029
2030 /* 功能描述:为指针*meas_rpt_bcn及(*meas_rpt_bcn)->meas_rpt_bcn_item分配内存空间,并将内存空间清零 */
hmac_rrm_alloc_mem_for_meas_rpt_bcn(mac_meas_rpt_bcn_stru ** meas_rpt_bcn)2031 OAL_STATIC osal_u32 hmac_rrm_alloc_mem_for_meas_rpt_bcn(mac_meas_rpt_bcn_stru **meas_rpt_bcn)
2032 {
2033 *meas_rpt_bcn = (mac_meas_rpt_bcn_stru *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL,
2034 sizeof(mac_meas_rpt_bcn_stru), OSAL_TRUE);
2035 if (*meas_rpt_bcn == NULL) {
2036 return OAL_FAIL;
2037 }
2038
2039 memset_s(*meas_rpt_bcn, sizeof(mac_meas_rpt_bcn_stru), 0, sizeof(mac_meas_rpt_bcn_stru));
2040
2041 (*meas_rpt_bcn)->meas_rpt_bcn_item = (mac_meas_rpt_bcn_item_stru *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL,
2042 sizeof(mac_meas_rpt_bcn_item_stru), OSAL_TRUE);
2043 if ((*meas_rpt_bcn)->meas_rpt_bcn_item == NULL) {
2044 oal_mem_free(*meas_rpt_bcn, OSAL_TRUE);
2045 return OAL_FAIL;
2046 }
2047 memset_s((*meas_rpt_bcn)->meas_rpt_bcn_item, sizeof(mac_meas_rpt_bcn_item_stru),
2048 0, sizeof(mac_meas_rpt_bcn_item_stru));
2049 return OAL_SUCC;
2050 }
2051
2052 /*
2053 * 功能描述 : 判断BSSID的信息是否已经保存在漫游链表中
2054 */
hmac_rrm_bssid_saved_in_entry(mac_vap_rrm_info_stru * rrm_info,osal_u8 * bssid,osal_u8 length)2055 OAL_STATIC osal_u8 hmac_rrm_bssid_saved_in_entry(mac_vap_rrm_info_stru *rrm_info, osal_u8 *bssid, osal_u8 length)
2056 {
2057 struct osal_list_head *meas_rpt_entry = OSAL_NULL;
2058 mac_meas_rpt_bcn_stru *meas_rpt_bcn_entry = OSAL_NULL;
2059 osal_u32 count = 0;
2060
2061 if (osal_list_empty(&(rrm_info->meas_rpt_list)) == 0) {
2062 osal_list_for_each(meas_rpt_entry, &(rrm_info->meas_rpt_list)) {
2063 count++;
2064 meas_rpt_bcn_entry = osal_list_entry(meas_rpt_entry, mac_meas_rpt_bcn_stru, dlist_head);
2065 if (meas_rpt_bcn_entry == OSAL_NULL || meas_rpt_bcn_entry->meas_rpt_bcn_item == OSAL_NULL) {
2066 oam_error_log2(0, OAM_SF_RRM, "{hmac_rrm_bssid_saved_in_entry count[%d] next is null[%d]}",
2067 count, ((rrm_info->meas_rpt_list.next == OSAL_NULL) ? 1 : 0));
2068 break;
2069 }
2070 if (memcmp(meas_rpt_bcn_entry->meas_rpt_bcn_item->bssid, bssid, length) == 0) {
2071 return OSAL_TRUE;
2072 }
2073 }
2074 }
2075 return OSAL_FALSE;
2076 }
2077
hmac_rrm_get_bcn_info_from_rx(hmac_vap_stru * hmac_vap,struct osal_list_head * bss_list_head)2078 OAL_STATIC osal_void hmac_rrm_get_bcn_info_from_rx(hmac_vap_stru *hmac_vap, struct osal_list_head *bss_list_head)
2079 {
2080 mac_ieee80211_frame_stru *frame_hdr = OSAL_NULL;
2081 osal_u8 *frm_body_remaining = OSAL_NULL;
2082 struct osal_list_head *entry = OSAL_NULL;
2083 hmac_scanned_bss_info *scanned_bss_info = OSAL_NULL;
2084 mac_bss_dscr_stru *bss_dscr = OSAL_NULL;
2085 hmac_device_stru *hmac_device = hmac_res_get_mac_dev_etc(0);
2086 mac_meas_rpt_bcn_stru *meas_rpt_bcn = OSAL_NULL;
2087 hmac_rrm_rpt_frag_stru rpt_frag = {0};
2088 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2089
2090 if (rrm_info == OSAL_NULL) {
2091 return;
2092 }
2093
2094 /*************************************************************************/
2095 /* Beacon Report - Frame Body */
2096 /* --------------------------------------------------------------------- */
2097 /* |oper class|chn num|Actual Meas Start Time|Meas Duration|Rpt Frm Info| */
2098 /* --------------------------------------------------------------------- */
2099 /* |1 |1 |8 |2 | 1 | */
2100 /* --------------------------------------------------------------------- */
2101 /* --------------------------------------------------------------------- */
2102 /* | RCPI | RSNI | BSSID | Antenna ID | Parent TSF| Optional Subelements| */
2103 /* --------------------------------------------------------------------- */
2104 /* |1 |1 |6 |1 |4 | Var | */
2105 /* --------------------------------------------------------------------- */
2106 /*************************************************************************/
2107 /* 申请一个bss 信息 数据信息 */
2108 /* 遍历扫描到的bss信息 */
2109 osal_list_for_each(entry, bss_list_head) {
2110 scanned_bss_info = osal_list_entry(entry, hmac_scanned_bss_info, dlist_head);
2111 bss_dscr = &(scanned_bss_info->bss_dscr_info);
2112 frame_hdr = (mac_ieee80211_frame_stru *)bss_dscr->mgmt_buff;
2113
2114 /* 根据bssid ssid 过滤 */
2115 if (hmac_rrm_bcn_rpt_filter(hmac_vap, bss_dscr, &(hmac_device->scan_params)) == OAL_FAIL) {
2116 continue;
2117 }
2118
2119 /* 判断该BSSID的信息是否已经保存过,若已保存过,则不再保存 更新 */
2120 if (hmac_rrm_bssid_saved_in_entry(rrm_info, frame_hdr->address3, WLAN_MAC_ADDR_LEN) == OSAL_TRUE) {
2121 continue;
2122 }
2123
2124 if (hmac_rrm_alloc_mem_for_meas_rpt_bcn(&meas_rpt_bcn) == OAL_FAIL) {
2125 continue;
2126 }
2127
2128 hmac_rrm_extract_bcn_rpt_fix_field(hmac_vap, meas_rpt_bcn->meas_rpt_bcn_item, bss_dscr);
2129 hmac_rrm_extract_bcn_rpt_detail(hmac_vap, meas_rpt_bcn, bss_dscr,
2130 &frm_body_remaining, rpt_frag.beacon_report_id);
2131
2132 oam_warning_log4(0, OAM_SF_RRM, "{FindBSS %02x:%02x:%02x:%02x:xx:xx}", frame_hdr->address3[MAC_ADDR_0],
2133 frame_hdr->address3[MAC_ADDR_1], frame_hdr->address3[MAC_ADDR_2], frame_hdr->address3[MAC_ADDR_3]);
2134 osal_list_add_tail(&(meas_rpt_bcn->dlist_head), &(rrm_info->meas_rpt_list));
2135
2136 /* 需要分片,申请内存存放超过的部分 */
2137 rpt_frag.beacon_report_id++;
2138 rpt_frag.meas_rpt_bcn = meas_rpt_bcn;
2139 hmac_rrm_get_bcn_frag(hmac_vap, bss_dscr, frm_body_remaining, &rpt_frag);
2140 }
2141 }
2142
hmac_rrm_get_bcn_info_from_save(hmac_vap_stru * hmac_vap)2143 OAL_STATIC osal_void hmac_rrm_get_bcn_info_from_save(hmac_vap_stru *hmac_vap)
2144 {
2145 mac_ieee80211_frame_stru *frame_hdr = OSAL_NULL;
2146 hmac_device_stru *hmac_device = hmac_res_get_mac_dev_etc(0);
2147 osal_u8 *frm_body_remaining = NULL;
2148 struct osal_list_head *entry = OSAL_NULL;
2149 hmac_scanned_bss_info *scanned_bss = OSAL_NULL;
2150 mac_bss_dscr_stru *dscr = OSAL_NULL;
2151 mac_meas_rpt_bcn_stru *meas_rpt_bcn = OSAL_NULL;
2152 hmac_bss_mgmt_stru *bss_mgmt = OSAL_NULL;
2153 hmac_rrm_rpt_frag_stru rpt_frag = {0};
2154 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2155
2156 if (rrm_info == OSAL_NULL) {
2157 return;
2158 }
2159
2160 /* 获取管理扫描的bss结果的结构体 */
2161 bss_mgmt = &(hmac_device->scan_mgmt.scan_record_mgmt.bss_mgmt);
2162
2163 /*************************************************************************/
2164 /* Beacon Report - Frame Body */
2165 /* --------------------------------------------------------------------- */
2166 /* |oper class|chn num|Actual Meas Start Time|Meas Duration|Rpt Frm Info| */
2167 /* --------------------------------------------------------------------- */
2168 /* |1 |1 |8 |2 | 1 | */
2169 /* --------------------------------------------------------------------- */
2170 /* --------------------------------------------------------------------- */
2171 /* | RCPI | RSNI | BSSID | Antenna ID | Parent TSF| Optional Subelements| */
2172 /* --------------------------------------------------------------------- */
2173 /* |1 |1 |6 |1 |4 | Var | */
2174 /* --------------------------------------------------------------------- */
2175 /*************************************************************************/
2176 /* 申请一个bss 信息 数据信息 */
2177 /* 对链表删操作前加锁 */
2178 osal_spin_lock(&(bss_mgmt->lock));
2179 osal_list_for_each(entry, &(bss_mgmt->bss_list_head)) {
2180 scanned_bss = osal_list_entry(entry, hmac_scanned_bss_info, dlist_head);
2181 dscr = &(scanned_bss->bss_dscr_info);
2182 frame_hdr = (mac_ieee80211_frame_stru *)dscr->mgmt_buff;
2183
2184 /* 根据bssid ssid 过滤 */
2185 if (hmac_rrm_bcn_rpt_filter(hmac_vap, dscr, &(hmac_device->scan_params)) == OAL_FAIL) {
2186 continue;
2187 }
2188
2189 /* 判断该BSSID的信息是否已经保存过,若已保存过,则不再保存 更新 */
2190 if (hmac_rrm_bssid_saved_in_entry(rrm_info, frame_hdr->address3, WLAN_MAC_ADDR_LEN) == OSAL_TRUE) {
2191 continue;
2192 }
2193
2194 if (hmac_rrm_alloc_mem_for_meas_rpt_bcn(&meas_rpt_bcn) == OAL_FAIL) {
2195 continue;
2196 }
2197
2198 hmac_rrm_extract_bcn_rpt_fix_field(hmac_vap, meas_rpt_bcn->meas_rpt_bcn_item, dscr);
2199 hmac_rrm_extract_bcn_rpt_detail(hmac_vap, meas_rpt_bcn, dscr, &frm_body_remaining, rpt_frag.beacon_report_id);
2200
2201 oam_warning_log4(0, OAM_SF_RRM, "{FindBSS %02x:%02x:%02x:%02x:xx:xx}", frame_hdr->address3[MAC_ADDR_0],
2202 frame_hdr->address3[MAC_ADDR_1], frame_hdr->address3[MAC_ADDR_2], frame_hdr->address3[MAC_ADDR_3]);
2203 osal_list_add_tail(&(meas_rpt_bcn->dlist_head), &(rrm_info->meas_rpt_list));
2204
2205 /* 需要分片,申请内存存放超过的部分 */
2206 rpt_frag.beacon_report_id++;
2207 rpt_frag.meas_rpt_bcn = meas_rpt_bcn;
2208 hmac_rrm_get_bcn_frag(hmac_vap, dscr, frm_body_remaining, &rpt_frag);
2209 }
2210 osal_spin_unlock(&(bss_mgmt->lock));
2211 }
2212
2213
hmac_rrm_fill_bcn_rpt_item(hmac_vap_stru * hmac_vap,mac_bcn_rpt_stru * bcn_rpt_item,mac_meas_rpt_bcn_stru * meas_rpt_bcn)2214 OAL_STATIC osal_void hmac_rrm_fill_bcn_rpt_item(
2215 hmac_vap_stru *hmac_vap, mac_bcn_rpt_stru *bcn_rpt_item, mac_meas_rpt_bcn_stru *meas_rpt_bcn)
2216 {
2217 mac_meas_rpt_bcn_item_stru *meas_rpt_bcn_item = meas_rpt_bcn->meas_rpt_bcn_item;
2218
2219 unref_param(hmac_vap);
2220 bcn_rpt_item->optclass = meas_rpt_bcn_item->optclass;
2221 bcn_rpt_item->channum = meas_rpt_bcn_item->channum;
2222 memcpy_s(bcn_rpt_item->act_meas_start_time, sizeof(bcn_rpt_item->act_meas_start_time),
2223 meas_rpt_bcn_item->act_meas_start_time, sizeof(meas_rpt_bcn_item->act_meas_start_time));
2224 bcn_rpt_item->duration = meas_rpt_bcn_item->duration;
2225 bcn_rpt_item->condensed_phy_type = meas_rpt_bcn_item->condensed_phy_type;
2226 bcn_rpt_item->rpt_frm_type = meas_rpt_bcn_item->rpt_frm_type;
2227 bcn_rpt_item->rcpi = meas_rpt_bcn_item->rcpi;
2228 bcn_rpt_item->rsni = meas_rpt_bcn_item->rsni;
2229 memcpy_s(bcn_rpt_item->bssid, sizeof(bcn_rpt_item->bssid),
2230 meas_rpt_bcn_item->bssid, sizeof(meas_rpt_bcn_item->bssid));
2231 bcn_rpt_item->antenna_id = meas_rpt_bcn_item->antenna_id;
2232 bcn_rpt_item->parent_tsf = meas_rpt_bcn_item->parent_tsf;
2233 }
2234
2235 /*
2236 * 功能描述 : 组装Measurement Report IE的固定域
2237 */
hmac_rrm_fill_bcn_rpt_ie(hmac_vap_stru * hmac_vap,mac_meas_rpt_bcn_stru * meas_rpt_bcn,mac_meas_rpt_ie_stru * meas_rpt_ie,mac_last_beacon_report_indication_stru ** last_bcn_rpt_indication)2238 OAL_STATIC osal_u8 hmac_rrm_fill_bcn_rpt_ie(hmac_vap_stru *hmac_vap, mac_meas_rpt_bcn_stru *meas_rpt_bcn,
2239 mac_meas_rpt_ie_stru *meas_rpt_ie, mac_last_beacon_report_indication_stru **last_bcn_rpt_indication)
2240 {
2241 mac_bcn_rpt_stru *bcn_rpt_item = (mac_bcn_rpt_stru *)(meas_rpt_ie->meas_rpt);
2242 osal_u8 curr_beacon_item_len = MAC_BEACON_RPT_FIX_LEN + (osal_u8)meas_rpt_bcn->rpt_detail_act_len;
2243 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2244
2245 if (rrm_info == OSAL_NULL) {
2246 return curr_beacon_item_len;
2247 }
2248
2249 hmac_rrm_fill_bcn_rpt_item(hmac_vap, bcn_rpt_item, meas_rpt_bcn);
2250 /* Reported Frame Body EID&Len */
2251 if ((meas_rpt_bcn->rpt_detail_act_len > 0) && (meas_rpt_bcn->rpt_detail_data != NULL)) {
2252 hmac_rrm_fill_meas_sub_elm(hmac_vap, bcn_rpt_item, meas_rpt_bcn);
2253 curr_beacon_item_len += 2; // 2: rpt detail data len
2254 if (rrm_info->bcn_req_info.rpt_frag_type != MAC_BCN_RPT_NO_FRAG) {
2255 hmac_rrm_fill_frame_body_fragment_id(bcn_rpt_item, meas_rpt_bcn);
2256 curr_beacon_item_len += 4; // 4: Reported Frame Body ie len + hdr_len
2257 }
2258 /* subElement ID: Last Beacon Report Indication(164) */
2259 if (rrm_info->bcn_req_info.rpt_frag_type == MAC_BCN_RPT_FRAG_WITH_LAST_INDICATION) {
2260 *last_bcn_rpt_indication = hmac_rrm_get_last_bcn_rpt_indication(bcn_rpt_item, meas_rpt_bcn);
2261 curr_beacon_item_len += 3; // 3: Last Beacon Report Indication ie len + hdr_len
2262 }
2263 }
2264 return curr_beacon_item_len;
2265 }
2266
hmac_rrm_set_meas_rpt_ie(mac_meas_rpt_ie_stru * meas_rpt_ie,mac_vap_rrm_info_stru * rrm_info)2267 OAL_STATIC osal_void hmac_rrm_set_meas_rpt_ie(mac_meas_rpt_ie_stru *meas_rpt_ie, mac_vap_rrm_info_stru *rrm_info)
2268 {
2269 meas_rpt_ie->eid = MAC_EID_MEASREP;
2270 meas_rpt_ie->token = rrm_info->bcn_req_info.meas_token;
2271 meas_rpt_ie->rpttype = rrm_info->bcn_req_info.meas_type;
2272 memset_s(&(meas_rpt_ie->rptmode), sizeof(mac_meas_rpt_mode_stru), 0, sizeof(mac_meas_rpt_mode_stru));
2273 meas_rpt_ie->len = MAC_ACTION_RPT_FIX_LEN;
2274 }
2275
hmac_rrm_encap_meas_rpt(hmac_vap_stru * hmac_vap)2276 OAL_STATIC osal_void hmac_rrm_encap_meas_rpt(hmac_vap_stru *hmac_vap)
2277 {
2278 osal_u8 find_bss_num = 0;
2279 osal_u8 curr_beacon_item_len;
2280 mac_last_beacon_report_indication_stru *last_bcn_rpt_indication = OSAL_NULL;
2281 struct osal_list_head *meas_rpt_node = OSAL_NULL;
2282 mac_meas_rpt_bcn_stru *meas_rpt_bcn = OSAL_NULL;
2283 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2284 mac_meas_rpt_ie_stru *meas_rpt_ie = OSAL_NULL;
2285
2286 if (rrm_info == OSAL_NULL || rrm_info->meas_rpt_ie == OSAL_NULL) {
2287 return;
2288 }
2289
2290 meas_rpt_ie = rrm_info->meas_rpt_ie;
2291 /*************************************************************************/
2292 /* Measurement Report IE - Frame Body */
2293 /* --------------------------------------------------------------------- */
2294 /* |Element ID |Length |Meas Token| Meas Rpt Mode | Meas Type | Meas Rpt| */
2295 /* --------------------------------------------------------------------- */
2296 /* |1 |1 | 1 | 1 | 1 | var */
2297 /* --------------------------------------------------------------------- */
2298 /*************************************************************************/
2299 do {
2300 hmac_rrm_set_meas_rpt_ie(meas_rpt_ie, rrm_info);
2301 rrm_info->rm_rpt_action_len += MAC_MEASUREMENT_RPT_FIX_LEN;
2302 if (osal_list_empty(&(rrm_info->meas_rpt_list)) != 0) {
2303 break;
2304 }
2305
2306 meas_rpt_node = rrm_info->meas_rpt_list.next;
2307 meas_rpt_bcn = osal_list_entry(meas_rpt_node, mac_meas_rpt_bcn_stru, dlist_head);
2308 if (meas_rpt_bcn == OSAL_NULL || meas_rpt_bcn->meas_rpt_bcn_item == OSAL_NULL) {
2309 oam_warning_log0(0, OAM_SF_RRM, "hmac_rrm_encap_meas_rpt::no item or invalid meas_rpt_node");
2310 break;
2311 }
2312
2313 curr_beacon_item_len = (osal_u8)(MAC_BEACON_RPT_FIX_LEN + meas_rpt_bcn->rpt_detail_act_len);
2314 /* netbuf 长度不足,继续遍历bss链表并删除表项 */
2315 if (rrm_info->rm_rpt_action_len + curr_beacon_item_len > WLAN_LARGE_NETBUF_SIZE) {
2316 osal_dlist_delete_entry(meas_rpt_node);
2317 hmac_rrm_beacon_measure_free_one_rpt_bcn_item(meas_rpt_bcn);
2318 rrm_info->rm_rpt_action_len -= MAC_MEASUREMENT_RPT_FIX_LEN;
2319 continue;
2320 }
2321
2322 curr_beacon_item_len = hmac_rrm_fill_bcn_rpt_ie(hmac_vap, meas_rpt_bcn, meas_rpt_ie, &last_bcn_rpt_indication);
2323 meas_rpt_ie->len += curr_beacon_item_len;
2324 rrm_info->rm_rpt_action_len += curr_beacon_item_len;
2325
2326 /* 下一个Measurement Report的位置 */
2327 osal_dlist_delete_entry(meas_rpt_node);
2328 /* 最后一个片段 last beacon indication置1 */
2329 if (osal_list_empty(&(rrm_info->meas_rpt_list)) != 0) {
2330 if (last_bcn_rpt_indication != OSAL_NULL) {
2331 last_bcn_rpt_indication->last_beacon_report_indication = 1;
2332 }
2333 }
2334 hmac_rrm_beacon_measure_free_one_rpt_bcn_item(meas_rpt_bcn);
2335 meas_rpt_ie = (mac_meas_rpt_ie_stru *)((osal_u8 *)meas_rpt_ie + meas_rpt_ie->len + MAC_IE_HDR_LEN);
2336 find_bss_num++;
2337 } while (osal_list_empty(&(rrm_info->meas_rpt_list)) == 0);
2338
2339 oam_warning_log2(0, OAM_SF_RRM, "{hmac_rrm_encap_meas_rpt::bcn_req_info.uc_meas=[%d],Encap BSS_Num = [%d].",
2340 rrm_info->bcn_req_info.meas_token, find_bss_num);
2341 hmac_rrm_free_ssid_and_reqinfo_ieid_item(rrm_info);
2342 }
2343
2344 /*
2345 * 功能描述 : 11k Beacon report 组帧回复
2346 */
hmac_rrm_encap_beacon_rpt(hmac_vap_stru * hmac_vap)2347 OAL_STATIC osal_void hmac_rrm_encap_beacon_rpt(hmac_vap_stru *hmac_vap)
2348 {
2349 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2350
2351 if (rrm_info == OSAL_NULL) {
2352 return;
2353 }
2354
2355 rrm_info->meas_rpt_ie = (mac_meas_rpt_ie_stru *)rrm_info->rm_rpt_action->rpt_ies;
2356
2357 hmac_rrm_encap_meas_rpt(hmac_vap);
2358
2359 /* 发帧 */
2360 hmac_rrm_send_rm_rpt_action(hmac_vap);
2361 }
2362
2363 /*
2364 * 函 数 名 : hmac_rrm_encap_and_send_bcn_rpt
2365 * 功能描述 : 组Beacon report rsp Action帧,可能由多个Action帧共同完成信息传递
2366 */
hmac_rrm_encap_bcn_rpt(hmac_vap_stru * hmac_vap)2367 OAL_STATIC osal_void hmac_rrm_encap_bcn_rpt(hmac_vap_stru *hmac_vap)
2368 {
2369 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2370
2371 if (rrm_info == OSAL_NULL) {
2372 return;
2373 }
2374
2375 do {
2376 hmac_rrm_encap_beacon_rpt(hmac_vap);
2377 } while (osal_list_empty(&(rrm_info->meas_rpt_list)) == 0);
2378 }
2379
2380 /*****************************************************************************
2381 功能描述 : bcn扫描回调函数
2382 *****************************************************************************/
hmac_rrm_bcn_scan_cb(void * scan_record_ptr)2383 OAL_STATIC osal_void hmac_rrm_bcn_scan_cb(void *scan_record_ptr)
2384 {
2385 hmac_scan_record_stru *scan_record;
2386 hmac_bss_mgmt_stru *bss_mgmt;
2387 osal_u32 ret;
2388 hmac_vap_stru *hmac_vap = OSAL_NULL;
2389 mac_meas_rpt_mode_stru rptmode;
2390 mac_vap_rrm_info_stru *rrm_info = OSAL_NULL;
2391
2392 /* 判断入参合法性 */
2393 if (scan_record_ptr == OSAL_NULL) {
2394 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_bcn_scan_cb: input pointer is null!}");
2395 return;
2396 }
2397
2398 scan_record = (hmac_scan_record_stru *)scan_record_ptr;
2399
2400 /* 获取hmac VAP及判断扫描状态是否成功 */
2401 hmac_vap = hmac_rrm_bcn_get_vap(scan_record, &rptmode);
2402 if (hmac_vap == OSAL_NULL) {
2403 return;
2404 }
2405
2406 if (hmac_vap_id_param_check(hmac_vap->vap_id) != OSAL_TRUE) {
2407 return;
2408 }
2409
2410 rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2411 if (rrm_info == OSAL_NULL) {
2412 return;
2413 }
2414
2415 /* 获取扫描结果的管理结构地址 */
2416 bss_mgmt = &(scan_record->bss_mgmt);
2417
2418 /* 获取锁 */
2419 osal_spin_lock(&(bss_mgmt->lock));
2420
2421 /* 遍历扫描到的bss信息 */
2422 hmac_rrm_get_bcn_info_from_rx(hmac_vap, &(bss_mgmt->bss_list_head));
2423
2424 /* 解除锁 */
2425 osal_spin_unlock(&(bss_mgmt->lock));
2426
2427 if (osal_list_empty(&(rrm_info->meas_rpt_list)) != 0) {
2428 rptmode.refused = 1;
2429 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
2430 oam_warning_log2(0, OAM_SF_RRM, "vap_id[%d] hmac_rrm_bcn_scan_cb::scan fail, status[%d].",
2431 hmac_vap->vap_id, scan_record->scan_rsp_status);
2432 return;
2433 }
2434
2435 /* 申请RPT管理帧内存 */
2436 ret = hmac_rrm_fill_basic_rm_rpt_action(hmac_vap);
2437 if (ret != OAL_SUCC) {
2438 reset_rrm_info(rrm_info);
2439 rptmode.refused = 1;
2440 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
2441 oam_error_log1(0, OAM_SF_RRM, "{hmac_rrm_bcn_scan_cb: hmac_rrm_fill_basic_rm_rpt_action ret[%d].}", ret);
2442 return;
2443 }
2444
2445 hmac_rrm_encap_bcn_rpt(hmac_vap);
2446 return;
2447 }
2448
2449 /*****************************************************************************
2450 函 数 名 : hmac_rrm_bcn_means_mode_table
2451 功能描述 : table mode测量结果上报
2452 *****************************************************************************/
hmac_rrm_bcn_means_mode_table(hmac_vap_stru * hmac_vap)2453 OAL_STATIC osal_void hmac_rrm_bcn_means_mode_table(hmac_vap_stru *hmac_vap)
2454 {
2455 mac_meas_rpt_mode_stru rptmode;
2456 osal_u32 ret;
2457 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2458
2459 if (rrm_info == OSAL_NULL) {
2460 return;
2461 }
2462
2463 (osal_void)memset_s(&rptmode, sizeof(mac_meas_rpt_mode_stru), 0, sizeof(mac_meas_rpt_mode_stru));
2464 hmac_rrm_get_bcn_info_from_save(hmac_vap);
2465
2466 if (osal_list_empty(&(rrm_info->meas_rpt_list)) != 0) {
2467 rptmode.refused = 1;
2468 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
2469 oam_warning_log1(0, OAM_SF_RRM, "vap_id[%d] hmac_rrm_bcn_means_mode_table::scan fail.", hmac_vap->vap_id);
2470 return;
2471 }
2472
2473 /* 申请RPT管理帧内存 */
2474 oam_warning_log0(0, OAM_SF_RRM, "vap_id[%d] hmac_rrm_bcn_means_mode_table::hmac_rrm_fill_basic_rm_rpt_action.");
2475 ret = hmac_rrm_fill_basic_rm_rpt_action(hmac_vap);
2476 if (ret != OAL_SUCC) {
2477 reset_rrm_info(rrm_info);
2478 rptmode.refused = 1;
2479 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
2480 oam_error_log1(0, OAM_SF_RRM,
2481 "{hmac_rrm_bcn_means_mode_table::hmac_rrm_fill_basic_rm_rpt_action ret[%d].}", ret);
2482 return;
2483 }
2484
2485 hmac_rrm_encap_bcn_rpt(hmac_vap);
2486 }
2487
hmac_fill_scan_req_param(hmac_vap_stru * hmac_vap,mac_bcn_req_stru * bcn_req,mac_scan_req_stru * scan_req)2488 OAL_STATIC osal_void hmac_fill_scan_req_param(hmac_vap_stru *hmac_vap, mac_bcn_req_stru *bcn_req,
2489 mac_scan_req_stru *scan_req)
2490 {
2491 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2492
2493 if (rrm_info == OSAL_NULL) {
2494 return;
2495 }
2496
2497 scan_req->bss_type = WLAN_MIB_DESIRED_BSSTYPE_INFRA;
2498 scan_req->scan_mode = WLAN_SCAN_MODE_BACKGROUND_STA;
2499
2500 /* BSSID*过滤 */
2501 oal_set_mac_addr(scan_req->bssid[0], bcn_req->bssid);
2502 scan_req->bssid_num = 1;
2503 scan_req->vap_id = hmac_vap->vap_id;
2504 scan_req->scan_func = MAC_SCAN_FUNC_BSS;
2505 scan_req->max_scan_count_per_channel = 1;
2506 scan_req->max_send_probe_req_count_per_channel = WLAN_DEFAULT_SEND_PROBE_REQ_COUNT_PER_CHANNEL;
2507 scan_req->need_switch_back_home_channel = OAL_TRUE;
2508 scan_req->work_time_on_home_channel = MAC_WORK_TIME_ON_HOME_CHANNEL_DEFAULT;
2509 oal_set_mac_addr(scan_req->sour_mac_addr, mac_mib_get_station_id(hmac_vap));
2510 /* SSID过滤 */
2511 if (rrm_info->bcn_req_info.ssid != OAL_PTR_NULL) {
2512 if (memcpy_s(scan_req->mac_ssid_set[0].ssid, rrm_info->bcn_req_info.ssid_len,
2513 rrm_info->bcn_req_info.ssid, rrm_info->bcn_req_info.ssid_len) != EOK) {
2514 oam_warning_log0(0, OAM_SF_CFG, "{hmac_fill_scan_req_param data::memcpy err.}");
2515 }
2516 }
2517
2518 /* 回调函数指针 */
2519 scan_req->fn_cb = hmac_rrm_bcn_scan_cb;
2520 }
2521
2522 /*****************************************************************************
2523 函 数 名 : hmac_rrm_bcn_scan_do
2524 功能描述 : bcn扫描请求
2525 输入参数 : void *p_scan_record
2526 输出参数 : 无
2527 返 回 值 : 无
2528 *****************************************************************************/
hmac_rrm_bcn_scan_do(hmac_vap_stru * hmac_vap,mac_bcn_req_stru * bcn_req,mac_scan_req_stru * scan_req)2529 OAL_STATIC osal_u32 hmac_rrm_bcn_scan_do(hmac_vap_stru *hmac_vap, mac_bcn_req_stru *bcn_req,
2530 mac_scan_req_stru *scan_req)
2531 {
2532 osal_u32 ret;
2533 errno_t ret_memcpy;
2534 mac_meas_rpt_mode_stru rptmode;
2535 hmac_device_stru *hmac_device = OSAL_NULL;
2536 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2537 osal_void *fhook = OSAL_NULL;
2538
2539 if (rrm_info == OSAL_NULL) {
2540 return OAL_FAIL;
2541 }
2542
2543 hmac_fill_scan_req_param(hmac_vap, bcn_req, scan_req);
2544 fhook = hmac_get_feature_fhook(HMAC_FHOOK_MBO_STA_UPDATE_RRM_SCAN_PARAM);
2545 if (fhook != OSAL_NULL) {
2546 ((hmac_vap_mbo_update_rrm_scan_params_cb)fhook)(bcn_req, scan_req);
2547 }
2548
2549 /* 保存扫描参数,防止扫描参数被释放 */
2550 hmac_device = hmac_res_get_mac_dev_etc(hmac_vap->device_id);
2551 if (osal_unlikely(hmac_device == OAL_PTR_NULL)) {
2552 return OAL_ERR_CODE_PTR_NULL;
2553 }
2554 ret_memcpy = memcpy_s((mac_scan_req_stru *)&(hmac_device->scan_params), sizeof(mac_scan_req_stru),
2555 (mac_scan_req_stru *)scan_req, sizeof(mac_scan_req_stru));
2556 if (ret_memcpy != EOK) {
2557 oam_error_log1(0, OAM_SF_RRM, "{hmac_rrm_bcn_scan_do: memcpy error = [%d]}", ret_memcpy);
2558 return OAL_FAIL;
2559 }
2560
2561 /* 直接调用扫描模块扫描请求处理函数 */
2562 ret = hmac_scan_proc_scan_req_event_etc(hmac_vap, scan_req);
2563 if (ret != OAL_SUCC) {
2564 oam_warning_log1(0, OAM_SF_RRM, "hmac_rrm_bcn_scan_do:hmac_scan_add_req failed, ret=%d", ret);
2565 /* 扫描失败回复refuse bit */
2566 memset_s(&rptmode, OAL_SIZEOF(mac_meas_rpt_mode_stru), 0, OAL_SIZEOF(mac_meas_rpt_mode_stru));
2567 rptmode.refused = 1;
2568 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
2569 } else {
2570 rrm_info->is_measuring = OAL_TRUE;
2571 rrm_info->meas_status_timer.timeout = MAC_RRM_VAP_MEAS_STAUTS_TIME;
2572 frw_create_timer_entry(&(rrm_info->meas_status_timer), hmac_vap_meas_status_timeout,
2573 rrm_info->meas_status_timer.timeout, (osal_void *)rrm_info, OAL_FALSE);
2574 }
2575
2576 return ret;
2577 }
2578
hmac_rrm_bcn_encap_meas_rpt_reject(hmac_vap_stru * hmac_vap,const mac_bcn_req_stru * bcn_req)2579 OAL_STATIC osal_u32 hmac_rrm_bcn_encap_meas_rpt_reject(hmac_vap_stru *hmac_vap, const mac_bcn_req_stru *bcn_req)
2580 {
2581 mac_meas_rpt_mode_stru rptmode;
2582
2583 /* 根据模式进行测量 */
2584 memset_s(&rptmode, OAL_SIZEOF(mac_meas_rpt_mode_stru), 0, OAL_SIZEOF(mac_meas_rpt_mode_stru));
2585 switch (bcn_req->mode) {
2586 /* Passive:触发扫描,不发probe req,测量收到的Beacon和probe rsp */
2587 case RM_BCN_REQ_MEAS_MODE_PASSIVE:
2588 if (mac_mib_get_dot11RMBeaconPassiveMeasurementActivated(hmac_vap) == OAL_FALSE) {
2589 oam_warning_log1(0, OAM_SF_RRM, "vap_id[%d] passive measurement mode not enable",
2590 hmac_vap->vap_id);
2591 rptmode.incapable = 1;
2592 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
2593 return OAL_FAIL;
2594 }
2595 break;
2596
2597 /* Active:触发扫描,发probe req,测量收到的Beacon和probe rsp */
2598 case RM_BCN_REQ_MEAS_MODE_ACTIVE:
2599 if (mac_mib_get_dot11RMBeaconActiveMeasurementActivated(hmac_vap) == OAL_FALSE) {
2600 oam_warning_log1(0, OAM_SF_RRM, "vap_id[%d] active measurement mode not enable",
2601 hmac_vap->vap_id);
2602 rptmode.incapable = 1;
2603 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
2604 return OAL_FAIL;
2605 }
2606 break;
2607
2608 /* Table:上报保存的扫描结果 */
2609 case RM_BCN_REQ_MEAS_MODE_TABLE:
2610 if ((hmac_11k_get_vap_info(hmac_vap)->bcn_table_switch == OAL_FALSE) ||
2611 (mac_mib_get_dot11RMBeaconTableMeasurementActivated(hmac_vap) == OAL_FALSE)) {
2612 rptmode.incapable = 1;
2613 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
2614 oam_warning_log1(0, OAM_SF_RRM, "vap_id[%d] hmac_rrm_meas_bcn:table mode is shutdown!",
2615 hmac_vap->vap_id);
2616 return OAL_FAIL;
2617 }
2618 break;
2619
2620 default:
2621 oam_warning_log1(0, OAM_SF_RRM, "vap_id[%d] unkown measurement mode.",
2622 hmac_vap->vap_id);
2623 rptmode.refused = 1;
2624 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
2625 return OAL_FAIL;
2626 }
2627 return OAL_SUCC;
2628 }
2629
2630 /*****************************************************************************
2631 根据不同测量模式,准备扫描参数并启动扫描
2632 *****************************************************************************/
hmac_rrm_meas_bcn(hmac_vap_stru * hmac_vap,mac_bcn_req_stru * bcn_req,mac_scan_req_stru * scan_req)2633 OAL_STATIC osal_u32 hmac_rrm_meas_bcn(hmac_vap_stru *hmac_vap, mac_bcn_req_stru *bcn_req,
2634 mac_scan_req_stru *scan_req)
2635 {
2636 /* 根据模式进行测量 */
2637 if (hmac_rrm_bcn_encap_meas_rpt_reject(hmac_vap, bcn_req) == OAL_FAIL) {
2638 return OAL_FAIL;
2639 }
2640
2641 switch (bcn_req->mode) {
2642 /* Passive:触发扫描,不发probe req,测量收到的Beacon和probe rsp */
2643 case RM_BCN_REQ_MEAS_MODE_PASSIVE:
2644 scan_req->scan_type = WLAN_SCAN_TYPE_PASSIVE;
2645 /* 测量时间, 需要足够长的时间以保证可以收到指定beacon */
2646 scan_req->scan_time = MAC_RRM_BCN_REQ_PASSIVE_SCAN_TIME; // WLAN_DEFAULT_PASSIVE_SCAN_TIME;
2647 hmac_rrm_bcn_scan_do(hmac_vap, bcn_req, scan_req);
2648 break;
2649
2650 /* Active:触发扫描,发probe req,测量收到的Beacon和probe rsp */
2651 case RM_BCN_REQ_MEAS_MODE_ACTIVE:
2652 scan_req->scan_type = WLAN_SCAN_TYPE_ACTIVE;
2653 /* 测量时间 */
2654 scan_req->scan_time = WLAN_DEFAULT_ACTIVE_SCAN_TIME;
2655
2656 hmac_rrm_bcn_scan_do(hmac_vap, bcn_req, scan_req);
2657 break;
2658
2659 /* Table:上报保存的扫描结果 */
2660 case RM_BCN_REQ_MEAS_MODE_TABLE:
2661 hmac_rrm_bcn_means_mode_table(hmac_vap);
2662 break;
2663
2664 default:
2665 break;
2666 }
2667 return OAL_SUCC;
2668 }
2669
hmac_rrm_get_bcn_ap_rpt_channels(mac_ap_chn_rpt_stru ** ap_chn_rpt,osal_u8 ap_chn_rpt_num,mac_scan_req_stru * scan_req,osal_u8 chan_count)2670 OAL_STATIC osal_void hmac_rrm_get_bcn_ap_rpt_channels(mac_ap_chn_rpt_stru **ap_chn_rpt, osal_u8 ap_chn_rpt_num,
2671 mac_scan_req_stru *scan_req, osal_u8 chan_count)
2672 {
2673 osal_u8 chan_idx;
2674 osal_u8 chan_num;
2675 osal_u8 chan_avail_idx = 0;
2676 osal_u8 ap_chan_rpt_count;
2677 osal_u8 ap_chan_num;
2678 osal_u8 ap_chan_idx = 0;
2679 wlan_channel_band_enum_uint8 chan_band;
2680
2681 for (ap_chan_rpt_count = 0; ap_chan_rpt_count < ap_chn_rpt_num; ap_chan_rpt_count++) {
2682 /* 请求的信道个数,根据长度计算 */
2683 ap_chan_num = ap_chn_rpt[ap_chan_rpt_count]->length - 1;
2684
2685 for (chan_idx = 0; chan_idx < ap_chan_num; chan_idx++) {
2686 chan_num = *(&(ap_chn_rpt[ap_chan_rpt_count]->chan[0]) + chan_idx);
2687 chan_band = mac_get_band_by_channel_num(chan_num);
2688 if (hmac_get_channel_idx_from_num_etc(chan_band, chan_num, &ap_chan_idx) != OAL_SUCC) {
2689 continue;
2690 }
2691
2692 /* 检查信道号是否有效 */
2693 if (hmac_is_channel_idx_valid_etc(chan_band, ap_chan_idx) != OAL_SUCC) {
2694 continue;
2695 }
2696 scan_req->channel_list[chan_avail_idx].chan_number = chan_num;
2697 scan_req->channel_list[chan_avail_idx].band = chan_band;
2698 scan_req->channel_list[chan_avail_idx].chan_idx = ap_chan_idx;
2699 chan_avail_idx++;
2700
2701 /* AP chan rpt信道个数不超出管制域扫描信道个数 */
2702 if (chan_count == chan_avail_idx) {
2703 break;
2704 }
2705 }
2706
2707 if (chan_count == chan_avail_idx) {
2708 break;
2709 }
2710 }
2711 scan_req->channel_nums = chan_avail_idx;
2712 }
2713
2714
2715 /*****************************************************************************
2716 函 数 名 : hmac_rrm_get_bcn_rpt_channels
2717 功能描述 : 根据channel number及operating class计算所需测量的信道
2718 输入参数 : hmac_vap : dmac vap结构体指针
2719 ppst_ap_chn_rpt : 指向AP Channel Report的指针数组
2720 ap_chn_rpt_num : AP Channel Report个数
2721 scan_req : 扫描信息结构体指针
2722 *****************************************************************************/
hmac_rrm_get_bcn_rpt_channels(mac_bcn_req_stru * bcn_req,mac_ap_chn_rpt_stru ** ppst_ap_chn_rpt,osal_u8 ap_chn_rpt_num,mac_scan_req_stru * scan_req,wlan_channel_band_enum_uint8 chan_band)2723 OAL_STATIC osal_u32 hmac_rrm_get_bcn_rpt_channels(mac_bcn_req_stru *bcn_req, mac_ap_chn_rpt_stru **ppst_ap_chn_rpt,
2724 osal_u8 ap_chn_rpt_num, mac_scan_req_stru *scan_req, wlan_channel_band_enum_uint8 chan_band)
2725 {
2726 osal_u8 chan_idx, chan_count;
2727 osal_u8 chan_num = 0;
2728 osal_u8 chan_avail_idx = 0;
2729 osal_u8 ap_chan_idx = 0;
2730 osal_u32 ul_ret;
2731 osal_void *fhook = OSAL_NULL;
2732 wlan_channel_band_enum_uint8 band = chan_band;
2733
2734 /* 对应指定用例进行打桩 */
2735 chan_count = (band == WLAN_BAND_2G) ? (osal_u8)MAC_CHANNEL_FREQ_2_BUTT : (osal_u8)MAC_CHANNEL_FREQ_5_BUTT;
2736
2737 fhook = hmac_get_feature_fhook(HMAC_FHOOK_MBO_STA_MODIFY_CHAN_PARAM);
2738 if (fhook != OSAL_NULL) {
2739 ((hmac_mbo_modify_chan_param_cb)fhook)(bcn_req->optclass, &band, &chan_count);
2740 }
2741
2742 /* 当前operating class下的所有chan,先不处理regclass,使用2.4G信道总集 */
2743 if (bcn_req->channum == 0) {
2744 /* 根据channel_bitmap解析出对应的信道号集合 */
2745 for (chan_idx = 0; chan_idx < chan_count; chan_idx++) {
2746 /* 判断信道是不是在管制域内 */
2747 if (hmac_is_channel_idx_valid_etc(band, chan_idx) == OAL_SUCC) {
2748 hmac_get_channel_num_from_idx_etc(band, chan_idx, &chan_num);
2749 scan_req->channel_list[chan_avail_idx].chan_number = chan_num;
2750 scan_req->channel_list[chan_avail_idx].band = band;
2751 scan_req->channel_list[chan_avail_idx++].chan_idx = chan_idx;
2752 }
2753 }
2754 scan_req->channel_nums = chan_avail_idx;
2755 } else if (bcn_req->channum == 255) { /* 255 */
2756 /* 当前operating class与AP chan rpt的交集 */
2757 if (ap_chn_rpt_num == 0) {
2758 oam_warning_log0(0, OAM_SF_RRM, "hmac_rrm_get_bcn_rpt_channels: channum is 255,but NO ap_chan_rpt ie");
2759 return OAL_FAIL;
2760 }
2761 hmac_rrm_get_bcn_ap_rpt_channels(ppst_ap_chn_rpt, ap_chn_rpt_num, scan_req, chan_count);
2762 } else {
2763 /* 当前chan num */
2764 chan_num = bcn_req->channum;
2765 scan_req->channel_nums = 1;
2766 band = mac_get_band_by_channel_num(chan_num);
2767 ul_ret = hmac_get_channel_idx_from_num_etc(band, chan_num, &ap_chan_idx);
2768 if (ul_ret != OAL_SUCC) {
2769 oam_warning_log1(0, OAM_SF_RRM,
2770 "hmac_rrm_get_bcn_rpt_channels: hmac_get_channel_idx_from_num_etc fail,error_code=%d", ul_ret);
2771 return ul_ret;
2772 }
2773 /* 临时调试,需要更新管制类表格 */
2774 scan_req->channel_list[0].chan_number = chan_num;
2775 scan_req->channel_list[0].chan_idx = ap_chan_idx;
2776 scan_req->channel_list[0].band = band;
2777 }
2778
2779 return OAL_SUCC;
2780 }
2781
hmac_rrm_parse_beacon_ap_chn(hmac_vap_stru * hmac_vap,mac_bcn_req_stru * bcn_req,osal_u8 c_bcn_req_sub_len,mac_scan_req_stru * scan_req,mac_meas_rpt_mode_stru rptmode)2782 OAL_STATIC osal_u32 hmac_rrm_parse_beacon_ap_chn(hmac_vap_stru *hmac_vap,
2783 mac_bcn_req_stru *bcn_req, osal_u8 c_bcn_req_sub_len, mac_scan_req_stru *scan_req, mac_meas_rpt_mode_stru rptmode)
2784 {
2785 osal_u8 *chn_rpt_search_addr = bcn_req->subelm;
2786 osal_u8 chn_rpt_search_len;
2787 mac_ap_chn_rpt_stru *apst_ap_chn_rpt[MAC_11K_SUPPORT_AP_CHAN_RPT_NUM];
2788 osal_u8 ap_chn_rpt_count = 0;
2789 osal_u32 ret;
2790
2791 chn_rpt_search_len = c_bcn_req_sub_len;
2792 do {
2793 apst_ap_chn_rpt[ap_chn_rpt_count] = (mac_ap_chn_rpt_stru *)mac_find_ie_etc(MAC_EID_AP_CHAN_REPORT,
2794 chn_rpt_search_addr, chn_rpt_search_len);
2795 if (apst_ap_chn_rpt[ap_chn_rpt_count] == OAL_PTR_NULL) {
2796 break;
2797 }
2798 chn_rpt_search_addr = (osal_u8 *)apst_ap_chn_rpt[ap_chn_rpt_count] + 2 + /* 2 偏移 */
2799 apst_ap_chn_rpt[ap_chn_rpt_count]->length;
2800 chn_rpt_search_len = (osal_u8)(c_bcn_req_sub_len -
2801 (osal_u8)((osal_u8 *)apst_ap_chn_rpt[ap_chn_rpt_count] - bcn_req->subelm) -
2802 (2 + apst_ap_chn_rpt[ap_chn_rpt_count]->length)); /* 2 偏移 */
2803 ap_chn_rpt_count++;
2804 if (ap_chn_rpt_count == MAC_11K_SUPPORT_AP_CHAN_RPT_NUM) {
2805 oam_warning_log1(0, OAM_SF_RRM, "vap_id[%d] ap chan rpt num is larger than 8, truncate the later ones",
2806 hmac_vap->vap_id);
2807 break;
2808 }
2809 } while (chn_rpt_search_len > 0);
2810
2811 ret = hmac_rrm_get_bcn_rpt_channels(bcn_req, apst_ap_chn_rpt, ap_chn_rpt_count, scan_req,
2812 hmac_vap->channel.band);
2813 if (ret != OAL_SUCC) {
2814 rptmode.refused = 1;
2815 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
2816 return OAL_FAIL;
2817 }
2818 return OAL_SUCC;
2819 }
2820
hmac_rrm_parse_beacon_rpt_info(hmac_vap_stru * hmac_vap,osal_u8 * rpt_info_search_addr,osal_u8 c_bcn_req_sub_len,mac_meas_rpt_mode_stru rptmode)2821 OAL_STATIC osal_u32 hmac_rrm_parse_beacon_rpt_info(hmac_vap_stru *hmac_vap, osal_u8 *rpt_info_search_addr,
2822 osal_u8 c_bcn_req_sub_len, mac_meas_rpt_mode_stru rptmode)
2823 {
2824 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2825 osal_u8 *rpt_info_sub_element = OSAL_NULL;
2826
2827 if (rrm_info == OSAL_NULL) {
2828 return OAL_ERR_CODE_PTR_NULL;
2829 }
2830
2831 rpt_info_sub_element = mac_find_ie_etc(1, rpt_info_search_addr, c_bcn_req_sub_len);
2832 if (rpt_info_sub_element != OAL_PTR_NULL) {
2833 rrm_info->bcn_req_info.rpt_condition = *(rpt_info_sub_element + 2); /* 2 偏移 */
2834 rrm_info->bcn_req_info.rpt_ref_val = *(rpt_info_sub_element + 3); /* 3 偏移 */
2835 oam_warning_log3(0, OAM_SF_RRM,
2836 "vap_id[%d] hmac_rrm_parse_beacon_req::frame_body::rpt_condition[%d],rpt_ref_val[%d].",
2837 hmac_vap->vap_id, rrm_info->bcn_req_info.rpt_condition,
2838 rrm_info->bcn_req_info.rpt_ref_val);
2839 /* Repeat模式下使能Report Condition */
2840 if (rrm_info->bcn_req_info.rpt_condition != 0) {
2841 oam_warning_log1(0, OAM_SF_RRM, "vap_id[%d] BeaconMeasurementReportingConditions not enable",
2842 hmac_vap->vap_id);
2843 rptmode.incapable = 1;
2844 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
2845 return OAL_FAIL;
2846 }
2847 }
2848 return OAL_SUCC;
2849 }
2850
2851
hmac_rrm_parse_beacon_ssid(hmac_vap_stru * hmac_vap,osal_u8 * ssid_search_addr,osal_u8 c_bcn_req_sub_len)2852 OAL_STATIC osal_u32 hmac_rrm_parse_beacon_ssid(hmac_vap_stru *hmac_vap, osal_u8 *ssid_search_addr,
2853 osal_u8 c_bcn_req_sub_len)
2854 {
2855 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2856 osal_u8 *ssid_sub_element = OSAL_NULL;
2857
2858 if (rrm_info == OSAL_NULL) {
2859 return OAL_ERR_CODE_PTR_NULL;
2860 }
2861
2862 ssid_sub_element = mac_find_ie_etc(MAC_EID_SSID, ssid_search_addr, c_bcn_req_sub_len);
2863 if (ssid_sub_element != OAL_PTR_NULL) {
2864 /* check ssid len */
2865 if (ssid_sub_element[1] >= WLAN_SSID_MAX_LEN || ssid_sub_element[1] == 0) {
2866 oam_error_log1(0, OAM_SF_RRM, "hmac_rrm_parse_beacon_ssid::ssid_len[%d] invalid", ssid_sub_element[1]);
2867 return OAL_FAIL;
2868 }
2869 rrm_info->bcn_req_info.ssid_len = *(ssid_sub_element + 1);
2870 rrm_info->bcn_req_info.ssid = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, rrm_info->bcn_req_info.ssid_len, OAL_TRUE);
2871 if (rrm_info->bcn_req_info.ssid == OAL_PTR_NULL) {
2872 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_parse_beacon_ssid::memalloc ssid fail}");
2873 return OAL_FAIL;
2874 }
2875 if (memcpy_s(rrm_info->bcn_req_info.ssid, rrm_info->bcn_req_info.ssid_len,
2876 (ssid_sub_element + 2), rrm_info->bcn_req_info.ssid_len) != EOK) { /* 偏移2 */
2877 oam_warning_log0(0, OAM_SF_CFG, "{hmac_rrm_parse_beacon_ssid ::memcpy err.}");
2878 }
2879 }
2880 return OAL_SUCC;
2881 }
2882
hmac_rrm_parse_beacon_report(hmac_vap_stru * hmac_vap,osal_u8 * detail_search_addr,osal_u8 c_bcn_req_sub_len)2883 OAL_STATIC osal_void hmac_rrm_parse_beacon_report(hmac_vap_stru *hmac_vap, osal_u8 *detail_search_addr,
2884 osal_u8 c_bcn_req_sub_len)
2885 {
2886 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2887 osal_u8 *reporting_detail = OSAL_NULL;
2888 osal_u8 *last_ban_rpt = OSAL_NULL;
2889
2890 if (rrm_info == OSAL_NULL) {
2891 return;
2892 }
2893
2894 reporting_detail = mac_find_ie_etc(2, detail_search_addr, c_bcn_req_sub_len); /* 2 偏移 */
2895 if (reporting_detail != OAL_PTR_NULL) {
2896 rrm_info->bcn_req_info.rpt_detail = *(reporting_detail + 2); /* 2 偏移 */
2897 oam_warning_log2(0, OAM_SF_RRM, "vap_id[%d] hmac_rrm_parse_beacon_req::frame_body::rpt_detail[%d].",
2898 hmac_vap->vap_id, rrm_info->bcn_req_info.rpt_detail);
2899 }
2900
2901 last_ban_rpt = mac_find_ie_etc(164, detail_search_addr, c_bcn_req_sub_len); // 164 : LAST_BCN
2902 if ((last_ban_rpt != NULL) && (*(last_ban_rpt + 1) >= 1)) {
2903 rrm_info->bcn_req_info.rpt_frag_type = *(last_ban_rpt + 2); /* 2 偏移 */
2904 }
2905 }
2906
hmac_rrm_parse_beacon_reqinfo(hmac_vap_stru * hmac_vap,osal_u8 * reqinfo_search_addr,osal_u8 c_bcn_req_sub_len)2907 OAL_STATIC osal_u32 hmac_rrm_parse_beacon_reqinfo(hmac_vap_stru *hmac_vap, osal_u8 *reqinfo_search_addr,
2908 osal_u8 c_bcn_req_sub_len)
2909 {
2910 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2911 osal_u8 *reqinfo = OSAL_NULL;
2912
2913 if (rrm_info == OSAL_NULL) {
2914 return OAL_ERR_CODE_PTR_NULL;
2915 }
2916
2917 reqinfo = mac_find_ie_etc(MAC_EID_REQINFO, reqinfo_search_addr, c_bcn_req_sub_len);
2918 if (reqinfo != OAL_PTR_NULL) {
2919 rrm_info->bcn_req_info.req_ie_num = *(reqinfo + 1);
2920 oam_warning_log2(0, OAM_SF_RRM, "vap_id[%d] hmac_rrm_parse_beacon_req::frame_body::req_ie_num[%d].",
2921 hmac_vap->vap_id, rrm_info->bcn_req_info.req_ie_num);
2922 rrm_info->bcn_req_info.reqinfo_ieid = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL,
2923 rrm_info->bcn_req_info.req_ie_num, OAL_TRUE);
2924 if (rrm_info->bcn_req_info.reqinfo_ieid == OAL_PTR_NULL) {
2925 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_parse_beacon_req::memalloc reqinfo_ieid fail}");
2926 if (rrm_info->bcn_req_info.ssid != NULL) {
2927 oal_mem_free(rrm_info->bcn_req_info.ssid, OSAL_TRUE);
2928 rrm_info->bcn_req_info.ssid = NULL;
2929 rrm_info->bcn_req_info.ssid_len = 0;
2930 }
2931 return OAL_FAIL;
2932 }
2933 if (memcpy_s(rrm_info->bcn_req_info.reqinfo_ieid, rrm_info->bcn_req_info.req_ie_num,
2934 (reqinfo + 2), rrm_info->bcn_req_info.req_ie_num) != EOK) { /* 偏移2 */
2935 oam_warning_log0(0, OAM_SF_CFG, "{hmac_rrm_parse_beacon_req data::memcpy err.}");
2936 }
2937 }
2938 return OAL_SUCC;
2939 }
2940
hmac_rrm_parse_beacon_request(hmac_vap_stru * hmac_vap,mac_vap_rrm_info_stru * rrm_info,mac_bcn_req_stru * bcn_req,mac_scan_req_stru * scan_req)2941 OAL_STATIC osal_void hmac_rrm_parse_beacon_request(hmac_vap_stru *hmac_vap, mac_vap_rrm_info_stru *rrm_info,
2942 mac_bcn_req_stru *bcn_req, mac_scan_req_stru *scan_req)
2943 {
2944 osal_u32 ret;
2945
2946 rrm_info->bcn_req_info.opt_class = bcn_req->optclass;
2947 rrm_info->bcn_req_info.meas_duration = bcn_req->duration;
2948
2949 ret = hmac_rrm_meas_bcn(hmac_vap, bcn_req, scan_req);
2950 if (ret != OAL_SUCC) {
2951 hmac_rrm_free_ssid_and_reqinfo_ieid_item(rrm_info);
2952 oam_warning_log1(0, OAM_SF_RRM, "{hmac_rrm_parse_beacon_request::hmac_rrm_meas_bcn fail %u}", ret);
2953 }
2954 }
2955
2956 /*****************************************************************************
2957 函 数 名 : hmac_rrm_parse_beacon_req
2958 功能描述 : 解析Beacon Request信息,并准备测量
2959 输入参数 : hmac_vap : dmac vap结构体指针
2960 meas_req_ie : Measurement Request IE指针
2961 输出参数 : 无
2962 *****************************************************************************/
hmac_rrm_parse_beacon_req(hmac_vap_stru * hmac_vap,mac_meas_req_ie_stru * meas_req_ie)2963 OAL_STATIC osal_void hmac_rrm_parse_beacon_req(hmac_vap_stru *hmac_vap, mac_meas_req_ie_stru *meas_req_ie)
2964 {
2965 mac_bcn_req_stru *bcn_req = OSAL_NULL;
2966 mac_ap_chn_rpt_stru *apst_ap_chn_rpt[MAC_11K_SUPPORT_AP_CHAN_RPT_NUM];
2967 osal_u8 ap_chn_rpt_count = 0;
2968 osal_s8 c_bcn_req_sub_len;
2969 mac_scan_req_stru scan_req;
2970 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
2971 mac_meas_rpt_mode_stru rptmode;
2972 osal_u32 ret;
2973
2974 if (rrm_info == OSAL_NULL) {
2975 return;
2976 }
2977
2978 memset_s(&scan_req, OAL_SIZEOF(mac_scan_req_stru), 0, OAL_SIZEOF(mac_scan_req_stru));
2979 bcn_req = (mac_bcn_req_stru *)&(meas_req_ie->meas_req[0]);
2980 if (memcpy_s(rrm_info->bcn_req_info.bssid, WLAN_MAC_ADDR_LEN, bcn_req->bssid, WLAN_MAC_ADDR_LEN) != EOK) {
2981 oam_warning_log0(0, OAM_SF_CFG, "{hmac_rrm_parse_beacon_req data::memcpy err.}");
2982 }
2983 memset_s(&rptmode, OAL_SIZEOF(mac_meas_rpt_mode_stru), 0, OAL_SIZEOF(mac_meas_rpt_mode_stru));
2984
2985 /*************************************************************************/
2986 /* Beacon Request */
2987 /* -------------------------------------------------------------------- */
2988 /* |Operating Class |Channel Number |Rand Interval| Meas Duration | */
2989 /* -------------------------------------------------------------------- */
2990 /* |1 |1 | 2 | 2 | */
2991 /* -------------------------------------------------------------------- */
2992 /* -------------------------------------------------------------------- */
2993 /* |Meas Mode |BSSID |Optional Subelements | */
2994 /* -------------------------------------------------------------------- */
2995 /* |1 |6 | var | */
2996 /* -------------------------------------------------------------------- */
2997 /* */
2998 /*************************************************************************/
2999 oam_warning_log4(0, OAM_SF_RRM, "{Operating Class[%d],Channel Number[%d], Rand Interval[%u],Meas Duration[%u]}",
3000 bcn_req->optclass, bcn_req->channum, bcn_req->random_ivl, bcn_req->duration);
3001
3002 oam_warning_log4(0, OAM_SF_RRM, "{BSSID[%x:%x:%x:%x:xx:xx]}", bcn_req->bssid[0],
3003 bcn_req->bssid[1], bcn_req->bssid[2], bcn_req->bssid[3]); /* 1 2 3 MAC */
3004
3005 /* 从Subelements中获取被测信道集合,AP Channel Report可能会有多个 */
3006 c_bcn_req_sub_len = (osal_s8)meas_req_ie->len - 16; /* 16 长度 */
3007 if (c_bcn_req_sub_len <= 0) {
3008 ret = hmac_rrm_get_bcn_rpt_channels(bcn_req, apst_ap_chn_rpt, ap_chn_rpt_count, &scan_req,
3009 hmac_vap->channel.band);
3010 if (ret != OAL_SUCC) {
3011 rptmode.refused = 1;
3012 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
3013 return;
3014 }
3015 } else {
3016 if (hmac_rrm_parse_beacon_ap_chn(hmac_vap, bcn_req, (osal_u8)c_bcn_req_sub_len,
3017 &scan_req, rptmode) != OAL_SUCC) {
3018 return;
3019 }
3020
3021 /* 获取Beacon Reporting Information */
3022 if (hmac_rrm_parse_beacon_rpt_info(hmac_vap, bcn_req->subelm,
3023 (osal_u8)c_bcn_req_sub_len, rptmode) != OAL_SUCC) {
3024 return;
3025 }
3026
3027 /* 获取SSID */
3028 if (hmac_rrm_parse_beacon_ssid(hmac_vap, bcn_req->subelm, (osal_u8)c_bcn_req_sub_len) != OAL_SUCC) {
3029 return;
3030 }
3031 /* 获取Reporting detail */
3032 hmac_rrm_parse_beacon_report(hmac_vap, bcn_req->subelm, (osal_u8)c_bcn_req_sub_len);
3033 /* 获取ReqInfo */
3034 if (hmac_rrm_parse_beacon_reqinfo(hmac_vap, bcn_req->subelm, (osal_u8)c_bcn_req_sub_len) != OAL_SUCC) {
3035 return;
3036 }
3037 }
3038
3039 hmac_rrm_parse_beacon_request(hmac_vap, rrm_info, bcn_req, &scan_req);
3040 }
3041
hmac_rrm_handle_measure_req_ie(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,mac_meas_req_ie_stru * meas_req_ie,mac_action_rm_req_stru * rm_req)3042 OAL_STATIC osal_void hmac_rrm_handle_measure_req_ie(hmac_vap_stru* hmac_vap,
3043 hmac_user_stru *hmac_user, mac_meas_req_ie_stru *meas_req_ie, mac_action_rm_req_stru *rm_req)
3044 {
3045 mac_meas_rpt_mode_stru rptmode = {0};
3046 mac_vap_rrm_info_stru *rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
3047 hmac_11k_user_info_stru *hmac_11k_user_info = hmac_11k_get_user_info((osal_u8)hmac_user->assoc_id);
3048
3049 if (rrm_info == OSAL_NULL || hmac_11k_user_info == OSAL_NULL) {
3050 return;
3051 }
3052
3053 if (meas_req_ie->reqmode.enable == 1) {
3054 /* Req中拒绝某种类型的测量,一旦对端拒绝,在当前关联状态无法恢复测量能力位,需要重新关联 */
3055 if (meas_req_ie->reqmode.request == 0 && meas_req_ie->reqtype == RM_RADIO_MEAS_BCN) {
3056 oam_warning_log1(0, OAM_SF_RRM,
3057 "{hmac_rrm_handel_measure_reqs:: reqtype[%d] not support!}", meas_req_ie->reqtype);
3058 hmac_11k_user_info->rrm_enabled_cap.bcn_active_cap = 0;
3059 hmac_11k_user_info->rrm_enabled_cap.bcn_passive_cap = 0;
3060 hmac_11k_user_info->rrm_enabled_cap.bcn_table_cap = 0;
3061 hmac_11k_user_info->rrm_enabled_cap.bcn_meas_rpt_cond_cap = 0;
3062 }
3063
3064 /* Req中不允许发送对应的report */
3065 if (meas_req_ie->reqmode.rpt == 0) {
3066 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_handel_measure_reqs::user not expect rpt!}");
3067 return;
3068 }
3069 }
3070
3071 /* 并行测试暂不处理,如果对端要求则回复incapable bit */
3072 if (meas_req_ie->reqmode.parallel != 0) {
3073 rptmode.incapable = 1;
3074 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
3075 return;
3076 }
3077
3078 /* 处理Beacon req */
3079 if (meas_req_ie->reqtype == RM_RADIO_MEAS_BCN) {
3080 rrm_info->bcn_req_info.meas_type = meas_req_ie->reqtype;
3081 rrm_info->bcn_req_info.meas_token = meas_req_ie->token;
3082 rrm_info->bcn_req_info.repetition = OAL_NTOH_16(rm_req->num_rpt);
3083 rrm_info->bcn_req_info.dialog_token = rm_req->dialog_token;
3084 rrm_info->bcn_req_info.rpt_frag_type = MAC_BCN_RPT_NO_FRAG;
3085 hmac_rrm_parse_beacon_req(hmac_vap, meas_req_ie);
3086 } else {
3087 rptmode.incapable = 1;
3088 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
3089 oam_warning_log1(0, OAM_SF_RRM, "{Error Request,reqtype[%d]!}", meas_req_ie->reqtype);
3090 return;
3091 }
3092 }
3093
hmac_rrm_handel_measure_reqs(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,osal_u8 * netbuf,osal_u16 framebody_len)3094 OAL_STATIC osal_u32 hmac_rrm_handel_measure_reqs(hmac_vap_stru* hmac_vap, hmac_user_stru *hmac_user,
3095 osal_u8 *netbuf, osal_u16 framebody_len)
3096 {
3097 mac_vap_rrm_info_stru *rrm_info = OSAL_NULL;
3098 mac_meas_req_ie_stru *meas_req_ie = OSAL_NULL;
3099 mac_action_rm_req_stru *rm_req = OSAL_NULL;
3100 osal_u16 framebody_len_tmp;
3101 osal_u16 measure_ie_len;
3102
3103 rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
3104 if (rrm_info == OAL_PTR_NULL) {
3105 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_handel_measure_reqs::rrm_info is NULL}");
3106 return OAL_ERR_CODE_PTR_NULL;
3107 }
3108 rm_req = (mac_action_rm_req_stru *)(netbuf);
3109
3110 /**************************************************************************/
3111 /* Measurement Request IE */
3112 /* ---------------------------------------------------------------------- */
3113 /* |Element ID |Length |Meas Token| Meas Req Mode|Meas Type | Meas Req | */
3114 /* ---------------------------------------------------------------------- */
3115 /* |1 |1 | 1 | 1 |1 |var | */
3116 /* ---------------------------------------------------------------------- */
3117 /* */
3118 /**************************************************************************/
3119 /* 可能有多个Measurement Req IEs */
3120 framebody_len_tmp = framebody_len - MAC_MEASUREMENT_REQUEST_IE_OFFSET;
3121 while (framebody_len_tmp > MAC_IE_HDR_LEN) {
3122 meas_req_ie = (mac_meas_req_ie_stru *)&(netbuf[framebody_len - framebody_len_tmp]);
3123 rrm_info->meas_req_ie = meas_req_ie;
3124 measure_ie_len = meas_req_ie->len;
3125
3126 if ((framebody_len_tmp >= measure_ie_len) && (measure_ie_len > 0)) {
3127 framebody_len_tmp = framebody_len_tmp - measure_ie_len - MAC_IE_HDR_LEN;
3128 } else {
3129 oam_warning_log2(0, OAM_SF_RRM, "{invalid ie_len=[%d] len_tmp=[%d]!}", measure_ie_len, framebody_len_tmp);
3130 break;
3131 }
3132
3133 if (meas_req_ie->eid == MAC_EID_MEASREQ) {
3134 hmac_rrm_handle_measure_req_ie(hmac_vap, hmac_user, meas_req_ie, rm_req);
3135 } else {
3136 oam_warning_log1(0, OAM_SF_RRM, "{Error Request, but got EID[%d]!}", meas_req_ie->eid);
3137 return OAL_FAIL;
3138 }
3139 }
3140 return OAL_SUCC;
3141 }
3142
hmac_config_rrm_proc_rm_request(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,osal_u8 * netbuf,osal_u16 framebody_len)3143 OAL_STATIC osal_u32 hmac_config_rrm_proc_rm_request(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
3144 osal_u8 *netbuf, osal_u16 framebody_len)
3145 {
3146 mac_action_rm_req_stru *rm_req = OSAL_NULL;
3147 osal_u16 us_framebody_len;
3148 mac_vap_rrm_info_stru *rrm_info = OSAL_NULL;
3149 mac_meas_rpt_mode_stru rptmode = {0};
3150
3151 if (hmac_vap == OAL_PTR_NULL || hmac_user == OAL_PTR_NULL) {
3152 return OAL_ERR_CODE_PTR_NULL;
3153 }
3154
3155 rrm_info = hmac_11k_get_vap_rrm_info(hmac_vap);
3156 if (rrm_info == OAL_PTR_NULL) {
3157 oam_error_log0(0, OAM_SF_RRM, "{hmac_rrm_proc_rm_request::rrm_info is NULL}");
3158 return OAL_ERR_CODE_PTR_NULL;
3159 }
3160 us_framebody_len = framebody_len;
3161 rm_req = (mac_action_rm_req_stru *)(netbuf);
3162
3163 /**************************************************************************/
3164 /* Radio Measurement Request Frame - Frame Body */
3165 /* ---------------------------------------------------------------------- */
3166 /* |Category |Action |Dialog Token| Number of Repetitions|Meas Req Eles | */
3167 /* ---------------------------------------------------------------------- */
3168 /* |1 |1 | 1 | 2 |var */
3169 /* ---------------------------------------------------------------------- */
3170 /* */
3171 /**************************************************************************/
3172 /* 判断VAP是否正在进行测量 */
3173 if (rrm_info->is_measuring == OAL_TRUE) {
3174 oam_warning_log0(0, OAM_SF_RRM, "{hmac_rrm_proc_rm_request::vap is handling one request now.}");
3175 hmac_rrm_encap_meas_rpt_refuse_new_req(hmac_vap, hmac_user, rm_req);
3176 return OAL_FAIL;
3177 }
3178
3179 /* 保存req */
3180 rrm_info->action_code = rm_req->action_code;
3181 rrm_info->dialog_token = rm_req->dialog_token;
3182 rrm_info->req_user_id = hmac_user->assoc_id;
3183
3184 /* 是否有Meas Req */
3185 if (us_framebody_len <= MAC_RADIO_MEAS_ACTION_REQ_FIX_LEN) {
3186 /* 如果没有MR IE,也回一个不带Meas Rpt的Radio Meas Rpt */
3187 /* 申请管理帧内存并填充头部信息 */
3188 if (hmac_rrm_fill_basic_rm_rpt_action(hmac_vap) != OAL_SUCC) {
3189 return OAL_FAIL;
3190 }
3191 (osal_void)hmac_rrm_send_rm_rpt_action(hmac_vap);
3192 return OAL_FAIL;
3193 }
3194
3195 /* 重复测试次数暂不处理,如果对端要求重复测试,则回复incapable bit */
3196 oam_warning_log4(0, OAM_SF_RRM,
3197 "hmac_rrm_proc_rm_request::framebody::Category[%d],Action[%d],Dialog Token[%d],Number of Repetitions[%d].",
3198 rm_req->category, rm_req->action_code, rm_req->dialog_token, rm_req->num_rpt);
3199
3200 if (rm_req->num_rpt != 0) {
3201 rptmode.incapable = 1;
3202 hmac_rrm_encap_meas_rpt_reject(hmac_vap, &rptmode);
3203 oam_warning_log2(0, OAM_SF_RRM,
3204 "vap_id[%d] hmac_rrm_proc_rm_request::RepeatedMeasurements not support, num_rpt[%u].",
3205 hmac_vap->vap_id, rm_req->num_rpt);
3206 return OAL_FAIL;
3207 }
3208 return hmac_rrm_handel_measure_reqs(hmac_vap, hmac_user, netbuf, framebody_len);
3209 }
3210
3211 /*****************************************************************************
3212 函 数 名 : hmac_config_send_radio_meas_req
3213 功能描述 : radio_meas_req
3214 *****************************************************************************/
hmac_config_send_radio_meas_req(hmac_vap_stru * hmac_vap,frw_msg * msg)3215 OAL_STATIC osal_s32 hmac_config_send_radio_meas_req(hmac_vap_stru *hmac_vap, frw_msg *msg)
3216 {
3217 mac_chn_load_req_stru chn_load_req;
3218 mac_bcn_req_stru bcn_req;
3219 mac_rrm_req_cfg_stru req_cfg;
3220 mac_cfg_radio_meas_info_stru *radio_meas_cfg = (mac_cfg_radio_meas_info_stru *)msg->data;
3221 /* 获取用户 */
3222 hmac_user_stru *hmac_user = hmac_vap_get_user_by_addr_etc(hmac_vap, radio_meas_cfg->auc_mac_addr,
3223 WLAN_MAC_ADDR_LEN);
3224 if (hmac_user == OAL_PTR_NULL) {
3225 oam_error_log0(0, OAM_SF_CFG, "{hmac_config_send_radio_meas_req::mac_user is null.}");
3226 return OAL_ERR_CODE_PTR_NULL;
3227 }
3228
3229 /* Neighbor Report Request */
3230 if (radio_meas_cfg->action_type == MAC_RM_ACTION_NEIGHBOR_REPORT_REQUEST) {
3231 req_cfg.rpt_notify_id = HMAC_RRM_RPT_NOTIFY_11V;
3232 req_cfg.reqtype = MAC_RRM_TYPE_NEIGHBOR_RPT;
3233 hmac_config_send_meas_req(hmac_vap, hmac_user, &req_cfg);
3234 return OAL_SUCC;
3235 }
3236
3237 if (radio_meas_cfg->action_type != MAC_RM_ACTION_RADIO_MEASUREMENT_REQUEST) {
3238 return OAL_FAIL;
3239 }
3240
3241 /* Radio Measurement Request */
3242 req_cfg.rpt_num = radio_meas_cfg->num_rpt;
3243 req_cfg.req_mode = radio_meas_cfg->req_mode;
3244
3245 /* param set */
3246 radio_meas_cfg->random_ivl = 0;
3247
3248 /* optclass打桩 */
3249 radio_meas_cfg->optclass = 0;
3250
3251 if (radio_meas_cfg->means_type == RM_RADIO_MEAS_CHANNEL_LOAD) {
3252 /*************************************************************************/
3253 /* Channel Load Request */
3254 /* --------------------------------------------------------------------- */
3255 /* |Operating Class |Channel Number |Rand Interval| Meas Duration */
3256 /* --------------------------------------------------------------------- */
3257 /* |1 |1 | 2 | 2 */
3258 /* --------------------------------------------------------------------- */
3259 /* --------------------------------------------------------------------- */
3260 /* |Optional Subelements */
3261 /* --------------------------------------------------------------------- */
3262 /* | var */
3263 /* --------------------------------------------------------------------- */
3264 /* */
3265 /*************************************************************************/
3266 chn_load_req.optclass = radio_meas_cfg->optclass;
3267 chn_load_req.channum = radio_meas_cfg->channum;
3268 chn_load_req.random_ivl = radio_meas_cfg->random_ivl;
3269 chn_load_req.duration = radio_meas_cfg->duration;
3270
3271 req_cfg.rpt_notify_id = HMAC_RRM_RPT_NOTIFY_CHN_LOAD;
3272 req_cfg.reqtype = MAC_RRM_TYPE_CHANNEL_LOAD;
3273 req_cfg.p_arg = (osal_void *)&chn_load_req;
3274 hmac_config_send_meas_req(hmac_vap, hmac_user, &req_cfg);
3275 } else if (radio_meas_cfg->means_type == RM_RADIO_MEAS_BCN) {
3276 /*************************************************************************/
3277 /* Beacon Request */
3278 /* --------------------------------------------------------------------- */
3279 /* |Operating Class |Channel Number |Rand Interval| Meas Duration */
3280 /* --------------------------------------------------------------------- */
3281 /* |1 |1 | 2 | 2 */
3282 /* --------------------------------------------------------------------- */
3283 /* --------------------------------------------------------------------- */
3284 /* |Meas Mode |BSSID |Optional Subelements */
3285 /* --------------------------------------------------------------------- */
3286 /* |1 |6 | var */
3287 /* --------------------------------------------------------------------- */
3288 /* */
3289 /*************************************************************************/
3290 bcn_req.optclass = radio_meas_cfg->optclass;
3291 bcn_req.channum = radio_meas_cfg->channum;
3292 bcn_req.random_ivl = radio_meas_cfg->random_ivl;
3293 bcn_req.duration = radio_meas_cfg->duration;
3294 bcn_req.mode = radio_meas_cfg->bcn_mode;
3295 oal_set_mac_addr(bcn_req.bssid, radio_meas_cfg->bssid);
3296
3297 req_cfg.rpt_notify_id = HMAC_RRM_RPT_NOTIFY_HILINK;
3298 req_cfg.reqtype = MAC_RRM_TYPE_BCN;
3299 req_cfg.p_arg = (osal_void *)&bcn_req;
3300 hmac_config_send_meas_req(hmac_vap, hmac_user, &req_cfg);
3301 } else {
3302 oam_warning_log1(0, OAM_SF_ANY, "{invalid means_type[%d].}", radio_meas_cfg->means_type);
3303 return OAL_FAIL;
3304 }
3305
3306 return OAL_SUCC;
3307 }
3308
3309 /*****************************************************************************
3310 功能描述 : 命令设置radio_measurement_request参数,模拟AP侧发送的帧
3311 *****************************************************************************/
hmac_config_encap_meas_req_params(hmac_vap_stru * hmac_vap,osal_u8 * buffer,osal_u8 * param)3312 OAL_STATIC osal_u16 hmac_config_encap_meas_req_params(hmac_vap_stru *hmac_vap, osal_u8 *buffer, osal_u8 *param)
3313 {
3314 osal_u16 meas_req_frm_len = 0;
3315 mac_meas_req_ie_stru *meas_req_ie = OSAL_NULL;
3316 mac_action_rm_req_stru *rm_req = OSAL_NULL;
3317 osal_u8 *req_mode = OSAL_NULL;
3318 osal_u8 *reporting_detail = OSAL_NULL;
3319 mac_bcn_req_stru bcn_req;
3320 mac_cfg_radio_meas_info_stru *radio_meas_cfg;
3321 errno_t ret;
3322
3323 unref_param(hmac_vap);
3324 radio_meas_cfg = (mac_cfg_radio_meas_info_stru *)param;
3325 /* *********************************************************************** */
3326 /* Radio Measurement Request Frame - Frame Body */
3327 /* --------------------------------------------------------------------- */
3328 /* |Category |Action |Dialog Token| Number of Repetitions|Meas Req Eles | */
3329 /* --------------------------------------------------------------------- */
3330 /* |1 |1 | 1 | 2 |var */
3331 /* --------------------------------------------------------------------- */
3332 /* */
3333 /* *********************************************************************** */
3334 /* Radio Measurement Request */
3335 rm_req = (mac_action_rm_req_stru *)buffer;
3336 rm_req->category = MAC_ACTION_CATEGORY_RADIO_MEASURMENT;
3337 rm_req->action_code = radio_meas_cfg->action_type;
3338 rm_req->dialog_token = 10; /* 10表示token值 */
3339 rm_req->num_rpt = radio_meas_cfg->num_rpt;
3340 meas_req_ie = (mac_meas_req_ie_stru *)rm_req->req_ies;
3341
3342 /* *********************************************************************** */
3343 /* Measurement Request IE */
3344 /* --------------------------------------------------------------------- */
3345 /* |Element ID |Length |Meas Token| Meas Req Mode|Meas Type | Meas Req | */
3346 /* --------------------------------------------------------------------- */
3347 /* |1 |1 | 1 | 1 |1 |var | */
3348 /* --------------------------------------------------------------------- */
3349 /* */
3350 /* *********************************************************************** */
3351 /* Beacon Request */
3352 bcn_req.optclass = 12; // 12表示信道集
3353 bcn_req.channum = radio_meas_cfg->channum;
3354 bcn_req.random_ivl = 0;
3355 bcn_req.duration = radio_meas_cfg->duration;
3356 bcn_req.mode = radio_meas_cfg->bcn_mode;
3357 oal_set_mac_addr(bcn_req.bssid, radio_meas_cfg->bssid);
3358
3359 meas_req_ie->eid = MAC_EID_MEASREQ;
3360 meas_req_ie->token = 50; /* 50代表token值 */
3361 req_mode = (osal_u8 *)(&(meas_req_ie->reqmode));
3362 *req_mode = radio_meas_cfg->req_mode;
3363 meas_req_ie->len = 16; /* 16表示beacon默认长度 */
3364 meas_req_ie->reqtype = RM_RADIO_MEAS_BCN;
3365 ret = memcpy_s((mac_bcn_req_stru *)meas_req_ie->meas_req, sizeof(mac_bcn_req_stru),
3366 (mac_bcn_req_stru *)&bcn_req, sizeof(mac_bcn_req_stru));
3367 if (ret != EOK) {
3368 oam_error_log1(0, OAM_SF_RRM, "{hmac_config_encap_meas_req_params failed: memcpy error = [%d]}", ret);
3369 return OAL_FAIL;
3370 }
3371
3372 /* optional subelement */
3373 reporting_detail = ((mac_bcn_req_stru *)meas_req_ie->meas_req)->subelm;
3374 /* 2,Reporting Detail */
3375 *(reporting_detail + 0) = 2;
3376 *(reporting_detail + 1) = 1;
3377 *(reporting_detail + 2) = 1; /* 2表示字段类型参数 */
3378 meas_req_ie->len += 3; /* 3表示可选字段长度 */
3379
3380 meas_req_frm_len = meas_req_frm_len + MAC_IE_HDR_LEN + (osal_u16)(meas_req_ie->len);
3381 meas_req_ie = (mac_meas_req_ie_stru *)(rm_req->req_ies + meas_req_frm_len);
3382
3383 meas_req_frm_len += MAC_MEASUREMENT_REQUEST_IE_OFFSET;
3384 return meas_req_frm_len;
3385 }
3386
3387 /*****************************************************************************
3388 功能描述 : 命令发送radio_measurement_report帧
3389 *****************************************************************************/
hmac_config_send_radio_meas_rpt(hmac_vap_stru * hmac_vap,frw_msg * msg)3390 OAL_STATIC osal_s32 hmac_config_send_radio_meas_rpt(hmac_vap_stru *hmac_vap, frw_msg *msg)
3391 {
3392 hmac_user_stru *hmac_user = (hmac_user_stru *)mac_res_get_hmac_user_etc(hmac_vap->assoc_vap_id);
3393 osal_u8 rpt_param[WLAN_MEM_NETBUF_CNT1] = {0};
3394 osal_u16 framebody_len;
3395 framebody_len = hmac_config_encap_meas_req_params(hmac_vap, (osal_u8 *)rpt_param, msg->data);
3396 return (osal_s32)hmac_config_rrm_proc_rm_request(hmac_vap, hmac_user, (osal_u8 *)rpt_param, framebody_len);
3397 }
3398
hmac_11k_set_tsf(hmac_vap_stru * hmac_vap,mac_bss_dscr_stru * bss_dscr,mac_scanned_result_extend_info_stru * scan_result_extend)3399 OAL_STATIC osal_void hmac_11k_set_tsf(hmac_vap_stru *hmac_vap, mac_bss_dscr_stru *bss_dscr,
3400 mac_scanned_result_extend_info_stru *scan_result_extend)
3401 {
3402 if (hmac_vap == OSAL_NULL || bss_dscr == OSAL_NULL || scan_result_extend == OSAL_NULL) {
3403 return;
3404 }
3405
3406 if (hmac_vap_id_param_check(hmac_vap->vap_id) != OSAL_TRUE) {
3407 return;
3408 }
3409
3410 if (!is_legacy_sta(hmac_vap)) {
3411 return;
3412 }
3413
3414 if (g_11k_vap_info[hmac_vap->vap_id] == OSAL_NULL) {
3415 return;
3416 }
3417
3418 if (g_11k_vap_info[hmac_vap->vap_id]->enable_11k == OSAL_TRUE) {
3419 /* RSNI */
3420 bss_dscr->ac_rsni[0] = scan_result_extend->snr_ant0;
3421 bss_dscr->ac_rsni[1] = scan_result_extend->snr_ant1;
3422 /* phy type */
3423 bss_dscr->phy_type = (bss_dscr->st_channel.band == WLAN_BAND_2G) ? PHY_TYPE_DSSS : PHY_TYPE_OFDM;
3424 /* Parent TSF */
3425 bss_dscr->parent_tsf = scan_result_extend->parent_tsf;
3426 }
3427
3428 return;
3429 }
3430
3431 /*****************************************************************************
3432 函 数 名 : hmac_scan_update_bss_list_rrm
3433 功能描述 : 判断对方是否携带rrm
3434 *****************************************************************************/
hmac_scan_update_bss_list_rrm(mac_bss_dscr_stru * bss_dscr,osal_u8 * frame_body,osal_u16 frame_len)3435 OAL_STATIC osal_void hmac_scan_update_bss_list_rrm(mac_bss_dscr_stru *bss_dscr, osal_u8 *frame_body, osal_u16 frame_len)
3436 {
3437 osal_u8 *ie = OSAL_NULL;
3438
3439 if (bss_dscr == OSAL_NULL || frame_body == OSAL_NULL) {
3440 return;
3441 }
3442
3443 ie = mac_find_ie_etc(MAC_EID_RRM, frame_body, frame_len);
3444 if (ie == OAL_PTR_NULL) {
3445 bss_dscr->support_rrm = OAL_FALSE;
3446 } else {
3447 bss_dscr->support_rrm = OAL_TRUE;
3448 }
3449
3450 return;
3451 }
3452
hmac_11k_get_tsf(hmac_vap_stru * hmac_vap,mac_scanned_result_extend_info_stru * scan_result_ext_info,dmac_rx_ctl_stru * rx_ctrl)3453 OAL_STATIC osal_void hmac_11k_get_tsf(hmac_vap_stru *hmac_vap,
3454 mac_scanned_result_extend_info_stru *scan_result_ext_info, dmac_rx_ctl_stru *rx_ctrl)
3455 {
3456 if (hmac_vap == OSAL_NULL || scan_result_ext_info == OSAL_NULL || rx_ctrl == OSAL_NULL) {
3457 return;
3458 }
3459
3460 if (!is_legacy_sta(hmac_vap)) {
3461 return;
3462 }
3463
3464 hal_vap_tsf_get_32bit(hmac_vap->hal_vap, (osal_u32 *)&(scan_result_ext_info->parent_tsf));
3465 hal_phy_rx_get_snr_info(hal_chip_get_hal_device(),
3466 (uint8_t)rx_ctrl->rx_statistic.nss_rate.legacy_rate.protocol_mode,
3467 (uint16_t)rx_ctrl->rx_statistic.snr_ant0, &scan_result_ext_info->snr_ant0);
3468 hal_phy_rx_get_snr_info(hal_chip_get_hal_device(),
3469 (uint8_t)rx_ctrl->rx_statistic.nss_rate.legacy_rate.protocol_mode,
3470 (uint16_t)rx_ctrl->rx_statistic.snr_ant1, &scan_result_ext_info->snr_ant1);
3471 return;
3472 }
3473
3474 /*****************************************************************************
3475 功能描述 : 填充RRM Enabled Cap IE
3476 *****************************************************************************/
hmac_set_rrm_enabled_cap_field_etc(osal_void * vap,osal_u8 * buffer,osal_u8 * ie_len)3477 OAL_STATIC osal_void hmac_set_rrm_enabled_cap_field_etc(osal_void *vap, osal_u8 *buffer, osal_u8 *ie_len)
3478 {
3479 hmac_vap_stru *hmac_vap = (hmac_vap_stru *)vap;
3480 oal_rrm_enabled_cap_ie_stru *rrm_enabled_cap_ie;
3481
3482 if (vap == OSAL_NULL || buffer == OSAL_NULL || ie_len == OSAL_NULL) {
3483 return;
3484 }
3485
3486 if (mac_mib_get_dot11_radio_measurement_activated(hmac_vap) == OSAL_FALSE) {
3487 *ie_len = 0;
3488 return;
3489 }
3490
3491 buffer[0] = MAC_EID_RRM;
3492 buffer[1] = MAC_RRM_ENABLE_CAP_IE_LEN;
3493
3494 rrm_enabled_cap_ie = (oal_rrm_enabled_cap_ie_stru *)(buffer + MAC_IE_HDR_LEN);
3495
3496 memset_s(rrm_enabled_cap_ie, sizeof(oal_rrm_enabled_cap_ie_stru), 0, sizeof(oal_rrm_enabled_cap_ie_stru));
3497
3498 /* 只有bit0 4 5 6位置1 */
3499 rrm_enabled_cap_ie->link_cap = mac_mib_get_dot11RMLinkMeasurementActivated(hmac_vap);
3500 rrm_enabled_cap_ie->bcn_passive_cap = mac_mib_get_dot11RMBeaconPassiveMeasurementActivated(vap);
3501 rrm_enabled_cap_ie->bcn_active_cap = mac_mib_get_dot11RMBeaconActiveMeasurementActivated(vap);
3502 rrm_enabled_cap_ie->bcn_table_cap = mac_mib_get_dot11RMBeaconTableMeasurementActivated(vap);
3503 rrm_enabled_cap_ie->chn_load_cap = mac_mib_get_dot11RMChannelLoadMeasurementActivated(vap);
3504 rrm_enabled_cap_ie->neighbor_rpt_cap = mac_mib_get_dot11RMNeighborReportActivated(vap);
3505
3506 #ifdef _PRE_WLAN_FEATURE_FTM
3507 rrm_enabled_cap_ie->ftm_range_report_cap = mac_mib_get_fine_timing_msmt_range_req_activated(hmac_vap);
3508 #endif
3509
3510 *ie_len = MAC_IE_HDR_LEN + MAC_RRM_ENABLE_CAP_IE_LEN;
3511 }
3512
3513 /*****************************************************************************
3514 函 数 名 : hmac_sta_up_update_rrm_capability
3515 功能描述 : 更新ASOC关联实体中的radio measurement & neighbor信息
3516 输入参数 : 无
3517 输出参数 : 无
3518 *****************************************************************************/
hmac_sta_up_update_rrm_capability(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,osal_u8 * payload,osal_u32 rx_len)3519 OAL_STATIC osal_u32 hmac_sta_up_update_rrm_capability(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
3520 osal_u8 *payload, osal_u32 rx_len)
3521 {
3522 osal_u8 *ie = OSAL_NULL;
3523 osal_u8 len;
3524 mac_cap_info_stru *user_cap_info;
3525 mac_rrm_enabled_cap_ie_stru *rrm_enabled_cap_ie;
3526 hmac_11k_user_info_stru *hmac_11k_user_info = OSAL_NULL;
3527
3528 if (hmac_vap == OSAL_NULL || hmac_user == OSAL_NULL || payload == OSAL_NULL) {
3529 return OAL_FAIL;
3530 }
3531
3532 hmac_11k_user_info = hmac_11k_get_user_info((osal_u8)hmac_user->assoc_id);
3533 if (hmac_11k_user_info == OSAL_NULL) {
3534 return OAL_ERR_CODE_PTR_NULL;
3535 }
3536
3537 /* 发送assoc req前从AP获取的能力 */
3538 user_cap_info = (mac_cap_info_stru *)(&(hmac_vap->assoc_user_cap_info));
3539
3540 if (user_cap_info->radio_measurement == OAL_FALSE) {
3541 oam_warning_log1(0, OAM_SF_ASSOC,
3542 "vap_id[%d] {hmac_sta_up_update_rrm_capability::user not support MAC_CAP_RADIO_MEAS", hmac_vap->vap_id);
3543 return OAL_SUCC;
3544 }
3545
3546 ie = mac_find_ie_etc(MAC_EID_RRM, payload, (osal_s32)rx_len);
3547 if (ie == OAL_PTR_NULL) {
3548 oam_warning_log1(0, OAM_SF_ASSOC,
3549 "vap_id[%d] {hmac_sta_up_update_rrm_capability::user support 11k but not fill rrm_enabled_cap_ie.}",
3550 hmac_vap->vap_id);
3551 return OAL_FAIL;
3552 }
3553
3554 hmac_user->cap_info.enable_11k = OAL_TRUE;
3555
3556 /* user rrm capability list */
3557 len = ie[1];
3558 if (len > sizeof(mac_rrm_enabled_cap_ie_stru)) {
3559 oam_error_log0(0, OAM_SF_ANY, "{hmac_sta_up_update_rrm_capability::ie len invalid}");
3560 return OAL_FAIL;
3561 }
3562 if (memcpy_s(&(hmac_11k_user_info->rrm_enabled_cap), sizeof(mac_rrm_enabled_cap_ie_stru),
3563 ie + MAC_IE_HDR_LEN, len) != EOK) {
3564 oam_error_log0(0, OAM_SF_ANY, "{hmac_sta_up_update_rrm_capability::memcpy_s error}");
3565 }
3566
3567 rrm_enabled_cap_ie = (mac_rrm_enabled_cap_ie_stru *)(ie + MAC_IE_HDR_LEN);
3568 oam_warning_log4(0, OAM_SF_ASSOC,
3569 "{hmac_sta_up_update_rrm_capability::neighbor[%d], beacon[active:%d][passive:%d][table:%d].}",
3570 rrm_enabled_cap_ie->neighbor_rpt_cap,
3571 rrm_enabled_cap_ie->bcn_active_cap,
3572 rrm_enabled_cap_ie->bcn_passive_cap,
3573 rrm_enabled_cap_ie->bcn_table_cap);
3574 oam_warning_log2(0, OAM_SF_ASSOC,
3575 "vap_id[%d] {hmac_sta_up_update_rrm_capability::load[%d].}", hmac_vap->vap_id,
3576 rrm_enabled_cap_ie->chn_load_cap);
3577
3578 hmac_11k_init_rrm_info(hmac_user);
3579
3580 return OAL_SUCC;
3581 }
3582
hmac_sta_up_rx_action_radio_measurment(oal_netbuf_stru ** netbuf,hmac_vap_stru * hmac_vap)3583 OAL_STATIC osal_u32 hmac_sta_up_rx_action_radio_measurment(oal_netbuf_stru **netbuf, hmac_vap_stru *hmac_vap)
3584 {
3585 osal_u8 *data = OSAL_NULL;
3586 hmac_user_stru *hmac_user = OSAL_NULL;
3587 dmac_rx_ctl_stru *rx_ctl = OSAL_NULL;
3588 mac_ieee80211_frame_stru *frame_hdr = OSAL_NULL;
3589
3590 if (hmac_vap == OSAL_NULL || netbuf == OSAL_NULL) {
3591 return OAL_CONTINUE;
3592 }
3593
3594 rx_ctl = (dmac_rx_ctl_stru *)oal_netbuf_cb(*netbuf); /* 获取帧头信息 */
3595 data = oal_netbuf_rx_data(*netbuf);
3596 frame_hdr = (mac_ieee80211_frame_stru *)mac_get_rx_cb_mac_hdr(&(rx_ctl->rx_info));
3597
3598 if (!is_legacy_sta(hmac_vap)) {
3599 return OAL_CONTINUE;
3600 }
3601
3602 if (hmac_vap_id_param_check(hmac_vap->vap_id) != OSAL_TRUE) {
3603 return OAL_CONTINUE;
3604 }
3605
3606 if (hmac_11k_get_vap_info(hmac_vap)->enable_11k == OAL_FALSE) {
3607 return OAL_CONTINUE;
3608 }
3609
3610 if (frame_hdr->frame_control.sub_type != WLAN_ACTION || frame_hdr->frame_control.type != WLAN_MANAGEMENT) {
3611 return OAL_CONTINUE;
3612 }
3613
3614 if ((data[MAC_ACTION_OFFSET_ACTION] != MAC_RM_ACTION_RADIO_MEASUREMENT_REQUEST) ||
3615 (data[MAC_ACTION_OFFSET_CATEGORY] != MAC_ACTION_CATEGORY_RADIO_MEASURMENT)) {
3616 return OAL_CONTINUE;
3617 }
3618
3619 hmac_user = mac_vap_get_hmac_user_by_addr_etc(hmac_vap, frame_hdr->address2);
3620 if (hmac_user == OAL_PTR_NULL) {
3621 return OAL_CONTINUE;
3622 }
3623
3624 hmac_rrm_proc_rm_request(hmac_vap, hmac_user, *netbuf);
3625
3626 return OAL_CONTINUE;
3627 }
3628
3629 /*****************************************************************************
3630 函 数 名 : hmac_ap_up_update_rrm_capability
3631 功能描述 : 更新ASOC关联实体中的radio measurement & neighbor信息
3632 输入参数 : 无
3633 输出参数 : 无
3634 *****************************************************************************/
hmac_ap_up_update_rrm_capability(hmac_user_stru * hmac_user,osal_u16 us_cap_info,osal_u8 * payload,osal_u32 msg_len)3635 OAL_STATIC osal_u32 hmac_ap_up_update_rrm_capability(hmac_user_stru *hmac_user, osal_u16 us_cap_info,
3636 osal_u8 *payload, osal_u32 msg_len)
3637 {
3638 osal_u8 *ie = OAL_PTR_NULL;
3639 osal_u8 len;
3640 mac_rrm_enabled_cap_ie_stru *rrm_enabled_cap_ie;
3641 hmac_11k_user_info_stru *hmac_11k_user_info = OSAL_NULL;
3642
3643 if (hmac_user == OSAL_NULL || payload == OSAL_NULL) {
3644 return OAL_FAIL;
3645 }
3646
3647 hmac_11k_user_info = hmac_11k_get_user_info((osal_u8)hmac_user->assoc_id);
3648 if (hmac_11k_user_info == OSAL_NULL) {
3649 return OAL_ERR_CODE_PTR_NULL;
3650 }
3651
3652 if ((us_cap_info & MAC_CAP_RADIO_MEAS) != MAC_CAP_RADIO_MEAS) {
3653 oam_warning_log2(0, OAM_SF_ASSOC,
3654 "vap_id[%d] {hmac_ap_up_update_rrm_capability::user not support MAC_CAP_RADIO_MEAS[%x].}",
3655 hmac_user->vap_id, us_cap_info);
3656 return OAL_SUCC;
3657 }
3658
3659 ie = mac_find_ie_etc(MAC_EID_RRM, payload, (osal_s32)msg_len);
3660 if (ie == OAL_PTR_NULL) {
3661 oam_warning_log1(0, OAM_SF_ASSOC,
3662 "vap_id[%d] {hmac_ap_up_update_rrm_capability::user support 11k but not fill rrm_enabled_cap_ie.}",
3663 hmac_user->vap_id);
3664 return OAL_FAIL;
3665 }
3666
3667 hmac_user->cap_info.enable_11k = OAL_TRUE;
3668
3669 /* user rrm capability list */
3670 len = ie[1];
3671 if (memcpy_s(&(hmac_11k_user_info->rrm_enabled_cap), sizeof(mac_rrm_enabled_cap_ie_stru),
3672 ie + MAC_IE_HDR_LEN, len) != EOK) {
3673 oam_error_log0(0, OAM_SF_ANY, "{hmac_ap_up_update_rrm_capability::memcpy_s error}");
3674 }
3675
3676 rrm_enabled_cap_ie = (mac_rrm_enabled_cap_ie_stru *)(ie + MAC_IE_HDR_LEN);
3677 oam_warning_log4(0, OAM_SF_ASSOC,
3678 "{hmac_ap_up_update_rrm_capability::neighbor[%d], beacon[active:%d][passive:%d][table:%d].}",
3679 rrm_enabled_cap_ie->neighbor_rpt_cap,
3680 rrm_enabled_cap_ie->bcn_active_cap,
3681 rrm_enabled_cap_ie->bcn_passive_cap,
3682 rrm_enabled_cap_ie->bcn_table_cap);
3683 oam_warning_log2(0, OAM_SF_ASSOC,
3684 "vap_id[%d] {hmac_ap_up_update_rrm_capability::load[%d].}", hmac_user->vap_id,
3685 rrm_enabled_cap_ie->chn_load_cap);
3686
3687 hmac_11k_init_rrm_info(hmac_user);
3688
3689 return OAL_SUCC;
3690 }
3691
hmac_get_11k_cap(hmac_vap_stru * hmac_vap,osal_s32 * pl_value)3692 OAL_STATIC osal_void hmac_get_11k_cap(hmac_vap_stru *hmac_vap, osal_s32 *pl_value)
3693 {
3694 osal_u8 vap_id;
3695 osal_u32 val;
3696
3697 if (hmac_vap == OSAL_NULL || pl_value == OSAL_NULL) {
3698 return;
3699 }
3700
3701 val = (osal_u32)(*pl_value);
3702
3703 if (!is_legacy_sta(hmac_vap)) {
3704 return;
3705 }
3706
3707 vap_id = hmac_vap->vap_id;
3708 if (hmac_vap_id_param_check(vap_id) != OSAL_TRUE) {
3709 return;
3710 }
3711
3712 if (g_11k_vap_info[vap_id] != OSAL_NULL && g_11k_vap_info[vap_id]->enable_11k == OAL_TRUE) {
3713 val |= BIT(WAL_WIFI_FEATURE_SUPPORT_11K);
3714 *pl_value = (osal_s32)val;
3715 }
3716
3717 return;
3718 }
3719
3720 hmac_netbuf_hook_stru g_11k_netbuf_hook = {
3721 .hooknum = HMAC_FRAME_MGMT_RX_EVENT_D2H,
3722 .priority = HMAC_HOOK_PRI_HIGH,
3723 .hook_func = hmac_sta_up_rx_action_radio_measurment,
3724 };
3725
hmac_11k_init(osal_void)3726 osal_u32 hmac_11k_init(osal_void)
3727 {
3728 osal_u32 ret;
3729
3730 /* 注册监听 */
3731 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_ADD_VAP, hmac_11k_add_vap);
3732 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_DEL_VAP, hmac_11k_del_vap);
3733 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_DOWN_VAP, hmac_11k_down_vap);
3734 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_ADD_USER, hmac_11k_add_user);
3735 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_11k_del_user);
3736 frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_SCAN_BEGIN, hmac_rrm_get_meas_start_time);
3737 /* 注册消息 */
3738 frw_msg_hook_register(WLAN_MSG_W2H_CFG_SEND_RADIO_MEAS_REQ, hmac_config_send_radio_meas_req);
3739 frw_msg_hook_register(WLAN_MSG_W2H_CFG_SEND_RADIO_MEAS_RPT, hmac_config_send_radio_meas_rpt);
3740 /* 注册对外接口 */
3741 hmac_feature_hook_register(HMAC_FHOOK_11K_STA_UPDATE_RRM_CAP, hmac_sta_up_update_rrm_capability);
3742 hmac_feature_hook_register(HMAC_FHOOK_11K_AP_UPDATE_RRM_CAP, hmac_ap_up_update_rrm_capability);
3743 hmac_feature_hook_register(HMAC_FHOOK_11K_SET_RRM_CAP, hmac_set_rrm_enabled_cap_field_etc);
3744 hmac_feature_hook_register(HMAC_FHOOK_11K_GET_TSF, hmac_11k_get_tsf);
3745 hmac_feature_hook_register(HMAC_FHOOK_11K_UPDATE_BSS_LIST_RRM, hmac_scan_update_bss_list_rrm);
3746 hmac_feature_hook_register(HMAC_FHOOK_11K_SET_TSF, hmac_11k_set_tsf);
3747 hmac_feature_hook_register(HMAC_FHOOK_GET_11K_CAP, hmac_get_11k_cap);
3748 /* 注册转发Hook */
3749 ret = hmac_register_netbuf_hook(&g_11k_netbuf_hook);
3750 if (ret != OAL_SUCC) {
3751 oam_error_log0(0, OAM_SF_RX, "{hmac_11k_init:: MGMT RX IN register_netbuf_hooks error!");
3752 return ret;
3753 }
3754
3755 return OAL_SUCC;
3756 }
3757
hmac_11k_deinit(osal_void)3758 osal_void hmac_11k_deinit(osal_void)
3759 {
3760 /* 去注册监听 */
3761 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_ADD_VAP, hmac_11k_add_vap);
3762 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_DEL_VAP, hmac_11k_del_vap);
3763 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_DOWN_VAP, hmac_11k_down_vap);
3764 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_ADD_USER, hmac_11k_add_user);
3765 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_11k_del_user);
3766 frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_SCAN_BEGIN, hmac_rrm_get_meas_start_time);
3767 /* 去注册消息 */
3768 frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_SEND_RADIO_MEAS_REQ);
3769 frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_SEND_RADIO_MEAS_RPT);
3770 /* 去注册对外接口 */
3771 hmac_feature_hook_unregister(HMAC_FHOOK_11K_STA_UPDATE_RRM_CAP);
3772 hmac_feature_hook_unregister(HMAC_FHOOK_11K_AP_UPDATE_RRM_CAP);
3773 hmac_feature_hook_unregister(HMAC_FHOOK_11K_SET_RRM_CAP);
3774 hmac_feature_hook_unregister(HMAC_FHOOK_11K_GET_TSF);
3775 hmac_feature_hook_unregister(HMAC_FHOOK_11K_UPDATE_BSS_LIST_RRM);
3776 hmac_feature_hook_unregister(HMAC_FHOOK_11K_SET_TSF);
3777 hmac_feature_hook_unregister(HMAC_FHOOK_GET_11K_CAP);
3778 /* 去注册转发Hook */
3779 hmac_unregister_netbuf_hook(&g_11k_netbuf_hook);
3780
3781 return;
3782 }
3783
3784 #ifdef __cplusplus
3785 #if __cplusplus
3786 }
3787 #endif
3788 #endif
3789