1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * 文 件 名 : hmac_roam_alg.c
15 * 生成日期 : 2015年3月18日
16 * 功能描述 : 漫游模块算法实现
17 */
18
19 /*****************************************************************************
20 1 头文件包含
21 *****************************************************************************/
22 #include "hmac_roam_alg.h"
23 #include "oam_ext_if.h"
24 #include "mac_ie.h"
25 #include "mac_device_ext.h"
26 #include "mac_resource_ext.h"
27 #include "hmac_fsm.h"
28 #include "hmac_sme_sta.h"
29 #include "hmac_resource.h"
30 #include "hmac_device.h"
31 #include "hmac_scan.h"
32 #include "hmac_roam_main.h"
33 #include "hmac_mgmt_sta.h"
34 #include "hmac_blacklist.h"
35 #include "dmac_ext_if_hcm.h"
36 #include "hmac_feature_interface.h"
37 #include "hmac_11v.h"
38
39 #ifdef __cplusplus
40 #if __cplusplus
41 extern "C" {
42 #endif
43 #endif
44
45 #undef THIS_FILE_ID
46 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_ROAM_ALG_C
47
48 #undef THIS_MOD_ID
49 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
50
51 /*****************************************************************************
52 2 全局变量定义
53 *****************************************************************************/
54 /*****************************************************************************
55 3 函数实现
56 *****************************************************************************/
57 /*****************************************************************************
58 功能描述 : roam alg初始化
59 *****************************************************************************/
hmac_roam_alg_init_etc(hmac_roam_info_stru * roam_info,osal_s8 c_current_rssi)60 osal_void hmac_roam_alg_init_etc(hmac_roam_info_stru *roam_info, osal_s8 c_current_rssi)
61 {
62 hmac_roam_alg_stru *roam_alg = OAL_PTR_NULL;
63
64 if (roam_info == OAL_PTR_NULL) {
65 oam_error_log0(0, OAM_SF_ROAM, "{hmac_roam_alg_init_etc::param null.}");
66 return;
67 }
68 oam_warning_log1(0, OAM_SF_ROAM, "{hmac_roam_alg_init_etc c_current_rssi = %d.}", c_current_rssi);
69
70 roam_alg = &(roam_info->alg);
71 if (c_current_rssi == ROAM_RSSI_LINKLOSS_TYPE) {
72 roam_info->st_static.trigger_linkloss_cnt++;
73 } else {
74 roam_info->st_static.trigger_rssi_cnt++;
75 }
76
77 roam_alg->max_capacity = 0;
78 roam_alg->max_capacity_bss = OAL_PTR_NULL;
79 roam_alg->c_current_rssi = c_current_rssi;
80 roam_alg->c_max_rssi = 0;
81 roam_alg->another_bss_scaned = 0;
82 /* 首次关联时初始化 roam_alg->invalid_scan_cnt = 0x0; */
83 roam_alg->max_rssi_bss = OAL_PTR_NULL;
84
85 return;
86 }
87
88 /*****************************************************************************
89 功能描述 : 调整rssi增益
90 *****************************************************************************/
hmac_roam_alg_adjust_rssi_increase(hmac_roam_info_stru * roam_info,mac_bss_dscr_stru * bss_dscr)91 OAL_STATIC osal_s8 hmac_roam_alg_adjust_rssi_increase(hmac_roam_info_stru *roam_info,
92 mac_bss_dscr_stru *bss_dscr)
93 {
94 osal_s8 c_current_rssi;
95 osal_s8 c_target_rssi;
96 osal_u8 delta_rssi;
97 osal_u8 flag = OSAL_FALSE;
98
99 if (bss_dscr->st_channel.band == WLAN_BAND_5G) {
100 delta_rssi = roam_info->config.delta_rssi_5g;
101 } else {
102 delta_rssi = roam_info->config.delta_rssi_2g;
103 }
104
105 c_current_rssi = roam_info->alg.c_current_rssi;
106 c_target_rssi = bss_dscr->c_rssi;
107
108 if (delta_rssi < ROAM_RSSI_DIFF_4_DB) {
109 delta_rssi = ROAM_RSSI_DIFF_4_DB;
110 }
111
112 if (c_current_rssi >= ROAM_RSSI_NE70_DB) {
113 flag = OSAL_TRUE;
114 goto out;
115 }
116
117 if (delta_rssi >= ROAM_RSSI_DIFF_4_DB + 2) { /* 2DB */
118 /* 步进2DB至4DB */
119 delta_rssi -= 2;
120 }
121
122 if (c_current_rssi >= ROAM_RSSI_NE75_DB) {
123 flag = OSAL_TRUE;
124 goto out;
125 }
126
127 if (delta_rssi >= ROAM_RSSI_DIFF_4_DB + 2) { /* 2DB */
128 /* 步进2DB至4DB */
129 delta_rssi -= 2;
130 }
131
132 if (c_current_rssi >= ROAM_RSSI_NE80_DB) {
133 flag = OSAL_TRUE;
134 goto out;
135 }
136
137 out:
138 oam_warning_log4(0, OAM_SF_ROAM,
139 "{hmac_roam_alg_adjust_rssi_increase::flag[%d] target_rssi[%d], current_rssi[%d], delta_rssi[%d].}",
140 flag, c_target_rssi, c_current_rssi, (osal_s8)delta_rssi);
141 return flag == OSAL_TRUE ? (c_target_rssi - c_current_rssi - (osal_s8)delta_rssi) :
142 (c_target_rssi - c_current_rssi - ROAM_RSSI_DIFF_4_DB);
143 }
144
145 /*****************************************************************************
146 功能描述 : 将bssid添加到列表中
147 *****************************************************************************/
hmac_roam_alg_add_bsslist(hmac_roam_bss_list_stru * roam_bss_list,osal_u8 * bssid,roam_blacklist_type_enum_uint8 list_type)148 OAL_STATIC osal_u32 hmac_roam_alg_add_bsslist(hmac_roam_bss_list_stru *roam_bss_list, osal_u8 *bssid,
149 roam_blacklist_type_enum_uint8 list_type)
150 {
151 hmac_roam_bss_info_stru *cur_bss = OAL_PTR_NULL;
152 osal_u8 mac_zero[WLAN_MAC_ADDR_LEN] = {0};
153 osal_u32 timeout, current_index;
154
155 hmac_roam_bss_info_stru *oldest_bss = OAL_PTR_NULL;
156 hmac_roam_bss_info_stru *zero_bss = OAL_PTR_NULL;
157 osal_u32 now = (osal_u32)oal_time_get_stamp_ms();
158
159 unref_param(list_type);
160
161 for (current_index = 0; current_index < ROAM_LIST_MAX; current_index++) {
162 cur_bss = &roam_bss_list->bss[current_index];
163 timeout = (osal_u32)cur_bss->timeout;
164 if (oal_compare_mac_addr(cur_bss->bssid, bssid) == 0) {
165 /* 优先查找已存在的记录,如果名单超时更新时间戳,否则更新count */
166 if (osal_get_runtime(cur_bss->time_stamp, now) > timeout) {
167 cur_bss->time_stamp = now;
168 cur_bss->count = 1;
169 return OAL_SUCC;
170 }
171 cur_bss->count++;
172 if (cur_bss->count == cur_bss->count_limit) {
173 cur_bss->time_stamp = now;
174 }
175 return OAL_SUCC;
176 }
177
178 /* 记录第一个空记录 */
179 if (zero_bss != OAL_PTR_NULL) {
180 continue;
181 }
182
183 if (oal_compare_mac_addr(cur_bss->bssid, (const osal_u8 *)mac_zero) == 0) {
184 zero_bss = cur_bss;
185 continue;
186 }
187
188 /* 记录一个非空最老记录 */
189 if (oldest_bss == OAL_PTR_NULL) {
190 oldest_bss = cur_bss;
191 } else if (osal_get_runtime(cur_bss->time_stamp, now) >
192 osal_get_runtime(oldest_bss->time_stamp, now)) {
193 oldest_bss = cur_bss;
194 }
195 }
196
197 if (zero_bss == OAL_PTR_NULL) {
198 zero_bss = oldest_bss;
199 }
200
201 if (zero_bss != OAL_PTR_NULL) {
202 oal_set_mac_addr(zero_bss->bssid, bssid);
203 zero_bss->time_stamp = now;
204 zero_bss->count = 1;
205 return OAL_SUCC;
206 }
207 return OAL_FAIL;
208 }
209
210 /*****************************************************************************
211 功能描述 : 检查列表中是否存在该bssid
212 *****************************************************************************/
hmac_roam_alg_find_in_bsslist(hmac_roam_bss_list_stru * roam_bss_list,osal_u8 * bssid)213 OAL_STATIC oal_bool_enum_uint8 hmac_roam_alg_find_in_bsslist(hmac_roam_bss_list_stru *roam_bss_list,
214 osal_u8 *bssid)
215 {
216 hmac_roam_bss_info_stru *cur_bss = OAL_PTR_NULL;
217 osal_u32 current_index;
218 osal_u32 now;
219 osal_u32 timeout;
220 osal_u32 delta_time;
221 osal_u16 count_limit;
222
223 now = (osal_u32)oal_time_get_stamp_ms();
224
225 for (current_index = 0; current_index < ROAM_LIST_MAX; current_index++) {
226 cur_bss = &roam_bss_list->bss[current_index];
227 timeout = cur_bss->timeout;
228 count_limit = cur_bss->count_limit;
229
230 if (oal_compare_mac_addr(cur_bss->bssid, bssid) == 0) {
231 /* 如果在超时时间内出现count_limit次以上记录 */
232 delta_time = osal_get_runtime(cur_bss->time_stamp, now);
233 if ((delta_time <= timeout) && (cur_bss->count >= count_limit)) {
234 return OAL_TRUE;
235 }
236 return OAL_FALSE;
237 }
238 }
239
240 return OAL_FALSE;
241 }
242
243 /*****************************************************************************
244 功能描述 : 将bssid添加到黑名单列表中
245 *****************************************************************************/
hmac_roam_alg_add_blacklist_etc(hmac_roam_info_stru * roam_info,osal_u8 * bssid,roam_blacklist_type_enum_uint8 list_type)246 osal_u32 hmac_roam_alg_add_blacklist_etc(hmac_roam_info_stru *roam_info, osal_u8 *bssid,
247 roam_blacklist_type_enum_uint8 list_type)
248 {
249 osal_u32 ul_ret;
250 if ((roam_info == OAL_PTR_NULL) || (bssid == OAL_PTR_NULL)) {
251 return OAL_ERR_CODE_PTR_NULL;
252 }
253
254 ul_ret = hmac_roam_alg_add_bsslist(&roam_info->alg.blacklist, bssid, list_type);
255 if (ul_ret != OAL_SUCC) {
256 oam_error_log1(0, OAM_SF_ROAM, "{hmac_roam_alg_add_blacklist_etc::hmac_roam_alg_add_list failed[%d].}", ul_ret);
257 return ul_ret;
258 }
259
260 oam_warning_log4(0, OAM_SF_ROAM, "{hmac_roam_alg_add_blacklist_etc:: bss[%02x:%02x:%02x:%02x:XX:XX]}",
261 bssid[0], bssid[1], bssid[2], bssid[3]); /* mac地址0/1/2/3 */
262 return OAL_SUCC;
263 }
264
265 /*****************************************************************************
266 功能描述 : 检查黑名单列表中是否存在该bssid
267 *****************************************************************************/
hmac_roam_alg_find_in_blacklist_etc(hmac_roam_info_stru * roam_info,osal_u8 * bssid)268 oal_bool_enum_uint8 hmac_roam_alg_find_in_blacklist_etc(hmac_roam_info_stru *roam_info, osal_u8 *bssid)
269 {
270 if ((roam_info == OAL_PTR_NULL) || (bssid == OAL_PTR_NULL)) {
271 return OAL_FALSE;
272 }
273
274 return hmac_roam_alg_find_in_bsslist(&roam_info->alg.blacklist, bssid);
275 }
276
277 /*****************************************************************************
278 功能描述 : 将bssid添加到历史优选AP列表中
279 *****************************************************************************/
hmac_roam_alg_add_history_etc(hmac_roam_info_stru * roam_info,osal_u8 * bssid)280 osal_u32 hmac_roam_alg_add_history_etc(hmac_roam_info_stru *roam_info, osal_u8 *bssid)
281 {
282 osal_u32 ul_ret;
283
284 if ((roam_info == OAL_PTR_NULL) || (bssid == OAL_PTR_NULL)) {
285 return OAL_ERR_CODE_PTR_NULL;
286 }
287
288 ul_ret = hmac_roam_alg_add_bsslist(&roam_info->alg.history, bssid, ROAM_BLACKLIST_TYPE_NORMAL_AP);
289 if (ul_ret != OAL_SUCC) {
290 oam_error_log1(0, OAM_SF_ROAM, "{hmac_roam_alg_add_history_etc::hmac_roam_alg_add_list failed[%d].}", ul_ret);
291 return ul_ret;
292 }
293
294 return OAL_SUCC;
295 }
296
hmac_roam_alg_fill_channel_list(mac_scan_req_stru * scan_params,osal_u8 index,osal_u8 chan_number,osal_u8 band,osal_u8 chan_idx)297 OAL_STATIC osal_void hmac_roam_alg_fill_channel_list(mac_scan_req_stru *scan_params, osal_u8 index,
298 osal_u8 chan_number, osal_u8 band, osal_u8 chan_idx)
299 {
300 scan_params->channel_list[index].chan_number = chan_number;
301 scan_params->channel_list[index].band = band;
302 scan_params->channel_list[index].chan_idx = chan_idx;
303 }
304
hmac_roam_alg_scan_orthogonal(const hmac_roam_info_stru * roam_info,mac_scan_req_stru * scan_params)305 OAL_STATIC osal_void hmac_roam_alg_scan_orthogonal(const hmac_roam_info_stru *roam_info,
306 mac_scan_req_stru *scan_params)
307 {
308 osal_u32 ret;
309 osal_u8 chan_idx;
310 osal_u8 chan_number;
311
312 switch (roam_info->config.scan_orthogonal) {
313 case ROAM_SCAN_CHANNEL_ORG_3:
314 hmac_roam_alg_fill_channel_list(scan_params, 0, 1, WLAN_BAND_2G, 0);
315
316 hmac_roam_alg_fill_channel_list(scan_params, 1, 6, WLAN_BAND_2G, 5); /* 6信道 5信道索引号 */
317
318 hmac_roam_alg_fill_channel_list(scan_params, 2, 11, WLAN_BAND_2G, 10); /* 元素2 11信道 10信道索引号 */
319
320 scan_params->channel_nums = 3; /* 扫描信道个数为3 */
321 break;
322 case ROAM_SCAN_CHANNEL_ORG_4:
323 hmac_roam_alg_fill_channel_list(scan_params, 0, 1, WLAN_BAND_2G, 0);
324
325 hmac_roam_alg_fill_channel_list(scan_params, 1, 5, WLAN_BAND_2G, 4); /* 5信道 4信道索引号 */
326
327 hmac_roam_alg_fill_channel_list(scan_params, 2, 7, WLAN_BAND_2G, 6); /* 数组元素2,7信道 6信道索引号 */
328
329 hmac_roam_alg_fill_channel_list(scan_params, 3, 13, WLAN_BAND_2G, 12); /* 元素3,13信道 12信道索引号 */
330
331 scan_params->channel_nums = 4; /* 扫描信道个数为4 */
332 break;
333 default:
334 for (chan_idx = 0; chan_idx < MAC_CHANNEL_FREQ_2_BUTT; chan_idx++) {
335 ret = hmac_is_channel_idx_valid_etc(WLAN_BAND_2G, chan_idx);
336 if (ret != OAL_SUCC) {
337 continue;
338 }
339 hmac_get_channel_num_from_idx_etc(WLAN_BAND_2G, chan_idx, &chan_number);
340 hmac_roam_alg_fill_channel_list(scan_params, scan_params->channel_nums, chan_number,
341 WLAN_BAND_2G, chan_idx);
342 scan_params->channel_nums++;
343 }
344 break;
345 }
346 }
347
hmac_roam_alg_scan_channel_init_etc(hmac_roam_info_stru * roam_info,mac_scan_req_stru * scan_params)348 osal_u32 hmac_roam_alg_scan_channel_init_etc(hmac_roam_info_stru *roam_info, mac_scan_req_stru *scan_params)
349 {
350 hmac_vap_stru *hmac_vap = OAL_PTR_NULL;
351 mac_channel_stru *channel = OAL_PTR_NULL;
352 #ifdef _PRE_WLAN_SUPPORT_5G
353 osal_u32 ul_ret;
354 osal_u8 chan_idx, chan_number;
355 #endif
356 osal_void *fhook = hmac_get_feature_fhook(HMAC_FHOOK_11V_SET_SCAN_PARAMS);
357
358 if ((roam_info == OAL_PTR_NULL) || (scan_params == OAL_PTR_NULL)) {
359 oam_error_log0(0, OAM_SF_ROAM, "{hmac_roam_alg_scan_channel_init_etc::param null.}");
360 return OAL_ERR_CODE_PTR_NULL;
361 }
362
363 hmac_vap = roam_info->hmac_vap;
364
365 channel = &(hmac_vap->channel);
366 scan_params->channel_nums = 0;
367
368 if (roam_info->config.scan_orthogonal == ROAM_SCAN_CHANNEL_ORG_1) {
369 oam_info_log3(0, OAM_SF_ROAM, "{scan one channel: ChanNum[%d], Band[%d], ChanIdx[%d]}",
370 channel->chan_number, channel->band, channel->chan_idx);
371
372 if (roam_info->roam_trigger != ROAM_TRIGGER_11V) {
373 hmac_roam_alg_fill_channel_list(scan_params, 0, channel->chan_number, channel->band, channel->chan_idx);
374 scan_params->channel_nums = 1;
375 return OAL_SUCC;
376 }
377
378 if (fhook != OSAL_NULL) {
379 ((hmac_11v_set_scan_params_cb)fhook)(scan_params, roam_info);
380 }
381 return OAL_SUCC;
382 }
383
384 if ((roam_info->config.scan_band & ROAM_BAND_2G_BIT) != 0) {
385 hmac_roam_alg_scan_orthogonal(roam_info, scan_params);
386 }
387 #ifdef _PRE_WLAN_SUPPORT_5G
388 if ((roam_info->config.scan_band & ROAM_BAND_5G_BIT) != 0) {
389 for (chan_idx = 0; chan_idx < MAC_CHANNEL_FREQ_5_BUTT; chan_idx++) {
390 ul_ret = hmac_is_channel_idx_valid_etc(WLAN_BAND_5G, chan_idx);
391 if (ul_ret != OAL_SUCC) {
392 continue;
393 }
394 hmac_get_channel_num_from_idx_etc(WLAN_BAND_5G, chan_idx, &chan_number);
395 hmac_roam_alg_fill_channel_list(scan_params, scan_params->channel_nums, chan_number,
396 WLAN_BAND_5G, chan_idx);
397 scan_params->channel_nums++;
398 }
399 }
400 #endif
401 return OAL_SUCC;
402 }
403
hmac_roam_alg_get_capacity_by_rssi(wlan_protocol_enum_uint8 protocol,wlan_bw_cap_enum_uint8 bw_cap,osal_s8 c_rssi)404 OAL_STATIC osal_u32 hmac_roam_alg_get_capacity_by_rssi(wlan_protocol_enum_uint8 protocol,
405 wlan_bw_cap_enum_uint8 bw_cap, osal_s8 c_rssi)
406 {
407 hmac_roam_rssi_capacity_stru *rssi_table = OAL_PTR_NULL;
408 osal_u8 index;
409 hmac_roam_rssi_capacity_stru rssi_tab_11b[ROAM_RSSI_LEVEL] = { {-88, 0, 81}, {-92, 0, 49}, {-94, 0, 9} };
410 hmac_roam_rssi_capacity_stru rssi_tab_11g_ofdm[ROAM_RSSI_LEVEL] = { {-75, 0, 293}, {-82, 0, 173}, {-90, 0, 54} };
411 hmac_roam_rssi_capacity_stru rssi_tab_11a_ofdm[ROAM_RSSI_LEVEL] = { {-75, 0, 293}, {-82, 0, 173}, {-90, 0, 54} };
412 hmac_roam_rssi_capacity_stru rssi_tab_ht20_ofdm[ROAM_RSSI_LEVEL] = { {-72, 0, 588}, {-80, 0, 353}, {-90, 0, 58} };
413 hmac_roam_rssi_capacity_stru rssi_tab_ht40_ofdm[ROAM_RSSI_LEVEL] = { {-75, 0, 1281}, {-77, 0, 705},
414 {-87, 0, 116} };
415 hmac_roam_rssi_capacity_stru rssi_tab_vht80_ofdm[ROAM_RSSI_LEVEL] = { {-72, 0, 2562}, {-74, 0, 1410},
416 {-84, 0, 232} };
417
418 switch (protocol) {
419 case WLAN_LEGACY_11A_MODE:
420 rssi_table = rssi_tab_11a_ofdm;
421 break;
422
423 case WLAN_LEGACY_11B_MODE:
424 rssi_table = rssi_tab_11b;
425 break;
426
427 case WLAN_LEGACY_11G_MODE:
428 case WLAN_MIXED_ONE_11G_MODE:
429 case WLAN_MIXED_TWO_11G_MODE:
430 rssi_table = rssi_tab_11g_ofdm;
431 break;
432
433 case WLAN_HT_MODE:
434 case WLAN_VHT_MODE:
435 if (bw_cap == WLAN_BW_CAP_20M) {
436 rssi_table = rssi_tab_ht20_ofdm;
437 } else if (bw_cap == WLAN_BW_CAP_40M) {
438 rssi_table = rssi_tab_ht40_ofdm;
439 } else {
440 rssi_table = rssi_tab_vht80_ofdm;
441 }
442 break;
443
444 default:
445 break;
446 }
447
448 if (rssi_table == OAL_PTR_NULL) {
449 return 0;
450 }
451
452 for (index = 0; index < ROAM_RSSI_LEVEL; index++) {
453 if (rssi_table[index].c_rssi <= c_rssi) {
454 /* capacity_kbps的单位是100Kb,此处乘以100,单位换算为kb */
455 return ((osal_u32)rssi_table[index].capacity_kbps * 100);
456 }
457 }
458
459 return 0;
460 }
461
hmac_roam_alg_calc_avail_channel_capacity(mac_bss_dscr_stru * bss_dscr)462 OAL_STATIC osal_u32 hmac_roam_alg_calc_avail_channel_capacity(mac_bss_dscr_stru *bss_dscr)
463 {
464 osal_u32 capacity;
465 osal_u32 avail_channel_cap;
466 osal_u32 ul_ret;
467 osal_u8 channel_utilization;
468 osal_u8 *obss_ie = OAL_PTR_NULL;
469 osal_u8 ie_offset;
470 wlan_protocol_enum_uint8 protocol;
471
472 ul_ret = hmac_sta_get_user_protocol_etc(bss_dscr, &protocol);
473 if (ul_ret != OAL_SUCC) {
474 return 0;
475 }
476 /***************************************************************************
477 ------------------------------------------------------------------------
478 |EID |Len |StationCount |ChannelUtilization |AvailableAdmissionCapacity|
479 ------------------------------------------------------------------------
480 |1 |1 |2 |1 |2 |
481 ------------------------------------------------------------------------
482 ***************************************************************************/
483 ie_offset = MAC_80211_FRAME_LEN + MAC_TIME_STAMP_LEN + MAC_BEACON_INTERVAL_LEN + MAC_CAP_INFO_LEN;
484 obss_ie = mac_find_ie_etc(MAC_EID_QBSS_LOAD, (osal_u8 *)(bss_dscr->mgmt_buff + ie_offset),
485 (osal_s32)(bss_dscr->mgmt_len - ie_offset));
486 /* 长度要到达ChannelUtilization这个域,至少为3 */
487 if (obss_ie && (obss_ie[1] >= 3)) {
488 channel_utilization = *(obss_ie + 4); /* +4:得到channel_utilization的初始地址 */
489 } else {
490 return 0;
491 }
492
493 capacity = hmac_roam_alg_get_capacity_by_rssi(protocol, bss_dscr->bw_cap, bss_dscr->c_rssi);
494
495 /* 文档规定信道利用率计算方法:normalized to 255 */
496 avail_channel_cap = capacity * (255 - channel_utilization) / 255 / ROAM_CONCURRENT_USER_NUMBER;
497
498 return avail_channel_cap;
499 }
500
501 /*****************************************************************************
502 功能描述 : 触发强信号漫游前,校验pmf能力位
503 *****************************************************************************/
hmac_roam_alg_bss_pmf_capa_check(hmac_vap_stru * hmac_vap,mac_bss_dscr_stru * bss_dscr)504 OAL_STATIC osal_u32 hmac_roam_alg_bss_pmf_capa_check(hmac_vap_stru *hmac_vap, mac_bss_dscr_stru *bss_dscr)
505 {
506 #ifdef _PRE_WLAN_FEATURE_PMF
507 osal_u16 rsn_cap_info = 0;
508 osal_bool pmf_cap;
509 osal_bool pmf_require;
510
511 if (bss_dscr->rsn_ie != OSAL_NULL) {
512 /* 获取目的AP的RSN CAP信息 */
513 rsn_cap_info = hmac_get_rsn_capability_etc(bss_dscr->rsn_ie);
514 }
515
516 /* 漫游时使用上次pmf能力位 并判断与漫游的目的ap能力位是否匹配 */
517 pmf_cap = mac_mib_get_dot11_rsnamfpc(hmac_vap);
518 pmf_require = mac_mib_get_dot11_rsnamfpr(hmac_vap);
519 if ((pmf_require == OSAL_TRUE) && ((rsn_cap_info & BIT7) == 0)) { /* 本地强制,对端没有MFP能力 */
520 oam_warning_log0(0, OAM_SF_CFG, "{hmac_roam_alg_bss_pmf_capa_check:: vap require pmf but ap don't have}");
521 return OAL_FAIL;
522 }
523 if ((pmf_cap == OSAL_FALSE) && ((rsn_cap_info & BIT6) != 0)) { /* 对端强制,本地没有MFP能力 */
524 oam_warning_log0(0, OAM_SF_CFG, "{hmac_roam_alg_bss_pmf_capa_check:: vap no pmf cap and ap required}");
525 return OAL_FAIL;
526 }
527 #endif
528
529 return OAL_SUCC;
530 }
531
hmac_roam_alg_bss_in_ess_etc(hmac_roam_info_stru * roam_info,mac_bss_dscr_stru * bss_dscr)532 osal_u32 hmac_roam_alg_bss_in_ess_etc(hmac_roam_info_stru *roam_info, mac_bss_dscr_stru *bss_dscr)
533 {
534 hmac_vap_stru *hmac_vap = OAL_PTR_NULL;
535 hmac_roam_alg_stru *roam_alg = OAL_PTR_NULL;
536 mac_cfg_ssid_param_stru cfg_ssid;
537 osal_u8 stru_len;
538 osal_u32 scan_expire_time, curr_time;
539
540 if ((roam_info == OAL_PTR_NULL) || (bss_dscr == OAL_PTR_NULL)) {
541 oam_error_log0(0, OAM_SF_ROAM, "{hmac_roam_alg_bss_in_ess_etc::param null.}");
542 return OAL_ERR_CODE_PTR_NULL;
543 }
544
545 hmac_vap = roam_info->hmac_vap;
546 if (hmac_vap == OAL_PTR_NULL) {
547 return OAL_ERR_CODE_ROAM_INVALID_VAP;
548 }
549
550 hmac_mib_get_ssid_etc(hmac_vap, &stru_len, (osal_u8 *)(&cfg_ssid));
551
552 if ((osal_strlen(bss_dscr->ac_ssid) != cfg_ssid.ssid_len) ||
553 (osal_memcmp(cfg_ssid.ac_ssid, bss_dscr->ac_ssid, cfg_ssid.ssid_len) != 0)) {
554 return OAL_SUCC;
555 }
556
557 /* 挑选 scan_expire_time 时间以内的有效bss */
558 scan_expire_time = (osal_u32)mac_is_dfs_channel(WLAN_BAND_5G, bss_dscr->st_channel.chan_number) == OAL_TRUE ?
559 HMAC_SCAN_MAX_VALID_SCANNED_DFS_EXPIRE : HMAC_SCAN_MAX_VALID_SCANNED_BSS_EXPIRE;
560 curr_time = (osal_u32)oal_time_get_stamp_ms();
561 if (oal_time_after((osal_ulong)curr_time, (osal_ulong)(bss_dscr->timestamp + scan_expire_time)) != 0) {
562 oam_warning_log4(0, OAM_SF_ROAM, "{hmac_roam_alg_bss_in_ess_etc:: bss[%02x:%02x:%02x:%02x:XX:XX]}",
563 bss_dscr->bssid[0], bss_dscr->bssid[1], bss_dscr->bssid[2], bss_dscr->bssid[3]); /* mac地址0/1/2/3 */
564 oam_warning_log2(0, OAM_SF_ROAM, "{hmac_roam_alg_bss_in_ess_etc::expire scan time %d ms, diff_time=%d}",
565 scan_expire_time, curr_time - bss_dscr->timestamp);
566 return OAL_SUCC;
567 }
568
569 /* pmf能力位校验不通过的,不漫游 */
570 if (hmac_roam_alg_bss_pmf_capa_check(hmac_vap, bss_dscr) != OAL_SUCC) {
571 return OAL_SUCC;
572 }
573
574 roam_alg = &(roam_info->alg);
575 /* 是否扫描到了当前关联的 bss, 仅置位,不过滤 */
576 if (oal_compare_mac_addr(hmac_vap->bssid, bss_dscr->bssid) != 0) {
577 roam_alg->another_bss_scaned = 1;
578
579 /* Roaming Scenario Recognition
580 * dense AP standard: RSSI>=-60dB, candidate num>=5;
581 * RSSI<-60dB && RSSI >=-75dB, candidate num>=10;
582 */
583 roam_alg->candidate_bss_num++;
584 if (bss_dscr->c_rssi >= roam_info->config.c_candidate_good_rssi) {
585 roam_alg->candidate_good_rssi_num++;
586 } else if ((bss_dscr->c_rssi < roam_info->config.c_candidate_good_rssi) &&
587 bss_dscr->c_rssi >= ROAM_RSSI_NE75_DB) {
588 roam_alg->candidate_weak_rssi_num++;
589 }
590
591 if (bss_dscr->c_rssi > roam_alg->c_max_rssi) {
592 roam_alg->c_max_rssi = bss_dscr->c_rssi;
593 }
594 } else {
595 roam_alg->c_current_rssi = bss_dscr->c_rssi;
596 }
597
598 return OAL_SUCC;
599 }
600
601 /*****************************************************************************
602 功能描述 : 校验加密相关 和 rssi
603 *****************************************************************************/
hmac_roam_alg_bss_check_privacy_and_rssi(hmac_roam_info_stru * roam_info,mac_bss_dscr_stru * bss_dscr,hmac_vap_stru * hmac_vap,hmac_roam_alg_stru * roam_alg)604 OAL_STATIC osal_u32 hmac_roam_alg_bss_check_privacy_and_rssi(hmac_roam_info_stru *roam_info,
605 mac_bss_dscr_stru *bss_dscr, hmac_vap_stru *hmac_vap, hmac_roam_alg_stru *roam_alg)
606 {
607 osal_u32 avail_channel_cap;
608 osal_s8 tmp_rssi;
609 osal_u8 *pmkid = OAL_PTR_NULL;
610 osal_s8 delta_rssi;
611 mac_cap_info_stru *cap_info = OAL_PTR_NULL;
612
613 if (roam_info->current_bss_ignore == OAL_FALSE) {
614 /* 排除当前bss的rssi值计算,本地已经保存了dmac上报的rssi */
615 if (oal_compare_mac_addr(hmac_vap->bssid, bss_dscr->bssid) == 0) {
616 return OAL_ERR_CODE_ROAM_NO_VALID_BSS;
617 }
618 }
619
620 /* wep的bss直接过滤掉 */
621 cap_info = (mac_cap_info_stru *)&bss_dscr->us_cap_info;
622 if ((bss_dscr->rsn_ie == OAL_PTR_NULL) && (bss_dscr->wpa_ie == OAL_PTR_NULL) &&
623 (cap_info->privacy != 0)) {
624 return OAL_ERR_CODE_ROAM_NO_VALID_BSS;
625 }
626
627 /* open加密方式到wpa/wpa2直接过滤掉 */
628 if ((cap_info->privacy == 0) != (mac_mib_get_privacyinvoked(hmac_vap) != OAL_TRUE)) {
629 return OAL_ERR_CODE_ROAM_NO_VALID_BSS;
630 }
631
632 /* c_current_rssi为0时,表示linkloss上报的触发,不需要考虑rssi增益 */
633 delta_rssi = hmac_roam_alg_adjust_rssi_increase(roam_info, bss_dscr);
634 if (delta_rssi <= 0) {
635 return OAL_ERR_CODE_ROAM_NO_VALID_BSS;
636 }
637
638 avail_channel_cap = hmac_roam_alg_calc_avail_channel_capacity(bss_dscr);
639 if ((avail_channel_cap != 0) && ((roam_alg->max_capacity_bss == OAL_PTR_NULL) ||
640 (avail_channel_cap > roam_alg->max_capacity))) {
641 /* 暂时不考虑容量 */
642 }
643
644 tmp_rssi = bss_dscr->c_rssi;
645 /* 对于已存在pmk缓存的bss进行加分处理 */
646 pmkid = hmac_vap_get_pmksa_etc(hmac_vap, bss_dscr->bssid);
647 if (pmkid != OAL_PTR_NULL) {
648 tmp_rssi += ROAM_RSSI_DIFF_4_DB;
649 }
650
651 if (bss_dscr->st_channel.band == WLAN_BAND_5G) {
652 tmp_rssi += ROAM_RSSI_DIFF_4_DB; /* 5G AP have 4dB weight for higher priority */
653 }
654
655 if ((roam_alg->max_rssi_bss == OAL_PTR_NULL) || (tmp_rssi > roam_alg->c_max_rssi)) {
656 roam_alg->c_max_rssi = tmp_rssi;
657 roam_alg->max_rssi_bss = bss_dscr;
658 }
659
660 return OAL_SUCC;
661 }
662
663 /*****************************************************************************
664 功能描述 : 检查
665 *****************************************************************************/
hmac_roam_alg_bss_check_etc(hmac_roam_info_stru * roam_info,mac_bss_dscr_stru * bss_dscr)666 osal_u32 hmac_roam_alg_bss_check_etc(hmac_roam_info_stru *roam_info, mac_bss_dscr_stru *bss_dscr)
667 {
668 hmac_vap_stru *hmac_vap = OAL_PTR_NULL;
669 hmac_roam_alg_stru *roam_alg = OAL_PTR_NULL;
670 mac_cfg_ssid_param_stru cfg_ssid;
671 osal_u32 ret;
672 osal_u8 stru_len;
673 osal_void *fhook;
674
675 if ((roam_info == OAL_PTR_NULL) || (bss_dscr == OAL_PTR_NULL)) {
676 oam_error_log0(0, OAM_SF_ROAM, "{hmac_roam_alg_bss_check_etc::param null.}");
677 return OAL_ERR_CODE_PTR_NULL;
678 }
679
680 hmac_vap = roam_info->hmac_vap;
681 if (hmac_vap == OAL_PTR_NULL) {
682 return OAL_ERR_CODE_ROAM_INVALID_VAP;
683 }
684
685 hmac_mib_get_ssid_etc(hmac_vap, &stru_len, (osal_u8 *)(&cfg_ssid));
686
687 if ((osal_strlen(bss_dscr->ac_ssid) != cfg_ssid.ssid_len) ||
688 (osal_memcmp(cfg_ssid.ac_ssid, bss_dscr->ac_ssid, cfg_ssid.ssid_len) != 0)) {
689 return OAL_ERR_CODE_ROAM_NO_VALID_BSS;
690 }
691 roam_alg = &(roam_info->alg);
692
693 if (roam_info->current_bss_ignore == OAL_FALSE) {
694 if (oal_time_after((osal_ulong)oal_time_get_stamp_ms(),
695 (osal_ulong)(bss_dscr->timestamp + HMAC_SCAN_MAX_VALID_SCANNED_BSS_EXPIRE)) != 0) {
696 return OAL_ERR_CODE_ROAM_NO_VALID_BSS;
697 }
698 }
699
700 /* 检查黑名单 */
701 ret = hmac_roam_alg_find_in_blacklist_etc(roam_info, bss_dscr->bssid);
702 if (ret == OAL_TRUE) {
703 oam_warning_log4(0, OAM_SF_ROAM, "{hmac_roam_alg_bss_check_etc:: [%02X:%02X:%02X:%02X:XX:XX] in blacklist!}",
704 /* 打印mac的第0位,第1位,第2位,第3位 */
705 bss_dscr->bssid[0], bss_dscr->bssid[1], bss_dscr->bssid[2], bss_dscr->bssid[3]);
706 return OAL_ERR_CODE_ROAM_NO_VALID_BSS;
707 }
708
709 /* check bssid blacklist from Framework setting */
710 fhook = hmac_get_feature_fhook(HMAC_FHOOK_BLACKLIST_FILTER_ETC);
711 if (fhook != OSAL_NULL) {
712 ret = ((hmac_blacklist_filter_etc_cb)fhook)(hmac_vap, bss_dscr->bssid);
713 if (ret == OAL_TRUE) {
714 return OAL_ERR_CODE_ROAM_NO_VALID_BSS;
715 }
716 }
717
718 return hmac_roam_alg_bss_check_privacy_and_rssi(roam_info, bss_dscr, hmac_vap, roam_alg);
719 }
720
hmac_roam_alg_need_to_stop_roam_trigger_etc(hmac_roam_info_stru * roam_info)721 oal_bool_enum_uint8 hmac_roam_alg_need_to_stop_roam_trigger_etc(hmac_roam_info_stru *roam_info)
722 {
723 hmac_vap_stru *hmac_vap = OAL_PTR_NULL;
724 hmac_roam_alg_stru *roam_alg = OAL_PTR_NULL;
725
726 if (roam_info == OAL_PTR_NULL) {
727 return OAL_FALSE;
728 }
729
730 hmac_vap = roam_info->hmac_vap;
731 if (hmac_vap == OAL_PTR_NULL) {
732 return OAL_FALSE;
733 }
734
735 roam_alg = &(roam_info->alg);
736
737 if (roam_alg->another_bss_scaned == OSAL_TRUE) {
738 roam_alg->invalid_scan_cnt = 0xff;
739 return OAL_FALSE;
740 }
741
742 if (roam_alg->invalid_scan_cnt == 0xff) {
743 return OAL_FALSE;
744 }
745
746 if (roam_alg->invalid_scan_cnt++ > 4) { /* 最大次数为4 */
747 roam_alg->invalid_scan_cnt = 0xff;
748 return OAL_TRUE;
749 }
750
751 return OAL_FALSE;
752 }
753
hmac_roam_alg_select_bss_etc(hmac_roam_info_stru * roam_info)754 mac_bss_dscr_stru *hmac_roam_alg_select_bss_etc(hmac_roam_info_stru *roam_info)
755 {
756 hmac_vap_stru *hmac_vap = OAL_PTR_NULL;
757 mac_bss_dscr_stru *bss_dscr = OAL_PTR_NULL;
758 hmac_roam_alg_stru *roam_alg = OAL_PTR_NULL;
759 osal_s8 c_delta_rssi;
760 osal_s8 c_max_rssi = 0;
761
762 if (roam_info == OAL_PTR_NULL) {
763 return OAL_PTR_NULL;
764 }
765
766 hmac_vap = roam_info->hmac_vap;
767 if (hmac_vap == OAL_PTR_NULL) {
768 return OAL_PTR_NULL;
769 }
770
771 roam_alg = &(roam_info->alg);
772
773 /* 取得最大 rssi 的 bss */
774 bss_dscr = roam_alg->max_rssi_bss;
775
776 if ((roam_alg->max_capacity_bss != OAL_PTR_NULL) &&
777 (roam_alg->max_capacity >= ROAM_THROUGHPUT_THRESHOLD)) {
778 /* 取得最大 capacity 的 bss */
779 bss_dscr = roam_alg->max_capacity_bss;
780 }
781
782 if (bss_dscr == OAL_PTR_NULL) {
783 /* should not be here */
784 return OAL_PTR_NULL;
785 }
786
787 if (roam_info->current_bss_ignore == OAL_FALSE) {
788 /* 过滤当前关联的 bss */
789 if (oal_compare_mac_addr(hmac_vap->bssid, bss_dscr->bssid) == 0) {
790 return OAL_PTR_NULL;
791 }
792 }
793
794 /* rssi增益处理 */
795 c_delta_rssi = hmac_roam_alg_adjust_rssi_increase(roam_info, bss_dscr);
796 if (c_delta_rssi <= 0) {
797 return OAL_PTR_NULL;
798 }
799 c_max_rssi = roam_alg->c_max_rssi;
800 #ifdef _PRE_WLAN_SUPPORT_5G
801 if (bss_dscr->st_channel.band == WLAN_BAND_5G) {
802 c_max_rssi = roam_alg->c_max_rssi - ROAM_RSSI_DIFF_4_DB;
803 }
804 #endif
805 oam_warning_log2(0, OAM_SF_ROAM, "hmac_roam_alg_select_bss:roam_to candidate AP, band=%d(0:2.4G,1:5G) max_rssi=%d",
806 bss_dscr->st_channel.band, c_max_rssi);
807 oam_warning_log4(0, OAM_SF_ROAM, "{hmac_roam_alg_select_bss::[%02X:%02X:%02X:%02X:XX:XX]}",
808 /* 0:1:2:3:数组下标 */
809 bss_dscr->bssid[0], bss_dscr->bssid[1], bss_dscr->bssid[2], bss_dscr->bssid[3]);
810
811 return bss_dscr;
812 }
813
814 #ifdef __cplusplus
815 #if __cplusplus
816 }
817 #endif
818 #endif
819