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 * Description: wps feature file
15 */
16
17 /*****************************************************************************
18 1 头文件包含
19 *****************************************************************************/
20 #include "hmac_wps.h"
21
22 #ifdef __cplusplus
23 #if __cplusplus
24 extern "C" {
25 #endif
26 #endif
27
28 #undef THIS_FILE_ID
29 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_WPS_C
30
31 #undef THIS_MOD_ID
32 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
33
34 /*****************************************************************************
35 2 全局变量定义
36 *****************************************************************************/
37
38 /*****************************************************************************
39 3 函数实现
40 *****************************************************************************/
41
42 /*****************************************************************************
43 函 数 名 : hmac_config_set_wps_p2p_ie_etc
44 功能描述 : mp02 设置WPS/P2P 信息元素
45 输入参数 : hmac_vap_stru *hmac_vap
46 osal_u16 len
47 osal_u8 *param
48 输出参数 : 无
49 *****************************************************************************/
hmac_config_set_wps_p2p_ie_etc(hmac_vap_stru * hmac_vap,frw_msg * msg)50 OAL_STATIC osal_s32 hmac_config_set_wps_p2p_ie_etc(hmac_vap_stru *hmac_vap, frw_msg *msg)
51 {
52 oal_w2h_app_ie_stru *w2h_wps_p2p_ie;
53 oal_app_ie_stru app_ie;
54 osal_u32 ul_ret;
55
56 w2h_wps_p2p_ie = (oal_w2h_app_ie_stru *)msg->data;
57
58 if ((w2h_wps_p2p_ie->app_ie_type >= OAL_APP_IE_NUM) ||
59 (w2h_wps_p2p_ie->ie_len >= WLAN_WPS_IE_MAX_SIZE)) {
60 oam_warning_log3(0, OAM_SF_CFG,
61 "vap_id[%d] {hmac_config_set_wps_p2p_ie_etc::app_ie_type=[%d] app_ie_len=[%d],param invalid.}",
62 hmac_vap->vap_id,
63 w2h_wps_p2p_ie->app_ie_type, w2h_wps_p2p_ie->ie_len);
64 return OAL_FAIL;
65 }
66
67 oam_warning_log3(0, OAM_SF_CFG, "vap_id[%d] {hmac_config_set_wps_p2p_ie_etc::p2p_ie_type=[%d], p2p_ie_len=[%d].}",
68 hmac_vap->vap_id,
69 w2h_wps_p2p_ie->app_ie_type, w2h_wps_p2p_ie->ie_len);
70
71 memset_s(&app_ie, OAL_SIZEOF(app_ie), 0, OAL_SIZEOF(app_ie));
72 app_ie.app_ie_type = w2h_wps_p2p_ie->app_ie_type;
73 app_ie.ie_len = w2h_wps_p2p_ie->ie_len;
74 if (memcpy_s(app_ie.ie, sizeof(app_ie.ie), w2h_wps_p2p_ie->data_ie, app_ie.ie_len) != EOK) {
75 oam_error_log0(0, OAM_SF_ANY, "{hmac_config_set_wps_p2p_ie_etc::memcpy_s error}");
76 }
77
78 /* 设置WPS/P2P 信息 */
79 ul_ret = hmac_config_set_app_ie_to_vap_etc(hmac_vap, &app_ie, app_ie.app_ie_type);
80 if (ul_ret != OAL_SUCC) {
81 return (osal_s32)ul_ret;
82 }
83
84 /* 检测beacon 信息中是否有WPS 信息元素 */
85 if (app_ie.app_ie_type == OAL_APP_BEACON_IE) {
86 if ((app_ie.ie_len != 0) &&
87 hmac_find_vendor_ie_etc(MAC_WLAN_OUI_MICROSOFT, MAC_WLAN_OUI_TYPE_MICROSOFT_WPS,
88 app_ie.ie, (osal_s32)(app_ie.ie_len)) != OAL_PTR_NULL) {
89 /* 设置WPS 功能使能 */
90 mac_mib_set_WPSActive(hmac_vap, OAL_TRUE);
91 oam_info_log1(0, OAM_SF_CFG, "vap_id[%d] {hmac_config_set_wps_p2p_ie_etc::set wps enable.}",
92 hmac_vap->vap_id);
93 } else {
94 mac_mib_set_WPSActive(hmac_vap, OAL_FALSE);
95 }
96 }
97
98 return (osal_s32)ul_ret;
99 }
100
101 /*****************************************************************************
102 函 数 名 : hmac_config_set_wps_ie_etc
103 功能描述 : AP 设置WPS 信息元素
104 输入参数 : hmac_vap_stru *hmac_vap
105 osal_u16 len
106 osal_u8 *param
107 输出参数 : 无
108 *****************************************************************************/
hmac_config_set_wps_ie_etc(hmac_vap_stru * hmac_vap,frw_msg * msg)109 OAL_STATIC osal_s32 hmac_config_set_wps_ie_etc(hmac_vap_stru *hmac_vap, frw_msg *msg)
110 {
111 oal_app_ie_stru *wps_ie;
112 osal_u8 *ie;
113 osal_u32 ret;
114
115 wps_ie = (oal_app_ie_stru *)msg->data;
116
117 /* 设置WPS 信息 */
118 ret = hmac_config_set_app_ie_to_vap_etc(hmac_vap, wps_ie, wps_ie->app_ie_type);
119 if (ret != OAL_SUCC) {
120 oam_warning_log2(0, OAM_SF_CFG,
121 "vap_id[%d] {hmac_config_set_wps_ie_etc::ret=[%d].}", hmac_vap->vap_id, ret);
122 return (osal_s32)ret;
123 }
124
125 /* 检测beacon 信息中是否有WPS 信息元素 */
126 if ((wps_ie->app_ie_type == OAL_APP_BEACON_IE) && (wps_ie->ie_len != 0)) {
127 ie = hmac_find_vendor_ie_etc(MAC_WLAN_OUI_MICROSOFT, MAC_WLAN_OUI_TYPE_MICROSOFT_WPS,
128 wps_ie->ie, (osal_s32)(wps_ie->ie_len));
129 if (ie != OAL_PTR_NULL) {
130 /* 设置WPS 功能使能 */
131 mac_mib_set_WPSActive(hmac_vap, OAL_TRUE);
132 oam_info_log1(0, OAM_SF_CFG, "vap_id[%d] {hmac_config_set_wps_ie_etc::set wps enable.}",
133 hmac_vap->vap_id);
134 }
135 } else if ((wps_ie->ie_len == 0) && (wps_ie->app_ie_type == OAL_APP_BEACON_IE)) {
136 mac_mib_set_WPSActive(hmac_vap, OAL_FALSE);
137 oam_info_log1(0, OAM_SF_CFG, "vap_id[%d] {hmac_config_set_wps_ie_etc::set wps disable.}",
138 hmac_vap->vap_id);
139 }
140
141 return (osal_s32)ret;
142 }
143
144 /*****************************************************************************
145 功能描述 : 查找WPS attribute信息元素
146 *****************************************************************************/
hmac_find_wps_attribute_etc(osal_u16 eid,osal_u8 * ies,osal_s32 len)147 OAL_STATIC osal_u8 *hmac_find_wps_attribute_etc(osal_u16 eid, osal_u8 *ies, osal_s32 len)
148 {
149 osal_s32 ie_len;
150
151 if (ies == OSAL_NULL) {
152 return OSAL_NULL;
153 }
154
155 /* 查找WPS attribute, 如果不是直接找下一个, 属性中 eid 两个字节, len 两个字节 */
156 while (len > MAC_WPS_ATTRIBUTE_HDR_LEN && ((ies[0] << 8) + ies[1]) != eid) { /* 8: 1 Byte; 小端, 0,1 字节 */
157 ie_len = (osal_s32)((ies[2] << 8) + ies[3]); /* 8: 1 Byte; 小端, 2,3 字节 */
158 len -= ie_len + MAC_WPS_ATTRIBUTE_HDR_LEN;
159 ies += ie_len + MAC_WPS_ATTRIBUTE_HDR_LEN;
160 }
161
162 /* 查找到WPS attribute,剩余长度不匹配直接返回空指针 */
163 if ((len <= MAC_WPS_ATTRIBUTE_HDR_LEN) ||
164 (len < (MAC_WPS_ATTRIBUTE_HDR_LEN + (osal_s32)((ies[2] << 8) + ies[3]))) || /* 8: 1 Byte; 小端, 2,3 字节 */
165 ((len == MAC_WPS_ATTRIBUTE_HDR_LEN) && (((ies[0] << 8) + ies[1]) != eid))) { /* 8: 1 Byte; 小端, 0,1 字节 */
166 return OSAL_NULL;
167 }
168
169 return ies;
170 }
171
hmac_scan_check_wps_status(hmac_vap_stru * hmac_vap,osal_u32 len,osal_u8 * ie,osal_u8 * type)172 OAL_STATIC osal_u32 hmac_scan_check_wps_status(hmac_vap_stru *hmac_vap, osal_u32 len, osal_u8 *ie, osal_u8 *type)
173 {
174 osal_u8 *wps_ie = OAL_PTR_NULL;
175 osal_u8 *request_type_attr = OAL_PTR_NULL;
176
177 /* 查找WPS IE信息 */
178 wps_ie = hmac_find_vendor_ie_etc(MAC_WLAN_OUI_MICROSOFT, MAC_WLAN_OUI_TYPE_MICROSOFT_WPS, ie, (osal_s32)len);
179 if ((wps_ie == OSAL_NULL) || (wps_ie[1] < MAC_MIN_WPS_IE_LEN)) {
180 oam_warning_log2(0, OAM_SF_CFG, "vap_id[%d] {hmac_scan_check_wps_status::wps_ie len %d invalid.}",
181 hmac_vap->vap_id, (wps_ie == OSAL_NULL) ? 0xff : wps_ie[1]);
182 return OAL_ERR_CODE_PTR_NULL;
183 }
184
185 /* 查找WPS request type attribute 信息 */
186 request_type_attr = hmac_find_wps_attribute_etc(MAC_WPS_ATTRIBUTE_REQUEST_TYPE,
187 wps_ie + WPS_IE_HDR_LEN, (wps_ie[1] - 4)); /* 跳过4个字节, MAC_MIN_WPS_IE_LEN 是否该定义为4? */
188 if (request_type_attr == OAL_PTR_NULL) {
189 oam_warning_log2(0, OAM_SF_CFG, "vap_id[%d] {hmac_scan_check_wps_status::not find request type, wps_ie[1] %d.}",
190 hmac_vap->vap_id, wps_ie[1]);
191 return OAL_ERR_CODE_PTR_NULL;
192 }
193
194 /* request_type_attr 长度校验, 小端, 2进制高位左移8位切换为10进制, 2,3下标 */
195 if (((request_type_attr[2] << 8) + request_type_attr[3]) != MAC_WPS_REQUEST_TYPE_ATTR_LEN) {
196 oam_warning_log2(0, OAM_SF_CFG, "vap_id[%d] {hmac_scan_check_wps_status::invalid request type ie len[%d].}",
197 /* 2进制高位左移8位切换为10进制, 2,3下标 */
198 hmac_vap->vap_id, (osal_s32)((request_type_attr[2] << 8) + request_type_attr[3]));
199 return OAL_FAIL;
200 }
201
202 /* 获取 request_type_attr 信息 */
203 *type = request_type_attr[4]; /* 4 下标 */
204 oam_info_log3(0, OAM_SF_CFG, "vap[%d]hmac_scan_check_wps_status:type[%d] len[%d]",
205 hmac_vap->vap_id, *type, wps_ie[1]);
206
207 return OAL_SUCC;
208 }
209
210 /*****************************************************************************
211 函 数 名 : hmac_config_del_ie
212 功能描述 : 删除wpa_supplicant 下发的IE 中的指定 IE
213 输入参数 : osal_u8 ie_type 需要删除的ie类型
214 osal_u8 *ie_buf wpa_supplicant 下发的ie
215 osal_u32 *ie_buf_len wpa_supplicant 下发的ie 长度
216 输出参数 : 无
217 *****************************************************************************/
hmac_config_del_ie(osal_u8 ie_type,osal_u8 * ie_buf,osal_u32 * ie_buf_len)218 OAL_STATIC osal_void hmac_config_del_ie(osal_u8 ie_type, osal_u8 *ie_buf, osal_u32 *ie_buf_len)
219 {
220 osal_u8 *del_ie_buf = OSAL_NULL;
221 osal_u8 *ie_buf_end = OSAL_NULL;
222 osal_u8 *del_ie_end = OSAL_NULL;
223 osal_u32 i, del_ie_buf_len;
224
225 mac_ie_oui_stru mac_wlan_ie_oui[] = {
226 {MAC_P2P_IE, MAC_WLAN_OUI_WFA, MAC_WLAN_OUI_TYPE_WFA_P2P},
227 {MAC_WPS_IE, MAC_WLAN_OUI_MICROSOFT, MAC_WLAN_OUI_TYPE_MICROSOFT_WPS}
228 };
229
230 if ((ie_buf == OSAL_NULL) || (ie_buf_len == OSAL_NULL) || (*ie_buf_len == 0)) {
231 oam_warning_log0(0, OAM_SF_CFG, "{hmac_config_del_ie::param error.}");
232 return;
233 }
234
235 for (i = 0; i < osal_array_size(mac_wlan_ie_oui); i++) {
236 if (mac_wlan_ie_oui[i].ie_type == ie_type) {
237 break;
238 }
239 }
240
241 if (i == osal_array_size(mac_wlan_ie_oui)) {
242 oam_error_log1(0, OAM_SF_CFG, "{hmac_config_del_ie::not find the ie[%d].}", ie_type);
243 return;
244 }
245
246 del_ie_buf = hmac_find_vendor_ie_etc(mac_wlan_ie_oui[i].oui, (osal_u8)mac_wlan_ie_oui[i].oui_type,
247 (osal_u8 *)ie_buf, (osal_s32)(*ie_buf_len));
248 if (del_ie_buf == OSAL_NULL) {
249 oam_warning_log1(0, OAM_SF_CFG, "{hmac_config_del_ie::not find the ie[%d] in ie buf.}", ie_type);
250 return;
251 }
252
253 del_ie_buf_len = del_ie_buf[1] + MAC_IE_HDR_LEN;
254
255 /* 将del ie后面的内容拷贝到del ie现所在位置 */
256 ie_buf_end = (ie_buf + *ie_buf_len);
257 del_ie_end = (del_ie_buf + del_ie_buf_len);
258 if (ie_buf_end < del_ie_end) {
259 return;
260 }
261
262 if (ie_buf_end > del_ie_end) {
263 errno_t ret;
264 ret = memmove_s(del_ie_buf, (osal_u32)(ie_buf_end - del_ie_end),
265 del_ie_end, (osal_u32)(ie_buf_end - del_ie_end));
266 if (ret != EOK) {
267 oam_error_log1(0, OAM_SF_CFG, "{hmac_config_del_ie::memmove fail[%d].", ret);
268 return;
269 }
270 }
271 *ie_buf_len -= del_ie_buf_len;
272 }
273
hmac_scan_del_wps_ie(hmac_vap_stru * hmac_vap,osal_u32 * len,osal_u8 * ie,osal_u8 del_wps_ie)274 OAL_STATIC osal_void hmac_scan_del_wps_ie(hmac_vap_stru *hmac_vap, osal_u32 *len, osal_u8 *ie, osal_u8 del_wps_ie)
275 {
276 osal_u8 request_type = 0xff;
277
278 #ifdef _PRE_WLAN_FEATURE_P2P
279 hmac_config_del_ie(MAC_P2P_IE, ie, len);
280 #endif
281
282 /* wfa认证要求sta 扫描probe req报文携带wps ie */
283 if (del_wps_ie == 0) {
284 return;
285 }
286
287 if ((hmac_scan_check_wps_status(hmac_vap, *len, ie, &request_type) == OAL_SUCC) && (request_type == 0)) {
288 hmac_config_del_ie(MAC_WPS_IE, ie, len);
289 }
290 }
291
hmac_wps_init(osal_void)292 osal_u32 hmac_wps_init(osal_void)
293 {
294 /* 消息注册 */
295 frw_msg_hook_register(WLAN_MSG_W2H_CFG_SET_WPS_IE, hmac_config_set_wps_ie_etc);
296 frw_msg_hook_register(WLAN_MSG_W2H_CFG_SET_WPS_P2P_IE, hmac_config_set_wps_p2p_ie_etc);
297
298 /* 对外接口注册 */
299 hmac_feature_hook_register(HMAC_FHOOK_SCAN_DEL_WPS_IE, hmac_scan_del_wps_ie);
300
301 return OAL_SUCC;
302 }
303
hmac_wps_deinit(osal_void)304 osal_void hmac_wps_deinit(osal_void)
305 {
306 /* 消息去注册 */
307 frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_SET_WPS_IE);
308 frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_SET_WPS_P2P_IE);
309
310 /* 对外接口去注册 */
311 hmac_feature_hook_unregister(HMAC_FHOOK_SCAN_DEL_WPS_IE);
312
313 return;
314 }
315
316 #ifdef __cplusplus
317 #if __cplusplus
318 }
319 #endif
320 #endif
321