• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 Huawei Device Co., Ltd.
3  *
4  * This software may be distributed under the terms of the BSD license.
5  * See README for more details.
6  */
7 #include "includes.h"
8 #include "driver_nl80211_hisi.h"
9 #include "driver_nl80211.h"
10 #include "wpa_supplicant_i.h"
11 #include "config.h"
12 #include "android_drv.h"
13 #include "securec.h"
14 
15 #if defined(HISI_CONNECTIVITY_PATCH) && defined(HISI_MIRACAST_SINK_OPT)
16 #include "hisi_miracast_sink.h"
17 #endif
18 
19 #define WPA_PS_ENABLED		0
20 #define WPA_PS_DISABLED		1
21 
22 int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv, struct nl_msg *msg,
23 		       int (*valid_handler)(struct nl_msg *, void *),
24 		       void *valid_data);
25 
26 static int drv_errors = 0;
27 
wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data * drv)28 static void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data *drv)
29 {
30 	drv_errors++;
31 	if (drv_errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
32 		drv_errors = 0;
33 		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
34 	}
35 }
36 
wpa_driver_set_power_save(void * priv,int state)37 static int wpa_driver_set_power_save(void *priv, int state)
38 {
39 	struct i802_bss *bss = priv;
40 	struct wpa_driver_nl80211_data *drv = bss->drv;
41 	struct nl_msg *msg;
42 	int ret = -1;
43 	enum nl80211_ps_state ps_state;
44 
45 	msg = nlmsg_alloc();
46 	if (!msg)
47 		return -1;
48 
49 	genlmsg_put(msg, 0, 0, drv->global->nl80211_id, 0, 0,
50 		    NL80211_CMD_SET_POWER_SAVE, 0);
51 
52 	if (state == WPA_PS_ENABLED)
53 		ps_state = NL80211_PS_ENABLED;
54 	else
55 		ps_state = NL80211_PS_DISABLED;
56 
57 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
58 	NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state);
59 
60 	ret = send_and_recv_msgs(drv, msg, NULL, NULL);
61 	msg = NULL;
62 	if (ret < 0)
63 		wpa_printf(MSG_ERROR, "nl80211: Set power mode fail: %d", ret);
64 nla_put_failure:
65 	nlmsg_free(msg);
66 	return ret;
67 }
68 
get_power_mode_handler(struct nl_msg * msg,void * arg)69 static int get_power_mode_handler(struct nl_msg *msg, void *arg)
70 {
71 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
72 	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
73 	int *state = (int *)arg;
74 
75 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
76 		  genlmsg_attrlen(gnlh, 0), NULL);
77 
78 	if (!tb[NL80211_ATTR_PS_STATE])
79 		return NL_SKIP;
80 
81 	if (state) {
82 		*state = (int)nla_get_u32(tb[NL80211_ATTR_PS_STATE]);
83 		wpa_printf(MSG_DEBUG, "nl80211: Get power mode = %d", *state);
84 		*state = (*state == NL80211_PS_ENABLED) ?
85 				WPA_PS_ENABLED : WPA_PS_DISABLED;
86 	}
87 
88 	return NL_SKIP;
89 }
90 
wpa_driver_get_power_save(void * priv,int * state)91 static int wpa_driver_get_power_save(void *priv, int *state)
92 {
93 	struct i802_bss *bss = priv;
94 	struct wpa_driver_nl80211_data *drv = bss->drv;
95 	struct nl_msg *msg;
96 	int ret = -1;
97 
98 	msg = nlmsg_alloc();
99 	if (!msg)
100 		return -1;
101 
102 	genlmsg_put(msg, 0, 0, drv->global->nl80211_id, 0, 0,
103 		    NL80211_CMD_GET_POWER_SAVE, 0);
104 
105 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
106 
107 	ret = send_and_recv_msgs(drv, msg, get_power_mode_handler, state);
108 	msg = NULL;
109 	if (ret < 0)
110 		wpa_printf(MSG_ERROR, "nl80211: Get power mode fail: %d", ret);
111 nla_put_failure:
112 	nlmsg_free(msg);
113 	return ret;
114 }
115 
116 int g_is_jp = 0;
wpa_driver_nl80211_driver_cmd(void * priv,char * cmd,char * buf,size_t buf_len)117 int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf, size_t buf_len )
118 {
119     struct i802_bss *bss = priv;
120     struct wpa_driver_nl80211_data *drv = bss->drv;
121     struct ifreq ifr;
122     int ret = 0;
123     int ret_s;
124 
125     wpa_printf(MSG_ERROR, "wpa_driver_nl80211_driver_cmd:cmd = %s", cmd);
126     if (os_strcasecmp(cmd, "STOP") == 0)
127     {
128         linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0);
129         wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
130     }
131     else if (os_strcasecmp(cmd, "START") == 0)
132     {
133         linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1);
134         wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
135     }
136     else if (os_strcasecmp(cmd, "MACADDR") == 0)
137     {
138         u8 macaddr[ETH_ALEN] = {};
139 
140         ret = linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, macaddr);
141         if (!ret)
142         {
143             ret_s = snprintf_s(buf, buf_len, buf_len - 1,
144                       "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
145             if (ret_s == -1) {
146                 wpa_printf(MSG_ERROR, "%s:%d, snprintf failed, ret=%d", __func__, __LINE__, ret_s);
147             }
148         }
149     }
150     else if (os_strcasecmp(cmd, "RELOAD") == 0)
151     {
152         wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
153     }
154     else if (os_strncasecmp(cmd, "POWERMODE ", 10) == 0)
155     {
156         int state;
157 
158         state = atoi(cmd + 10);
159         ret = wpa_driver_set_power_save(priv, state);
160         if (ret < 0)
161         {
162             wpa_driver_send_hang_msg(drv);
163         }
164         else
165         {
166             drv_errors = 0;
167         }
168     }
169     else if (os_strncasecmp(cmd, "GETPOWER", 8) == 0)
170     {
171         int state = -1;
172 
173         ret = wpa_driver_get_power_save(priv, &state);
174         if (!ret && (state != -1))
175         {
176             ret_s = snprintf_s(buf, buf_len, buf_len - 1, "POWERMODE = %d\n", state);
177             if (ret_s == -1) {
178                 wpa_printf(MSG_ERROR, "%s:%d, snprintf failed, ret=%d", __func__, __LINE__, ret_s);
179             }
180             drv_errors = 0;
181         }
182         else
183         {
184             wpa_driver_send_hang_msg(drv);
185         }
186     }
187     else
188     {
189         /* Use private command */
190         wifi_priv_cmd priv_cmd = {0};
191         uint32 ret_len = 0;
192         size_t buf_len_tmp;
193 
194         if (buf_len > MAX_PRIV_CMD_SIZE || strlen(cmd) >= MAX_PRIV_CMD_SIZE)
195         {
196             wpa_printf(MSG_ERROR, "%s: too long priavte command, strlen(cmd)=%zu buf_len=%zu", __func__, strlen(cmd), buf_len);
197             return -1;
198         }
199         buf_len_tmp = buf_len;
200         if (MAX_PRIV_CMD_SIZE == buf_len)
201         {
202             buf_len = strlen(cmd); /* default driver xxx cmd */
203         }
204 
205         /* Hisi private data structure cmd should use buf_len, rather than strlen(cmd) */
206         ret_s = memcpy_s(buf, buf_len_tmp, cmd, buf_len);
207         if (ret_s != EOK) {
208             wpa_printf(MSG_ERROR, "%s:%d, memcpy failed, ret=%d", __func__, __LINE__, ret_s);
209         }
210 
211         ret_s = memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr));
212         if (ret_s != EOK) {
213             wpa_printf(MSG_ERROR, "%s:%d, memset failed, ret=%d", __func__, __LINE__, ret_s);
214         }
215 
216         ret_s = memcpy_s(priv_cmd.buf, MAX_PRIV_CMD_SIZE, buf, buf_len);
217         if (ret_s != EOK) {
218             wpa_printf(MSG_ERROR, "%s:%d, memcpy failed, ret=%d", __func__, __LINE__, ret_s);
219         }
220 
221         priv_cmd.total_len = buf_len; /* MAX_PRIV_CMD_SIZE */
222         priv_cmd.used_len = buf_len; /* strlen(cmd) */
223 
224         ifr.ifr_data = (void *)&priv_cmd;
225         os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
226 
227         wpa_printf(MSG_EXCESSIVE, "%s: 1:ifr_name=%s, len=%zu, buf_len=%zu", __func__, ifr.ifr_name, strlen(buf), buf_len);
228 
229         ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr);
230         if (ret < 0)
231         {
232             wpa_printf(MSG_ERROR, "%s: failed to issue private commands\n", __func__);
233             wpa_driver_send_hang_msg(drv);
234         }
235         else
236         {
237             drv_errors = 0;
238             ret_len = os_strlen(priv_cmd.buf);
239             ret_len = (ret_len < MAX_PRIV_CMD_SIZE) ? ret_len : (MAX_PRIV_CMD_SIZE - 1);
240             /* SET Command return 0 which means OK, GET Command return string length */
241             if (os_strncasecmp(buf, priv_cmd.buf, ret_len) != 0)
242             {
243                 ret = ret_len;
244             }
245             ret_s = memset_s(buf, buf_len, 0, buf_len);
246             if (ret_s != EOK) {
247                 wpa_printf(MSG_ERROR, "%s:%d, memset failed, ret=%d", __func__, __LINE__, ret_s);
248             }
249 
250             ret_s = memcpy_s(buf, buf_len, priv_cmd.buf, ret_len); /* copy kernel space return string to user space */
251             if (ret_s != EOK) {
252                 wpa_printf(MSG_ERROR, "%s:%d, memcpy failed, ret=%d", __func__, __LINE__, ret_s);
253             }
254             buf[ret_len] = '\0';
255 
256             if (os_strncasecmp(cmd, "COUNTRY", 7) == 0)
257             {
258                 union wpa_event_data event = {0};
259                 g_is_jp = (os_strncasecmp(cmd + 8, "JP", 2) == 0) ? 1 : 0 ;
260 
261                 event.channel_list_changed.initiator = REGDOM_SET_BY_USER;
262                 event.channel_list_changed.type = REGDOM_TYPE_UNKNOWN;
263                 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &event);
264 
265                 wpa_printf(MSG_DEBUG, "%s:set country code end. len=%zu, ret_len=%d ret=%d", __func__, strlen(buf), ret_len, ret);
266                 return ret;
267             }
268 #ifdef HISI_MIRACAST_SINK_OPT
269             hisi_miracast_sink_log("%s:%.15s len=%zu, ret_len=%d ret=%d", __func__, buf, strlen(buf), ret_len, ret);
270 #else
271 #ifdef HW_WPA_REDUCE_LOG
272             wpa_printf(MSG_EXCESSIVE, "%s:%.15s len=%zu, ret_len=%d ret=%d", __func__, buf, strlen(buf), ret_len, ret);
273 #else
274             wpa_printf(MSG_DEBUG, "%s:%.15s len=%zu, ret_len=%d ret=%d", __func__, buf, strlen(buf), ret_len, ret);
275 #endif
276 #endif
277         }
278     }
279     return ret;
280 }
281 
wpa_driver_set_p2p_noa(void * priv,u8 count,int start,int duration)282 int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration)
283 {
284     char buf[MAX_DRV_CMD_SIZE] = {0};
285     char *pbuf;
286     oal_p2p_noa_param_stru *pst_p2p_noa = NULL;
287     char *_cmd = "P2P_SET_NOA";
288     int ret_s;
289 
290     wpa_printf(MSG_ERROR, "%s: Entry", __func__);
291     pbuf = buf;
292     ret_s = sprintf_s(pbuf, MAX_DRV_CMD_SIZE, "%s", _cmd);
293     if (ret_s == -1) {
294         wpa_printf(MSG_ERROR, "%s:%d, sprintf failed, ret=%d", __func__, __LINE__, ret_s);
295     }
296     pbuf += ret_s;
297     *pbuf++ = '\0';
298     pst_p2p_noa = (oal_p2p_noa_param_stru *)pbuf;
299     pst_p2p_noa->uc_count = count;
300     pst_p2p_noa->ul_duration= duration;
301     pst_p2p_noa->ul_start_time= start;
302 
303     return wpa_driver_nl80211_driver_cmd(priv, buf, buf, strlen(_cmd) + 1 + sizeof(oal_p2p_noa_param_stru));
304 
305 }
306 
wpa_driver_get_p2p_noa(void * priv,u8 * buf,size_t len)307 int wpa_driver_get_p2p_noa(void *priv, u8 *buf, size_t len)
308 {
309 	/* Return 0 till we handle p2p_presence request completely in the device side */
310 	return 0;
311 }
312 
wpa_driver_set_p2p_ps(void * priv,int legacy_ps,int opp_ps,int ctwindow)313 int wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow)
314 {
315     char buf[MAX_DRV_CMD_SIZE] = {0};
316     char *pbuf;
317     oal_p2p_ops_param_stru *pst_p2p_ops = NULL;
318     char *_cmd = "P2P_SET_PS";
319     int ret_s;
320 
321 	wpa_printf(MSG_ERROR, "%s: Entry", __func__);
322     pbuf = buf;
323     ret_s = sprintf_s(pbuf, MAX_DRV_CMD_SIZE, "%s", _cmd);
324     if (ret_s == -1) {
325         wpa_printf(MSG_ERROR, "%s:%d, sprintf failed, ret=%d", __func__, __LINE__, ret_s);
326     }
327     pbuf += ret_s;
328     *pbuf++ = '\0';
329     pst_p2p_ops = (oal_p2p_ops_param_stru *)pbuf;
330     pst_p2p_ops->en_ops_ctrl = opp_ps;
331     pst_p2p_ops->uc_ct_window = ctwindow;
332 
333 	return wpa_driver_nl80211_driver_cmd(priv, buf, buf, strlen(_cmd) + 1 + sizeof(oal_p2p_ops_param_stru));
334 }
335 
wpa_driver_set_ap_wps_p2p_ie(void * priv,const struct wpabuf * beacon,const struct wpabuf * proberesp,const struct wpabuf * assocresp)336 int wpa_driver_set_ap_wps_p2p_ie(void *priv,
337                  const struct wpabuf *beacon,
338 				 const struct wpabuf *proberesp,
339 				 const struct wpabuf *assocresp)
340 {
341 	char buf[MAX_WPSP2PIE_CMD_SIZE] = {0};
342 	struct wpabuf *ap_wps_p2p_ie = NULL;
343 	char *_cmd = "SET_AP_WPS_P2P_IE";
344 	char *pbuf;
345 	int ret = 0;
346 	int i;
347 	int ret_s;
348 	oal_app_ie_stru *pst_app_ie = NULL;
349 	struct cmd_desc {
350 		int cmd;
351 		const struct wpabuf *src;
352 	} cmd_arr[] = {
353 		{0x0, beacon},
354 		{0x2, proberesp},
355 		{0x4, assocresp},
356 		{-1, NULL}
357 	};
358 
359 	wpa_printf(MSG_ERROR, "%s: Entry", __func__);
360 	for (i = 0; cmd_arr[i].cmd != -1; i++) {
361 		ret_s = memset_s(buf, sizeof(buf), 0, sizeof(buf));
362 		if (ret_s != EOK) {
363 			wpa_printf(MSG_ERROR, "%s:%d, memset failed, ret=%d", __func__, __LINE__, ret_s);
364 		}
365 		pbuf = buf;
366 		ret_s = sprintf_s(pbuf, MAX_WPSP2PIE_CMD_SIZE, "%s", _cmd);
367 		if (ret_s == -1) {
368 			wpa_printf(MSG_ERROR, "%s:%d, memset failed, ret=%d", __func__, __LINE__, ret_s);
369 		}
370 		pbuf += ret_s;
371 		*pbuf++ = '\0';
372 		ap_wps_p2p_ie = cmd_arr[i].src ?
373 			wpabuf_dup(cmd_arr[i].src) : NULL;
374 		if (ap_wps_p2p_ie) {
375             if (wpabuf_len(ap_wps_p2p_ie) > WLAN_WPS_IE_MAX_SIZE)
376             {
377                 wpa_printf(MSG_ERROR, "%s: app ie too large to wifi driver buffer.app_ie_len %d, auc_ie len %ul",
378                             __func__, (int)wpabuf_len(ap_wps_p2p_ie), WLAN_WPS_IE_MAX_SIZE);
379                 wpabuf_free(ap_wps_p2p_ie);
380                 return -1;
381             }
382 
383 			pst_app_ie = (oal_app_ie_stru *)pbuf;
384 			pst_app_ie->en_app_ie_type = cmd_arr[i].cmd;
385 			pst_app_ie->ul_ie_len = wpabuf_len(ap_wps_p2p_ie);
386 
387 			ret_s = memcpy_s(pst_app_ie->auc_ie, sizeof(pst_app_ie->auc_ie), wpabuf_head(ap_wps_p2p_ie), wpabuf_len(ap_wps_p2p_ie));
388 			if (ret_s != EOK) {
389 				wpa_printf(MSG_ERROR, "%s:%d, memcpy failed, ret=%d", __func__, __LINE__, ret_s);
390 			}
391 #if defined(HISI_CONNECTIVITY_PATCH) && defined(HISI_MIRACAST_SINK_OPT)
392 			hisi_miracast_sink_log("cmd:%s, type %d, ie_len %d\r\n",
393 						_cmd,
394 						pst_app_ie->en_app_ie_type,
395 						pst_app_ie->ul_ie_len);
396 #else
397 #ifdef HW_WPA_REDUCE_LOG
398 			wpa_printf(MSG_EXCESSIVE, "cmd:%s, type %d, ie_len %d\r\n",
399 						_cmd,
400 						pst_app_ie->en_app_ie_type,
401 						pst_app_ie->ul_ie_len);
402 #else
403 			wpa_printf(MSG_DEBUG, "cmd:%s, type %d, ie_len %d\r\n",
404 						_cmd,
405 						pst_app_ie->en_app_ie_type,
406 						pst_app_ie->ul_ie_len);
407 #endif /* HW_WPA_REDUCE_LOG */
408 #endif
409 			wpa_printf(MSG_EXCESSIVE, "ie %p\r\n",
410 						pst_app_ie->auc_ie);
411 
412 		    wpa_hexdump(MSG_EXCESSIVE, "P2P: set p2p wps ie", (const char *)pbuf, pst_app_ie->ul_ie_len + 8);
413 
414 			if (strlen(_cmd) + sizeof(oal_app_ie_stru) + 1 < sizeof(buf))
415 			{
416 				ret = wpa_driver_nl80211_driver_cmd(priv, buf, buf,
417 					strlen(_cmd) + sizeof(oal_app_ie_stru) + 1);
418 			}
419 			else
420 			{
421 				wpa_printf(MSG_ERROR, "%s:error.app total length to large!, cmd_len = %zu, buffer = %d", __func__, strlen(_cmd) + sizeof(oal_app_ie_stru) + 1, (int)sizeof(buf));
422 				ret = -1;
423 			}
424 			wpabuf_free(ap_wps_p2p_ie);
425 			if (ret < 0)
426 				break;
427 		}
428 	}
429 	return ret;
430 }
431 
wpa_driver_set_power_on(void * priv,int on)432 int wpa_driver_set_power_on(void *priv, int on)
433 {
434     char buf[MAX_PRIV_CMD_SIZE] = {0};
435     char *pbuf;
436     char *_cmd = "SET_POWER_ON";
437     int ret_s;
438 
439 	wpa_printf(MSG_DEBUG, "%s: Entry,power flag:%d", __func__, on);
440     pbuf = buf;
441     ret_s = sprintf_s(pbuf, MAX_PRIV_CMD_SIZE, "%s %d", _cmd, on);
442     if (ret_s == -1) {
443         wpa_printf(MSG_ERROR, "%s:%d, sprintf failed, ret=%d", __func__, __LINE__, ret_s);
444     }
445     wpa_printf(MSG_DEBUG, "%s:buf is %s", __func__, buf);
446 
447 	return wpa_driver_nl80211_driver_cmd(priv, buf, buf, strlen(buf));
448 }
449 
wpa_driver_set_powermgmt_on(void * priv,int powermgmt_on)450 int wpa_driver_set_powermgmt_on(void *priv, int powermgmt_on)
451 {
452     char buf[MAX_PRIV_CMD_SIZE] = {0};
453     char *pbuf;
454     char *_cmd = "SET_POWER_MGMT_ON";
455     int ret_s;
456 
457     wpa_printf(MSG_DEBUG, "%s: Entry,power mgmt flag:%d", __func__, powermgmt_on);
458     pbuf = buf;
459     ret_s = sprintf_s(pbuf, MAX_PRIV_CMD_SIZE, "%s %d", _cmd, powermgmt_on);
460     if (ret_s == -1) {
461         wpa_printf(MSG_ERROR, "%s:%d, sprintf failed, ret=%d", __func__, __LINE__, ret_s);
462     }
463     wpa_printf(MSG_DEBUG, "%s:buf is %s", __func__, buf);
464 
465     return wpa_driver_nl80211_driver_cmd(priv, buf, buf, strlen(buf));
466 }
467 
wpa_driver_set_qos_map(void * priv,const u8 * qos_map_set,u8 qos_map_set_len)468 int wpa_driver_set_qos_map(void *priv, const u8 *qos_map_set,
469 			                         u8 qos_map_set_len)
470 {
471     char  buf[MAX_DRV_CMD_SIZE] = {0};
472     char *pbuf;
473     int   i, up_start;
474     int   ret = 0;
475     int   ret_s;
476     oal_qos_map_param_stru *pst_qos_map = NULL;
477     char *_cmd = "SET_QOS_MAP";
478 
479     if (qos_map_set_len < 16 || qos_map_set_len > 58 || qos_map_set_len & 1)
480        {
481            wpa_printf(MSG_ERROR, "Invalid QoS Map");
482            return -1;
483        }
484 
485 	wpa_printf(MSG_ERROR, "%s: Entry,set_qos_map", __func__);
486     pbuf = buf;
487     ret_s = sprintf_s(pbuf, MAX_DRV_CMD_SIZE, "%s", _cmd);
488     if (ret_s == -1) {
489         wpa_printf(MSG_ERROR, "%s:%d, sprintf failed, ret=%d", __func__, __LINE__, ret_s);
490     }
491 	pbuf += ret_s;
492 	*pbuf++ = '\0';
493 
494     pst_qos_map= (oal_qos_map_param_stru *)pbuf;
495     pst_qos_map->valid = 1;
496     pst_qos_map->num_dscp_except = (qos_map_set_len - 16) / 2;
497     if (pst_qos_map->num_dscp_except)
498     {
499         for (i = 0; i < pst_qos_map->num_dscp_except; i++)
500         {
501             pst_qos_map->dscp_exception[i] = qos_map_set[i * 2];
502             pst_qos_map->dscp_exception_up[i]   = qos_map_set[i * 2 + 1];
503         }
504     }
505     up_start = qos_map_set_len - 16;
506 	for (i = 0; i < MAX_QOS_UP_RANGE; i++)
507 	{
508 		pst_qos_map->up_low[i]  = qos_map_set[up_start + (i * 2)];
509 		pst_qos_map->up_high[i] = qos_map_set[up_start + (i * 2) + 1];
510 	}
511 
512 	ret = wpa_driver_nl80211_driver_cmd(priv, buf, buf, strlen(_cmd) + 1 + sizeof(oal_qos_map_param_stru));
513 	return ret;
514 }
515 
wpa_driver_set_tx_power(void * priv,int power)516 int wpa_driver_set_tx_power(void *priv, int power)
517 {
518     char    buf[MAX_PRIV_CMD_SIZE] = {0};
519     int     len = 0;
520 
521     wpa_printf(MSG_ERROR, "%s: Entry,power limit:%d", __func__, power);
522     if (power <= 0 || power > 100)
523     {
524         wpa_printf(MSG_ERROR, "%s: Entry,invalid power, valid power should in range(0,100]!", __func__);
525         return -1;
526     }
527     len = snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "TX_POWER %d", power);
528     if (len == -1) {
529         wpa_printf(MSG_ERROR, "%s:%d, snprintf failed, ret=%d", __func__, __LINE__, len);
530     }
531     buf[len] = '\0';
532     wpa_printf(MSG_DEBUG, "%s:buf is %s", __func__, buf);
533 
534     return wpa_driver_nl80211_driver_cmd(priv, buf, buf, len);
535 }
536 
537 #ifdef CONFIG_OWE
wpa_driver_nl80211_sta_assoc(void * priv,const u8 * own_addr,const u8 * addr,int reassoc,u16 status,const u8 * pst_assoc_rsp_ie,size_t len)538 int wpa_driver_nl80211_sta_assoc(void *priv, const u8 *own_addr, const u8 *addr,
539 			  int reassoc, u16 status, const u8 *pst_assoc_rsp_ie, size_t len)
540 {
541     char buf[MAX_WPSP2PIE_CMD_SIZE] = {0};
542     char *pbuf;
543     char *_cmd = "SET_MLME_IE";
544     int ret = 0;
545     int ret_s;
546     set_mlme_stru *pst_mlme_ie = NULL;
547 
548     if (NULL == pst_assoc_rsp_ie)
549     {
550         wpa_printf(MSG_WARNING, "%s[%d]: buf is null.\n", __FUNCTION__, __LINE__);
551         return -1;
552     }
553 
554 	if (len > WLAN_WPS_IE_MAX_SIZE)
555 	{
556 		/* ����·�ie ���ȴ����¼��ڴ��С����ʾ���� */
557 		wpa_printf(MSG_ERROR, "%s[%d]: assoc rsp ie too large to wifi driver buffer. ie_len %zu, MAX len %d",
558 				  __FUNCTION__, __LINE__, len, WLAN_WPS_IE_MAX_SIZE);
559 		return -1;
560 	}
561 
562     pbuf = buf;
563     ret_s = sprintf_s(pbuf, MAX_WPSP2PIE_CMD_SIZE, "%s", _cmd);
564     if (ret_s == -1) {
565         wpa_printf(MSG_ERROR, "%s:%d, sprintf failed, ret=%d", __func__, __LINE__, ret_s);
566     }
567     pbuf += ret_s;
568     *pbuf++ = '\0';
569 
570 	pst_mlme_ie = (set_mlme_stru *)pbuf;
571 	if (reassoc)
572 	{
573 		pst_mlme_ie->en_mlme_type = OAL_IEEE80211_MLME_REASSOC_RSP;
574 	}
575 	else
576 	{
577 		pst_mlme_ie->en_mlme_type = OAL_IEEE80211_MLME_ASSOC_RSP;
578 	}
579 	pst_mlme_ie->us_status = status;
580 	ret_s = memcpy_s(pst_mlme_ie->uc_macaddr, sizeof(pst_mlme_ie->uc_macaddr), addr, ETH_ALEN);
581 	if (ret_s != EOK) {
582 		wpa_printf(MSG_ERROR, "%s:%d, memcpy failed, ret=%d", __func__, __LINE__, ret_s);
583 	}
584 
585 	pst_mlme_ie->us_ie_len = len;
586 	ret_s = memcpy_s(pst_mlme_ie->auc_ie, sizeof(pst_mlme_ie->auc_ie), pst_assoc_rsp_ie, len);
587 	if (ret_s != EOK) {
588 		wpa_printf(MSG_ERROR, "%s:%d, memcpy failed, ret=%d", __func__, __LINE__, ret_s);
589 	}
590 
591 	wpa_printf(MSG_ERROR, "%s[%d]: sta_assoc begin send assoc rsp ie len[%zu] to driver", __FUNCTION__, __LINE__, len);
592 
593 	wpa_printf(MSG_ERROR, "cmd:%s, type %d, status %d, ie_len %d",
594 				_cmd,
595 				pst_mlme_ie->en_mlme_type,
596 				pst_mlme_ie->us_status,
597 				pst_mlme_ie->us_ie_len);
598 
599 	wpa_hexdump(MSG_ERROR, "MLME: set sta_assoc ie", (const char *)pbuf, pst_mlme_ie->us_ie_len + 8);
600 
601 	if (os_strlen(_cmd) + sizeof(set_mlme_stru) + 1 < sizeof(buf))
602 	{
603 		ret = wpa_driver_nl80211_driver_cmd(priv, buf, buf,
604 					os_strlen(_cmd) + sizeof(set_mlme_stru) + 1);
605 	}
606 	else
607 	{
608 		wpa_printf(MSG_ERROR, "%s:error. app total length to large! cmd_len = %zu, buffer = %d",
609 				   __func__, os_strlen(_cmd) + sizeof(set_mlme_stru) + 1, (int)sizeof(buf));
610 		ret = -1;
611 	}
612 
613 	return ret;
614 }
615 #endif
616 
617 #ifdef CONFIG_HW_GET_P2P_SIGNAL_POLL
wpa_drv_get_p2p_link_noise(void * priv,struct wpa_signal_info * si)618 int wpa_drv_get_p2p_link_noise(void *priv, struct wpa_signal_info *si)
619 {
620     if (priv == NULL || si == NULL) {
621         return -1;
622     }
623     struct i802_bss *bss = priv;
624     struct wpa_driver_nl80211_data *drv = bss->drv;
625     os_memset(si, 0, sizeof(struct wpa_signal_info));
626     return nl80211_get_link_noise(drv, si);
627 }
628 #endif /* CONFIG_HW_GET_P2P_SIGNAL_POLL */
629 
wpa_sockets_open(void)630 static int wpa_sockets_open(void)
631 {
632     int skfd;
633 
634     skfd = socket(PF_INET, SOCK_DGRAM, 0);
635     if (skfd < 0)
636     {
637         wpa_printf(MSG_ERROR,
638                 "nl80211: socket open failed.");
639         return -1;
640     }
641     return skfd;
642 }
wpa_sockets_close(int32 skfd)643 static void wpa_sockets_close(int32 skfd)
644 {
645     close(skfd);
646 }
wpa_send_cmd_to_driver(int skfd,s8 * ifname,wifi_priv_cmd * ioctl_data)647 static int wpa_send_cmd_to_driver(int skfd, s8* ifname, wifi_priv_cmd* ioctl_data)
648 {
649     struct ifreq ifr;
650     int ret;
651     int ret_s;
652 
653     ret_s = memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr));
654     if (ret_s != EOK) {
655         wpa_printf(MSG_ERROR, "%s:%d, memset failed, ret=%d", __func__, __LINE__, ret_s);
656     }
657 
658     ret_s = strncpy_s(ifr.ifr_name, IFNAMSIZ, "wlan0", strlen("wlan0"));
659     if (ret_s != EOK) {
660         wpa_printf(MSG_ERROR, "%s:%d, strncpy failed, ret=%d", __func__, __LINE__, ret_s);
661     }
662     ifr.ifr_name[IFNAMSIZ-1] = '\0';
663     ifr.ifr_data = (void*)ioctl_data;
664 
665     ret = ioctl(skfd, SIOCDEVPRIVATE+1, &ifr);
666 
667     if (ret < 0)
668     {
669         wpa_printf(MSG_ERROR,
670                 "%s: failed to issue ioctl cmd.\n", __func__);
671     }
672 
673     return ret;
674 }
675 
676 static cust_data_stru global_cust_data = {0,0};
677 
get_cust_config_params(void)678 static void get_cust_config_params(void)
679 {
680     int skfd;
681     wifi_priv_cmd ioctl_data = {0};
682     int ret;
683     int len;
684 
685     if (-1 == (skfd = wpa_sockets_open()))
686     {
687         wpa_printf(MSG_ERROR,
688                 "%s: failed create socket.\n", __func__);
689         return;
690     }
691 
692     len = snprintf_s(ioctl_data.buf, MAX_PRIV_CMD_SIZE, MAX_PRIV_CMD_SIZE - 1, "WPAS_GET_CUST");
693     if (len == -1) {
694         wpa_printf(MSG_ERROR, "%s:%d, snprintf failed, ret=%d", __func__, __LINE__, len);
695     }
696     ioctl_data.total_len = MAX_PRIV_CMD_SIZE;
697     ioctl_data.used_len = len;
698 #ifdef HW_WPA_REDUCE_LOG
699     wpa_printf(MSG_ERROR, "%s:ioctl_data cmd is %s", __func__, ioctl_data.buf);
700 #else
701     wpa_printf(MSG_ERROR, "%s:ioctl_data cmd is %s", __func__, ioctl_data.buf);
702 #endif
703 
704     ret = wpa_send_cmd_to_driver(skfd, (s8 *)"wlan0", &ioctl_data);
705 
706     if (ret < 0)
707     {
708         wpa_printf(MSG_ERROR,
709                 "%s: send cmd to driver failed.\n", __func__);
710         wpa_sockets_close(skfd);
711         return;
712     }
713 
714     drv_errors = 0;
715 
716     global_cust_data.read = 1;
717     global_cust_data.disable_capab_2ght40 = (u32)(*ioctl_data.buf);
718     wpa_printf(MSG_ERROR,
719                 "%s: update wps global cust data: [disable_capab_2ght40:%d]\n", __func__, global_cust_data.disable_capab_2ght40);
720 
721     wpa_sockets_close(skfd);
722 }
723 
get_cust_disable_capab_2ght40(void)724 u32 get_cust_disable_capab_2ght40(void)
725 {
726     if (!global_cust_data.read)
727     {
728         get_cust_config_params();
729     }
730 
731     return global_cust_data.disable_capab_2ght40;
732 }