• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 /* ****************************************************************************
20   1 头文件包含
21 **************************************************************************** */
22 #include "wal_scan.h"
23 #include "wal_cfg80211.h"
24 #include "wal_main.h"
25 #include "wal_event.h"
26 #include "hmac_ext_if.h"
27 #include "frw_timer.h"
28 #include "wal_cfg80211_apt.h"
29 #include "hdf_wifi_event.h"
30 #include "hi_task.h"
31 #include "hi_wifi_driver_wpa_if.h"
32 #include "osal_mem.h"
33 
34 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
35 #ifndef _PRE_HDF_LINUX
36 #include <net/cfg80211.h>
37 #endif
38 #elif (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
39 #ifndef U64
40 #define U64 UINT64
41 #endif
42 #endif
43 
44 #ifdef __cplusplus
45 #if __cplusplus
46 extern "C" {
47 #endif
48 #endif
49 
50 /* ****************************************************************************
51   2 全局变量定义
52 **************************************************************************** */
53 /* ****************************************************************************
54   3 函数实现
55 **************************************************************************** */
56 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) || defined(_PRE_HDF_LINUX)
wal_free_scan_mgmt_resource(hmac_scan_stru * scan_mgmt)57 hi_void wal_free_scan_mgmt_resource(hmac_scan_stru *scan_mgmt)
58 {
59     if (scan_mgmt->request->ssids != HI_NULL) {
60         OsalMemFree(scan_mgmt->request->ssids);
61         scan_mgmt->request->ssids = HI_NULL;
62     }
63     if (scan_mgmt->request->ie != HI_NULL) {
64         OsalMemFree(scan_mgmt->request->ie);
65         scan_mgmt->request->ie = HI_NULL;
66     }
67     OsalMemFree(scan_mgmt->request);
68     scan_mgmt->request = HI_NULL;
69 }
70 #endif
71 
72 /* ****************************************************************************
73  函 数 名  : wal_inform_bss_frame
74  功能描述  : 逐个上报ssid消息给内核
75  输入参数  : 无
76  输出参数  : 无
77  返 回 值  :
78  调用函数  :
79  被调函数  :
80 
81  修改历史      :
82   1.日    期   : 2013年8月29日
83     作    者   : HiSilicon
84     修改内容   : 新生成函数
85 
86 **************************************************************************** */
wal_inform_bss_frame(const oal_net_device_stru * netdev,wal_scanned_bss_info_stru * scanned_bss_info,hi_void * data)87 static hi_void wal_inform_bss_frame(const oal_net_device_stru *netdev, wal_scanned_bss_info_stru *scanned_bss_info,
88     hi_void *data)
89 {
90 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
91     oal_cfg80211_bss_stru        *cfg80211_bss = HI_NULL;
92 #endif
93     oal_wiphy_stru               *wiphy = HI_NULL;
94     oal_ieee80211_channel_stru   *ieee80211_channel = HI_NULL;
95 
96 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
97 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0))
98     struct timespec ts;
99 #endif
100 #endif
101 
102     if ((scanned_bss_info == HI_NULL) || (data == HI_NULL)) {
103         oam_error_log2(0, OAM_SF_SCAN,
104             "{wal_inform_bss_frame::input param pointer is null, pst_scanned_bss_info[%p], p_data[%p]!}",
105             (uintptr_t)scanned_bss_info, (uintptr_t)data);
106         return;
107     }
108 
109     wiphy = (oal_wiphy_stru *)data;
110 
111     ieee80211_channel = oal_ieee80211_get_channel(wiphy, (hi_s32)scanned_bss_info->s_freq);
112     if (ieee80211_channel == HI_NULL) {
113         oam_warning_log1(0, OAM_SF_SCAN, "{wal_inform_bss_frame::get channel failed, wrong s_freq[%d]}",
114             (hi_s32)scanned_bss_info->s_freq);
115         return;
116     }
117 
118     scanned_bss_info->l_signal = scanned_bss_info->l_signal * 100; /* 100 扩大100倍 */
119 
120 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
121 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0))
122     /* 由于驱动缓存扫描结果,导致cts认证2次扫描的bss的timestamp时间一致(后一次没有扫描到) */
123     get_monotonic_boottime(&ts);
124     scanned_bss_info->mgmt->u.probe_resp.timestamp = ((hi_u64)ts.tv_sec * 1000000) /* 1000000 时间戳单位转换为s */
125         + ts.tv_nsec / 1000;                                                       /* 1000 时间戳单位转换为s */
126 #endif
127 #endif
128     /* 扫描维测 */
129     oam_info_log3(0, OAM_SF_SCAN, "{wal_inform_bss_frame::bssid:0x%x:XX:XX:XX:0x%x:0x%x}",
130         scanned_bss_info->mgmt->bssid[0], scanned_bss_info->mgmt->bssid[4], scanned_bss_info->mgmt->bssid[5]); /* 4 5 */
131 
132     /* 逐个上报内核bss 信息 */
133 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) || defined(_PRE_HDF_LINUX)
134     struct WlanChannel channel = {
135         .channelId = ieee80211_channel->hw_value,
136         .centerFreq = ieee80211_channel->center_freq,
137         .flags = ieee80211_channel->flags,
138     };
139     HdfWifiEventInformBssFrame(netdev, &channel, (struct ScannedBssInfo *)scanned_bss_info);
140 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
141     cfg80211_bss = oal_cfg80211_inform_bss_frame(wiphy, ieee80211_channel, scanned_bss_info->mgmt,
142         scanned_bss_info->mgmt_len, scanned_bss_info->l_signal, GFP_ATOMIC);
143 #endif
144 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) && !defined(_PRE_HDF_LINUX)
145     if (cfg80211_bss != NULL) {
146         /* cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) */
147         oal_cfg80211_put_bss(wiphy, cfg80211_bss);
148     }
149 #elif (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
150     /* liteos has no cfg80211_put_bss */
151 #endif
152 
153     return;
154 }
155 
156 /* ****************************************************************************
157  函 数 名  : wal_inform_all_bss
158  功能描述  : 上报所有的bss到内核
159  输入参数  : oal_wiphy_stru  *pst_wiphy,
160              hmac_bss_mgmt_stru  *pst_bss_mgmt,
161              hi_u8   uc_vap_id
162  输出参数  : 无
163  返 回 值  :
164  调用函数  :
165  被调函数  :
166 
167  修改历史      :
168   1.日    期   : 2015年7月8日
169     作    者   : HiSilicon
170     修改内容   : 新生成函数
171 
172 **************************************************************************** */
wal_inform_all_bss(const oal_net_device_stru * netdev,oal_wiphy_stru * wiphy,hmac_bss_mgmt_stru * bss_mgmt,hi_u8 vap_id)173 hi_void wal_inform_all_bss(const oal_net_device_stru *netdev, oal_wiphy_stru *wiphy, hmac_bss_mgmt_stru *bss_mgmt,
174     hi_u8 vap_id)
175 {
176     hi_list                   *entry = HI_NULL;
177     wal_scanned_bss_info_stru  scanned_bss_info;
178     hi_u32                     bss_num_not_in_regdomain = 0;
179 
180 #ifdef _PRE_WLAN_FEATURE_MESH
181     mac_vap_stru *mac_vap = mac_vap_get_vap_stru(vap_id);
182     if (mac_vap == HI_NULL) {
183         oam_error_log0(0, OAM_SF_SCAN, "{wal_inform_all_bss::mac_vap_get_vap_stru failed}");
184         return;
185     }
186 #else
187     hi_unref_param(vap_id);
188 #endif
189 
190     /* 获取锁 */
191     oal_spin_lock(&(bss_mgmt->st_lock));
192 
193     /* 遍历扫描到的bss信息 */
194     hi_list_for_each(entry, &(bss_mgmt->bss_list_head)) {
195         hmac_scanned_bss_info *scanned_bss = hi_list_entry(entry, hmac_scanned_bss_info, dlist_head);
196         hi_u8                  chan        = scanned_bss->bss_dscr_info.channel.chan_number;
197         enum ieee80211_band    band        = (enum ieee80211_band)scanned_bss->bss_dscr_info.channel.band;
198 
199         /* 判断信道是不是在管制域内,如果不在,则不上报内核 */
200         if (mac_is_channel_num_valid(band, chan) != HI_SUCCESS) {
201             oam_warning_log2(vap_id, OAM_SF_SCAN, "{wal_inform_all_bss::chan=%d,band=%d not in regdomain}", chan, band);
202             bss_num_not_in_regdomain++;
203             continue;
204         }
205 
206 #ifdef _PRE_WLAN_FEATURE_ANY
207         /* 支持ANY的设备进行扫描的时候,会把支持ANY的其他STA设备也扫描到,此时这些STA不应该上报内核,只上报AP */
208         if ((scanned_bss->bss_dscr_info.supp_any == HI_TRUE) && (scanned_bss->bss_dscr_info.is_any_sta == HI_TRUE)) {
209             continue;
210         }
211 #endif
212 
213         /* 安全编程规则6.6例外(1) 固定长度的结构体进行内存初始化 */
214         memset_s(&scanned_bss_info, sizeof(wal_scanned_bss_info_stru), 0, sizeof(wal_scanned_bss_info_stru));
215         scanned_bss_info.l_signal = scanned_bss->bss_dscr_info.rssi;
216 
217         /* 填bss所在信道的中心频率 */
218         scanned_bss_info.s_freq = (hi_s16)oal_ieee80211_channel_to_frequency(chan, band);
219 
220         /* 填管理帧指针和长度 */
221         scanned_bss_info.mgmt = (oal_ieee80211_mgmt_stru *)(scanned_bss->bss_dscr_info.auc_mgmt_buff);
222         scanned_bss_info.mgmt_len = scanned_bss->bss_dscr_info.mgmt_len;
223 
224         /* 获取上报的扫描结果的管理帧的帧头 */
225         mac_ieee80211_frame_stru *frame_hdr = (mac_ieee80211_frame_stru *)scanned_bss->bss_dscr_info.auc_mgmt_buff;
226 
227         /* 如果扫描请求接收到的帧类型有beacon类型,统一修改为probe rsp类型上报,
228            为了解决上报内核的扫描结果beacon帧不够敏感的问题,此问题,在01出现过 */
229         frame_hdr->frame_control.sub_type =
230             (frame_hdr->frame_control.sub_type == WLAN_BEACON) ? WLAN_PROBE_RSP : frame_hdr->frame_control.sub_type;
231 
232         /* 上报扫描结果给内核 */
233         /* 如果是mesh ap发起的扫描,只上报mesh ap */
234 #ifdef _PRE_WLAN_FEATURE_MESH
235         if (((mac_vap->vap_mode == WLAN_VAP_MODE_MESH) && (scanned_bss->bss_dscr_info.is_hisi_mesh == HI_TRUE)) ||
236             (mac_vap->vap_mode != WLAN_VAP_MODE_MESH)) {
237             wal_inform_bss_frame(netdev, &scanned_bss_info, wiphy);
238         }
239 #else
240         wal_inform_bss_frame(netdev, &scanned_bss_info, wiphy);
241 #endif
242     }
243 
244     /* 解除锁 */
245     oal_spin_unlock(&(bss_mgmt->st_lock));
246 
247     oam_warning_log2(vap_id, OAM_SF_SCAN, "{wal_inform_all_bss::%d bss not in regdomain,inform kernal bss num=%d}",
248         bss_num_not_in_regdomain, (bss_mgmt->bss_num - bss_num_not_in_regdomain));
249 }
250 
251 /* ****************************************************************************
252  函 数 名  : wal_free_scan_resource
253  功能描述  : 释放申请的信道信息资源
254  输入参数  : mac_cfg80211_scan_param_stru *
255  输出参数  : 无
256  返 回 值  :
257  调用函数  :
258  被调函数  :
259 
260  修改历史      :
261   1.日    期   : 2013年8月27日
262     作    者   : HiSilicon
263     修改内容   : 新生成函数
264 
265 **************************************************************************** */
wal_free_scan_resource(mac_cfg80211_scan_param_stru * scan_param)266 static hi_void wal_free_scan_resource(mac_cfg80211_scan_param_stru *scan_param)
267 {
268     if (scan_param->pul_channels_2_g != HI_NULL) {
269         oal_free(scan_param->pul_channels_2_g);
270         scan_param->pul_channels_2_g = HI_NULL;
271     }
272 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
273     if (scan_param->puc_ie != HI_NULL) {
274         oal_free((hi_u8 *)(scan_param->puc_ie));
275         scan_param->puc_ie = HI_NULL;
276     }
277 #endif
278     oal_mem_free(scan_param);
279 }
280 
281 /* ****************************************************************************
282  函 数 名  : wal_set_scan_channel
283  功能描述  : 提取内核下发扫描信道相关参数
284  输入参数  : 无
285  输出参数  : 无
286  返 回 值  :
287  调用函数  :
288  被调函数  :
289 
290  修改历史      :
291   1.日    期   : 2013年8月27日
292     作    者   : HiSilicon
293     修改内容   : 新生成函数
294 
295 **************************************************************************** */
wal_set_scan_channel(const oal_cfg80211_scan_request_stru * request,mac_cfg80211_scan_param_stru * scan_param)296 static hi_u32 wal_set_scan_channel(const oal_cfg80211_scan_request_stru *request,
297     mac_cfg80211_scan_param_stru *scan_param)
298 {
299     hi_u32 loop;
300     hi_u32 num_chan_2g = 0;
301 
302     if (request->n_channels == 0) {
303         oam_error_log0(0, OAM_SF_SCAN, "{wal_get_scan_channel_num::channel number is 0 in scan request, is wrong!}");
304         return HI_FAIL;
305     }
306 
307     scan_param->pul_channels_2_g = (hi_u32 *)oal_memalloc(request->n_channels * sizeof(hi_u32));
308     if (oal_unlikely(scan_param->pul_channels_2_g == HI_NULL)) {
309         oam_error_log0(0, OAM_SF_SCAN, "{wal_scan_work_func::memory is too low, fail to alloc for 2.4G channel!}");
310         return HI_ERR_CODE_ALLOC_MEM_FAIL;
311     }
312 
313     for (loop = 0; loop < request->n_channels; loop++) {
314         hi_u16  us_center_freq;
315         hi_u32  chn;
316 
317         us_center_freq = request->channels[loop]->center_freq;
318 
319         /* 根据中心频率,计算信道号 */
320         chn = (hi_u32)oal_ieee80211_frequency_to_channel((hi_s32)us_center_freq);
321 
322         if (us_center_freq <= WAL_MAX_FREQ_2G) {
323             scan_param->pul_channels_2_g[num_chan_2g++] = chn;
324         }
325     }
326 
327     scan_param->num_channels_2_g = (hi_u8)num_chan_2g;
328 
329     if (num_chan_2g == 0) {
330         oal_free(scan_param->pul_channels_2_g);
331         scan_param->pul_channels_2_g = HI_NULL;
332     }
333 
334     return HI_SUCCESS;
335 }
336 
337 /* ****************************************************************************
338  功能描述  : 设置扫描的SSID
339 
340  修改历史      :
341   1.日    期   : 2013年8月28日
342     作    者   : HiSilicon
343     修改内容   : 新生成函数
344 
345 **************************************************************************** */
wal_set_scan_ssid(const oal_cfg80211_scan_request_stru * request,mac_cfg80211_scan_param_stru * scan_param)346 static hi_void wal_set_scan_ssid(const oal_cfg80211_scan_request_stru *request,
347     mac_cfg80211_scan_param_stru *scan_param)
348 {
349     hi_u32 loop;
350     hi_u32 index = 0;
351     hi_u32 ssid_num;
352 
353     scan_param->l_ssid_num = 0;
354 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
355     if (request->prefix_ssid_scan_flag == HI_TRUE) {
356         scan_param->l_ssid_num = request->n_ssids;
357         return;
358     }
359 #endif
360 
361     /* 取内核下发的ssid的个数 */
362     ssid_num = (request->n_ssids > WLAN_SCAN_REQ_MAX_BSS) ? WLAN_SCAN_REQ_MAX_BSS : request->n_ssids;
363 
364     /* 将用户下发的ssid信息拷贝到对应的结构体中 */
365     if ((ssid_num == 0) || (request->ssids == HI_NULL)) {
366         return;
367     }
368 
369     for (loop = 0; loop < ssid_num; loop++) {
370         if (scan_param->ssids[index].ssid_len > OAL_IEEE80211_MAX_SSID_LEN) {
371             oam_warning_log2(0, OAM_SF_SCAN, "{wal_set_scan_ssid::ssid length [%d] is larger than %d, skip it.}",
372                 scan_param->ssids[loop].ssid_len, OAL_IEEE80211_MAX_SSID_LEN);
373             continue;
374         }
375         scan_param->ssids[index].ssid_len = request->ssids[loop].ssid_len;
376         if (memcpy_s(scan_param->ssids[index].auc_ssid, OAL_IEEE80211_MAX_SSID_LEN, request->ssids[loop].ssid,
377             scan_param->ssids[loop].ssid_len) != EOK) {
378             oam_warning_log0(0, OAM_SF_SCAN, "{wal_set_scan_ssid::fail to copy ssid to scan_param, skip it!}");
379             continue;
380         }
381         index++;
382     }
383 
384     scan_param->l_ssid_num = index;
385 }
386 
387 /* ****************************************************************************
388  功能描述  : 等待扫描完成超时处理函数
389 
390  修改历史      :
391   1.日    期   : 2015年5月19日
392     作    者   : HiSilicon
393     修改内容   : 新生成函数
394 
395 **************************************************************************** */
wal_wait_for_scan_timeout_fn(hi_void * arg)396 static hi_u32 wal_wait_for_scan_timeout_fn(hi_void *arg)
397 {
398     hmac_vap_stru                  *hmac_vap = (hmac_vap_stru *)arg;
399     mac_vap_stru                   *mac_vap  = hmac_vap->base_vap;
400     hmac_device_stru               *hmac_dev = HI_NULL;
401     mac_device_stru                *mac_dev = HI_NULL;
402     hmac_bss_mgmt_stru             *bss_mgmt = HI_NULL;
403     hmac_scan_stru                 *scan_mgmt = HI_NULL;
404     oal_wiphy_stru                 *wiphy = HI_NULL;
405     oal_net_device_stru            *netdev = HI_NULL;
406 
407     oam_warning_log0(mac_vap->vap_id, OAM_SF_SCAN, "{wal_wait_for_scan_timeout_fn:: 5 seconds scan timeout proc.}");
408 
409     /* 根据当前扫描的类型和当前vap的状态,决定切换vap的状态,扫描异常保护中,上报内核扫描状态为扫描完成 */
410     if ((mac_vap->vap_mode == WLAN_VAP_MODE_BSS_STA) && (mac_vap->vap_state == MAC_VAP_STATE_STA_WAIT_SCAN)) {
411         /* 改变vap状态到SCAN_COMP */
412         mac_vap_state_change(mac_vap, MAC_VAP_STATE_STA_SCAN_COMP);
413     }
414 
415     /* 获取hmac device */
416     hmac_dev   = hmac_get_device_stru();
417     mac_dev = mac_res_get_dev();
418     scan_mgmt  = &(hmac_dev->scan_mgmt);
419     wiphy      = mac_dev->wiphy;
420 
421     /* 获取net_device */
422     netdev = hmac_vap_get_net_device(mac_vap->vap_id);
423     if (netdev == HI_NULL) {
424         oam_error_log0(0, OAM_SF_ASSOC, "{wal_mesh_close_peer_inform::get net device ptr is null!}\r\n");
425 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) || defined(_PRE_HDF_LINUX)
426         oal_spin_lock(&(scan_mgmt->st_scan_request_spinlock));
427         wal_free_scan_mgmt_resource(scan_mgmt);
428         oal_spin_unlock(&(scan_mgmt->st_scan_request_spinlock));
429 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
430         scan_mgmt->request = HI_NULL;
431 #endif
432         scan_mgmt->complete = HI_TRUE;
433         scan_mgmt->is_scanning = HI_FALSE;
434         return HI_ERR_CODE_PTR_NULL;
435     }
436 
437     /* 获取扫描结果的管理结构地址 */
438     bss_mgmt = &(hmac_dev->scan_mgmt.scan_record_mgmt.bss_mgmt);
439 
440     /* 对于内核下发的扫描request资源加锁 */
441     oal_spin_lock(&(scan_mgmt->st_scan_request_spinlock));
442 
443     if (scan_mgmt->request != HI_NULL) {
444         /* 上报扫描到的所有的bss */
445         wal_inform_all_bss(netdev, wiphy, bss_mgmt, mac_vap->vap_id);
446 
447         /* 通知 kernel scan 已经结束 */
448 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) || defined(_PRE_HDF_LINUX)
449         HdfWifiEventScanDone(netdev, (WifiScanStatus)HISI_SCAN_TIMEOUT);
450         wal_free_scan_mgmt_resource(scan_mgmt);
451 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
452         oal_cfg80211_scan_done(scan_mgmt->request, 0);
453         scan_mgmt->request = HI_NULL;
454 #endif
455         scan_mgmt->complete = HI_TRUE;
456         scan_mgmt->is_scanning = HI_FALSE;
457     }
458 
459     /* 通知完内核,释放资源后解锁 */
460     oal_spin_unlock(&(scan_mgmt->st_scan_request_spinlock));
461 
462     return HI_SUCCESS;
463 }
464 
465 /* ****************************************************************************
466  函 数 名  : wal_process_timer_for_scan
467  功能描述  : 关闭扫描结果老化定时器,启动扫描定时器做扫描超时保护处理
468 
469  修改历史      :
470   1.日    期   : 2015年5月19日
471     作    者   : HiSilicon
472     修改内容   : 新生成函数
473 
474 **************************************************************************** */
wal_process_timer_for_scan(hi_u8 vap_id)475 static hi_void wal_process_timer_for_scan(hi_u8 vap_id)
476 {
477     hmac_vap_stru *hmac_vap = HI_NULL;
478 
479     /* 获取hmac vap */
480     hmac_vap = hmac_vap_get_vap_stru(vap_id);
481     if (hmac_vap == HI_NULL) {
482         oam_error_log0(vap_id, OAM_SF_SCAN, "{wal_process_timer_for_scan::pst_hmac_vap is null!}");
483         return;
484     }
485     /* 关闭扫描结果老化定时器 */
486     if (hmac_vap->scan_timeout.is_registerd == HI_TRUE) {
487         frw_timer_immediate_destroy_timer(&(hmac_vap->scanresult_clean_timeout));
488     }
489     /* 启动扫描保护定时器,在指定时间没有上报扫描结果,主动上报扫描完成 */
490     frw_timer_create_timer(&(hmac_vap->scan_timeout), wal_wait_for_scan_timeout_fn, WAL_MAX_SCAN_TIME_PER_SCAN_REQ,
491         hmac_vap, HI_FALSE);
492 
493     return;
494 }
495 
496 /* ****************************************************************************
497  函 数 名  : wal_start_scan_req
498  功能描述  : 解析内核下发扫描命令相关参数,启动扫描
499  输入参数  : 无
500  输出参数  : 无
501  返 回 值  :
502  调用函数  :
503  被调函数  :
504 
505  修改历史      :
506   1.日    期   : 2013年8月27日
507     作    者   : HiSilicon
508     修改内容   : 新生成函数
509 
510 **************************************************************************** */
wal_start_scan_req(oal_net_device_stru * netdev,hmac_scan_stru * scan_mgmt)511 hi_u32 wal_start_scan_req(oal_net_device_stru *netdev, hmac_scan_stru *scan_mgmt)
512 {
513     mac_cfg80211_scan_param_stru *scan_param = HI_NULL;
514     hi_u32                        ret;
515     mac_vap_stru                 *mac_vap = oal_net_dev_priv(netdev);
516     hi_u8                         vap_id = mac_vap->vap_id;
517     oal_cfg80211_scan_request_stru *request = scan_mgmt->request;
518 
519     scan_param =
520         (mac_cfg80211_scan_param_stru *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(mac_cfg80211_scan_param_stru));
521     if (scan_param == HI_NULL) {
522         oam_error_log0(0, OAM_SF_SCAN, "{wal_start_scan_req::memory is too low, fail to alloc scan param memory!}");
523         return HI_ERR_CODE_PTR_NULL;
524     }
525     /* 安全编程规则6.6例外(3)从堆中分配内存后,赋予初值 */
526     memset_s(scan_param, sizeof(mac_cfg80211_scan_param_stru), 0, sizeof(mac_cfg80211_scan_param_stru));
527 
528     /* 解析内核下发的扫描信道列表 */
529     if (wal_set_scan_channel(request, scan_param) != HI_SUCCESS) {
530         wal_free_scan_resource(scan_param);
531         return HI_FAIL;
532     }
533 
534     /* 解析内核下发的ssid */
535     wal_set_scan_ssid(request, scan_param);
536 
537     /* 解析内核下发的ie,        Mesh ID携带在IE段中 */
538     if ((request->ie_len > 0) && (request->ie != HI_NULL)) {
539 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
540         scan_param->puc_ie = (hi_u8 *)malloc(request->ie_len);
541         if (oal_unlikely(scan_param->puc_ie == HI_NULL)) {
542             oam_error_log0(0, OAM_SF_SCAN, "{wal_start_scan_req::memory is too low, fail to alloc for scan ie!}");
543             wal_free_scan_resource(scan_param);
544             return HI_FAIL;
545         }
546 
547         if (memcpy_s((hi_void *)(scan_param->puc_ie), request->ie_len, request->ie, request->ie_len) != EOK) {
548             oam_error_log0(0, OAM_SF_SCAN, "{wal_start_scan_req::fail to copy scan ie, return!}");
549             wal_free_scan_resource(scan_param);
550             return HI_FAIL;
551         }
552 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
553         scan_param->puc_ie = request->ie;
554 #endif
555 
556         scan_param->ie_len = request->ie_len;
557     } else {
558         scan_param->puc_ie = HI_NULL;
559         scan_param->ie_len = 0;
560     }
561 
562     scan_param->scan_type = OAL_ACTIVE_SCAN; /* active scan */
563 
564     /* P2P WLAN/P2P 特性情况下,根据扫描的ssid 判断是否为p2p device 发起的扫描,
565      * ssid 为"DIRECT-"则认为是p2p device 发起的扫描解析下发扫描的device 是否为p2p device(p2p0)
566      */
567     if (is_p2p_scan_req(request)) {
568         scan_param->is_p2p0_scan = HI_TRUE;
569     }
570 
571     /* 在事件前防止异步调度完成扫描后,发生同步问题 */
572     scan_mgmt->complete = HI_FALSE;
573 
574     /* 抛事件,通知驱动启动扫描 */
575     ret = wal_cfg80211_start_req(netdev, &scan_param, sizeof(uintptr_t), WLAN_CFGID_CFG80211_START_SCAN, HI_TRUE);
576     if (ret != HI_SUCCESS) {
577         wal_free_scan_resource(scan_param);
578         oal_cfg80211_scan_done(scan_mgmt->request, 0);
579         scan_mgmt->complete = HI_TRUE;
580         return HI_FAIL;
581     }
582     wal_free_scan_resource(scan_param);
583     /* 关闭扫描结果老化定时器,启动扫描超时定时器 */
584     wal_process_timer_for_scan(vap_id);
585 
586     return HI_SUCCESS;
587 }
588 
589 /* ****************************************************************************
590  函 数 名  : wal_send_scan_abort_msg
591  功能描述  : 终止扫描
592  输入参数  : oal_net_device_stru   *pst_net_dev
593  输出参数  : 无
594  返 回 值  : hi_s32
595  调用函数  :
596  被调函数  :
597 
598  修改历史      :
599   1.日    期   : 2015年7月8日
600     作    者   : HiSilicon
601     修改内容   : 新生成函数
602 
603 **************************************************************************** */
wal_send_scan_abort_msg(oal_net_device_stru * netdev)604 hi_u32 wal_send_scan_abort_msg(oal_net_device_stru *netdev)
605 {
606     wal_msg_write_stru              write_msg;
607     hi_u32                          pedding_data = 0;       /* 填充数据,不使用,只是为了复用接口 */
608     hi_u32                          ret;
609     wal_msg_stru                    *rsp_msg = HI_NULL;
610 
611     /* 拋事件通知device侧终止扫描 */
612     wal_write_msg_hdr_init(&write_msg, WLAN_CFGID_SCAN_ABORT, sizeof(pedding_data));
613 
614     if (memcpy_s(write_msg.auc_value, sizeof(pedding_data), (hi_s8 *)&pedding_data, sizeof(pedding_data)) != EOK) {
615         oam_error_log0(0, OAM_SF_SCAN, "{wal_send_scan_abort_msg::mem safe function err!}");
616         return HI_FAIL;
617     }
618 
619     ret = wal_send_cfg_event(netdev, WAL_MSG_TYPE_WRITE, WAL_MSG_WRITE_MSG_HDR_LENGTH + sizeof(pedding_data),
620         (hi_u8 *)&write_msg, HI_TRUE, &rsp_msg);
621     if (HI_SUCCESS != wal_check_and_release_msg_resp(rsp_msg)) {
622         oam_warning_log0(0, OAM_SF_SCAN, "{wal_send_scan_abort_msg::wal_check_and_release_msg_resp fail.}");
623     }
624 
625     if (ret != HI_SUCCESS) {
626         oam_warning_log1(0, OAM_SF_SCAN, "{wal_send_scan_abort_msg::fail to stop scan, error[%u]}", ret);
627     }
628 
629     return ret;
630 }
631 
632 /* ************** **************************************************************
633  函 数 名  : wal_force_scan_complete
634  功能描述  : 通知扫描完成
635  输入参数  : oal_net_device_stru   *pst_net_dev,
636              hi_bool          en_is_aborted
637  输出参数  : 无
638  返 回 值  : hi_s32
639  调用函数  :
640  被调函数  :
641 
642  修改历史      :
643   1.日    期   : 2015年7月8日
644     作    者   : HiSilicon
645     修改内容   : 新生成函数
646 
647 **************************************************************************** */
wal_force_scan_complete(oal_net_device_stru * netdev)648 hi_u32 wal_force_scan_complete(oal_net_device_stru *netdev)
649 {
650     mac_device_stru *mac_dev = mac_res_get_dev();
651 
652     mac_vap_stru *mac_vap = oal_net_dev_priv(netdev);
653     if (mac_vap == HI_NULL) {
654         oam_warning_log0(0, OAM_SF_SCAN, "{wal_force_scan_complete::Cannot find mac_vap by net_dev!}");
655         return HI_ERR_CODE_PTR_NULL;
656     }
657 
658     /* 获取hmac device */
659     hmac_device_stru *hmac_dev = hmac_get_device_stru();
660     /* stop的vap和正在扫描的vap不相同则直接返回 */
661     if (mac_vap->vap_id != hmac_dev->scan_mgmt.scan_record_mgmt.vap_id) {
662         oam_warning_log2(mac_vap->vap_id, OAM_SF_SCAN,
663             "{wal_force_scan_complete::stop_vap[%d] is different scan_vap[%d]!}", mac_vap->vap_id,
664             hmac_dev->scan_mgmt.scan_record_mgmt.vap_id);
665         return HI_SUCCESS;
666     }
667 
668     hmac_scan_stru *scan_mgmt = &(hmac_dev->scan_mgmt);
669 
670     /* 结束扫描的时候设置标志为非ANY扫描 */
671     scan_mgmt->scan_record_mgmt.is_any_scan = HI_FALSE;
672 
673     /* 如果是来自内部的扫描 */
674     if (scan_mgmt->request == HI_NULL) {
675         /* 判断是否存在内部扫描,如果存在,也需要停止 */
676         if ((hmac_dev->scan_mgmt.is_scanning == HI_TRUE) &&
677             (mac_vap->vap_id == hmac_dev->scan_mgmt.scan_record_mgmt.vap_id)) {
678             oam_warning_log0(mac_vap->vap_id, OAM_SF_SCAN, "{wal_force_scan_complete::maybe internal scan,stop scan}");
679             /* 终止扫描 */
680             wal_send_scan_abort_msg(netdev);
681         }
682 
683         return HI_SUCCESS;
684     }
685 
686     /* 获取hmac vap */
687     hmac_vap_stru *hmac_vap = hmac_vap_get_vap_stru(mac_vap->vap_id);
688     if (hmac_vap == HI_NULL) {
689         oam_warning_log1(mac_vap->vap_id, OAM_SF_SCAN, "{wal_force_scan_complete::hmac_vap is null, vap_id[%d]!}",
690             mac_vap->vap_id);
691         return HI_ERR_CODE_PTR_NULL;
692     }
693 
694     /* 删除等待扫描超时定时器 */
695     if (hmac_vap->scan_timeout.is_registerd == HI_TRUE) {
696         frw_timer_immediate_destroy_timer(&(hmac_vap->scan_timeout));
697     }
698 
699     /* 如果是上层下发的扫描请求,则通知内核扫描结束,内部扫描不需通知 */
700     if (scan_mgmt->request != HI_NULL) {
701         /* 对于内核下发的扫描request资源加锁 */
702         oal_spin_lock(&(scan_mgmt->st_scan_request_spinlock));
703 
704         /* 上报内核扫描结果 */
705         wal_inform_all_bss(netdev, mac_dev->wiphy, &(hmac_dev->scan_mgmt.scan_record_mgmt.bss_mgmt), mac_vap->vap_id);
706 
707         /* 通知内核扫描终止 */
708 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) || defined(_PRE_HDF_LINUX)
709         HdfWifiEventScanDone(netdev, (WifiScanStatus)HISI_SCAN_SUCCESS);
710         wal_free_scan_mgmt_resource(scan_mgmt);
711 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
712         oal_cfg80211_scan_done(scan_mgmt->request, HI_TRUE);
713         scan_mgmt->request = HI_NULL;
714 #endif
715         scan_mgmt->complete = HI_TRUE;
716 
717         /* 通知完内核,释放资源后解锁 */
718         oal_spin_unlock(&(scan_mgmt->st_scan_request_spinlock));
719 
720         /* 下发device终止扫描 */
721         wal_send_scan_abort_msg(netdev);
722 
723         oam_info_log1(mac_vap->vap_id, OAM_SF_SCAN, "{wal_force_scan_complete::force to stop scan of vap_id[%d]}",
724             mac_vap->vap_id);
725     }
726 
727     return HI_SUCCESS;
728 }
729 
730 #ifdef __cplusplus
731 #if __cplusplus
732 }
733 #endif
734 #endif
735