• 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 "wpa_magiclink.h"
8 #include <net/if.h>
9 #include "includes.h"
10 #include "common.h"
11 #include "common/ieee802_11_common.h"
12 #include "common/ieee802_11_defs.h"
13 #include "wps/wps_i.h"
14 #include "eap_peer/eap.h"
15 
16 #include "wpa_supplicant_i.h"
17 #include "p2p_supplicant.h"
18 #include "bss.h"
19 #include "ctrl_iface.h"
20 #include "../wpa_supplicant/config.h"
21 #include "notify.h"
22 #include "securec.h"
23 #ifdef BRCM_VE
24 #include "wpa.h"
25 #include "wpa_i.h"
26 #include "wpa_supplicant_i.h"
27 #include "driver_i.h"
28 #endif /* BRCM_VE */
29 #ifdef CONFIG_LIBWPA_VENDOR
30 #include "wpa_client.h"
31 #endif
32 
33 #define MANUFACTURER_LEN  32
34 #define MODEL_NAME_LEN    32
35 #define MODEL_NUMBER_LEN  16
36 #define DEVICE_NAME_LEN   64
37 
38 #define HW_PENDING_EAPOL_EXPIRE_TIME_DEF     500 /* ms */
39 /*
40  * used in wps_vendor_specific_ies(wpa_supplicant/scan.c)
41  * wps vendor specific ies,
42  */
43 struct wps_vendor_ies {
44     char manufacturer[MANUFACTURER_LEN];
45     char model_name[MODEL_NAME_LEN];
46     char model_number[MODEL_NUMBER_LEN];
47     char device_name[DEVICE_NAME_LEN];
48 };
49 
50 #if defined(CONFIG_MAGICLINK)
51 /*lint -restore*/
52 #ifdef CONFIG_MAGICLINK_PC
hw_magiclink_gen_scan_res(const u8 * bssid,int freqency,int noGc)53 static struct wpa_scan_res *hw_magiclink_gen_scan_res(const u8 *bssid, int freqency, int noGc)
54 {
55 #else
56 static struct wpa_scan_res *hw_magiclink_gen_scan_res(const u8 *bssid, int freqency)
57 {
58 #endif
59     struct wpa_scan_res* res = NULL;
60     unsigned char ie_data[] = {
61         48, 20, 1,  0,  0, 15, 172, 4, 1, 0, 0,
62         15, 172, 4, 1, 0, 0, 15, 172, 2, 12, 0 }; // RSN IE
63 
64     res = os_zalloc(sizeof(*res) + sizeof(ie_data) + sizeof(ie_data));
65     if (!res) {
66         wpa_printf(MSG_ERROR, "P2P: Failed to allocate memory for magiclink");
67         return NULL;
68     }
69 
70     res->flags = 11;
71 #ifdef CONFIG_MAGICLINK_PC
72     if (noGc == 1) {
73         res->legacyGO = 1;
74     } else {
75         res->legacyGO = 0;
76     }
77 #endif
78     os_memcpy(res->bssid, bssid, ETH_ALEN);
79 
80     res->freq = freqency;
81     res->beacon_int = 100;
82     res->caps = 1297;
83     res->qual = 0;
84     res->noise = 0;
85     res->level = 0;
86     res->tsf = 0;
87     res->age = 0;
88     res->ie_len = sizeof(ie_data);
89     res->beacon_ie_len = sizeof(ie_data);
90     os_memcpy(res + 1, ie_data, sizeof(ie_data));
91     os_memcpy((char*)(res + 1) + res->ie_len, ie_data, sizeof(ie_data));
92 
93     return res;
94 }
95 
96 static int hw_magiclink_get_ht40_mode(int channel)
97 {
98     for (int op = 0; global_op_class[op].op_class; op++) {
99         const struct oper_class_map *o = &global_op_class[op];
100         u8 ch;
101 
102         if (o->mode != HOSTAPD_MODE_IEEE80211A)
103             continue;
104 
105         for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
106             if ((o->bw != BW40PLUS && o->bw != BW40MINUS) ||
107                 ch != channel)
108                 continue;
109             return (o->bw == BW40MINUS) ? -1 : 1;
110         }
111     }
112     return 0;
113 }
114 
115 static int hw_magiclink_scan_param(struct wpa_supplicant *wpa_s)
116 {
117     if (wpa_s == NULL) {
118         wpa_printf(MSG_ERROR, "Parameter error,wpa_s == NULL");
119         return -1;
120     }
121 
122     wpa_s->scan_req = MANUAL_SCAN_REQ;
123 
124     int pri_chan = 0;
125     enum hostapd_hw_mode hw_mode = ieee80211_freq_to_chan(wpa_s->magic_link_freq,
126                                                          (u8 *)&pri_chan);
127     if (hw_mode == NUM_HOSTAPD_MODES) {
128         wpa_printf(MSG_ERROR, "frequency(%d MHz) error", wpa_s->magic_link_freq);
129         return -1;
130     }
131     os_free(wpa_s->manual_scan_freqs);
132     // 3:Number of channels:primary channel,secondary channel,0
133     wpa_s->manual_scan_freqs = os_zalloc(3 * sizeof(int));
134     if (wpa_s->manual_scan_freqs == NULL) {
135         wpa_printf(MSG_ERROR, "alloc wpa_s->manual_scan_freqs failed");
136         return -1;
137     }
138     wpa_s->manual_scan_freqs[0] = wpa_s->magic_link_freq;
139     if (wpa_s->normal_scans && hw_mode == HOSTAPD_MODE_IEEE80211A) {
140         int behavior = hw_magiclink_get_ht40_mode(pri_chan);
141         // 5G channel to freq
142         int sec_freq = 5000 + (pri_chan + behavior * 4) * 5;
143 
144         switch (behavior) {
145         case -1:
146             wpa_s->manual_scan_freqs[0] = sec_freq;
147             wpa_s->manual_scan_freqs[1] = wpa_s->magic_link_freq;
148             break;
149         case 1:
150             wpa_s->manual_scan_freqs[1] = sec_freq;
151             break;
152         default:
153             break;
154         }
155     }
156     wpa_printf(MSG_DEBUG, "%s: freq[0]=%d, freq[1]=%d", __func__, wpa_s->manual_scan_freqs[0],
157                 wpa_s->manual_scan_freqs[1]);
158     return 0;
159 }
160 
161 void hw_magiclink_scan(struct wpa_supplicant *wpa_s)
162 {
163     if (!wpa_s) {
164         wpa_msg(wpa_s, MSG_DEBUG,
165                 "magiclink: Start scan for network selection fail");
166         return;
167     }
168     wpa_s->normal_scans = 0;
169     hw_magiclink_scan_param(wpa_s);
170     wpa_supplicant_req_scan(wpa_s, 0, 0);
171     return;
172 }
173 
174 void magiclink_prepare_scan(struct wpa_supplicant *wpa_s, int *timeout_usec)
175 {
176     if (!wpa_s) {
177         wpa_printf(MSG_ERROR, "Parameter error");
178         return;
179     }
180     if (timeout_usec != NULL) {
181         *timeout_usec = 50000;
182     }
183     if (wpa_s->normal_scans > 4) {
184         return;
185     }
186     hw_magiclink_scan_param(wpa_s);
187 }
188 
189 static int hw_magiclink_add_new_scan_res(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int freq, int noGc)
190 {
191 #define DEFAULT_SCAN_RES_SIZE 32
192     struct os_reltime fetch_time;
193     struct wpa_bss *bss = NULL;
194     struct wpa_scan_res *res = NULL;
195     struct wpa_bss **n = NULL;
196     unsigned int siz = DEFAULT_SCAN_RES_SIZE;
197 
198 #ifdef CONFIG_MAGICLINK_PC
199     res = hw_magiclink_gen_scan_res(ssid->bssid, freq, noGc);
200 #else
201     res = hw_magiclink_gen_scan_res(ssid->bssid, freq);
202 #endif
203 
204     if (!res) {
205         wpa_printf(MSG_ERROR, "P2P: Failed to generate scan result");
206         return -1;
207     }
208 
209     os_get_reltime(&fetch_time);
210     bss = hw_magiclink_bss_add(wpa_s, ssid->ssid, ssid->ssid_len, res, &fetch_time);
211     if (!bss) {
212         os_free(res);
213         return -1;
214     }
215 
216     n = os_realloc_array(wpa_s->last_scan_res, siz, sizeof(struct wpa_bss *));
217     if (!n) {
218         os_free(res);
219         return -1;
220     }
221     wpa_s->last_scan_res = n;
222     wpa_s->last_scan_res_size = siz;
223     wpa_s->last_scan_res[0] = bss;
224     wpa_s->last_scan_res_used = 1;
225     os_free(res);
226     return 0;
227 }
228 
229 static int hw_magiclink_connect_parse_param(struct wpa_supplicant *wpa_s, const char *cmd,
230     char **ppsk, char **pbssid, char **pfreq, int *noGc)
231 {
232     char *pos = NULL;
233 
234     if (!wpa_s || !cmd || !ppsk || !pbssid || !pfreq || !noGc) {
235         wpa_printf(MSG_ERROR, "%s param is null", __func__);
236         return -1;
237     }
238     // ssid
239     pos = os_strstr(cmd, "\n");
240     if (!pos) {
241         return -1;
242     }
243     *pos = '\0';
244 
245     // bssid
246     *pbssid = pos + 1;
247     pos = os_strstr(pos + 1, "\n");
248     if (!pos) {
249         return -1;
250     }
251     *pos = '\0';
252 
253     // password
254     *ppsk = pos + 1;
255     pos = os_strstr(pos + 1, "\n");
256     if (!pos) {
257         return -1;
258     }
259     *pos = '\0';
260     // frequency
261     *pfreq = pos + 1;
262 
263 #ifdef CONFIG_MAGICLINK_PC
264     // noGc
265     pos = os_strstr(pos + 1, "\n");
266     if (pos != NULL) {
267         *pos = '\0';
268         *noGc = atoi(pos + 1);
269         wpa_msg(wpa_s, MSG_INFO, "wpa_magiclink noGc is %d",  *noGc);
270     }
271 #endif
272 
273     return 0;
274 }
275 
276 static struct wpa_ssid *hw_magiclink_add_network(struct wpa_supplicant *wpa_s, char *pssid,
277     const char *pbssid, char *ppsk)
278 {
279     struct wpa_ssid *ssid = wpa_config_add_network(wpa_s->conf);
280     if (!ssid) {
281         return NULL;
282     }
283 
284     wpa_config_set_network_defaults(ssid);
285     hw_magiclink_ctrl_iface_update_network(wpa_s, ssid, "ssid", pssid);
286     hw_magiclink_ctrl_iface_update_network(wpa_s, ssid, "priority", "0");
287 
288     if (strcmp(ppsk, "\"\"") == 0) {
289         wpa_printf(MSG_DEBUG, "key_mgmt is NONE");
290         hw_magiclink_ctrl_iface_update_network(wpa_s, ssid, "key_mgmt", "NONE");
291     } else {
292         hw_magiclink_ctrl_iface_update_network(wpa_s, ssid, "key_mgmt", "WPA-PSK");
293         hw_magiclink_ctrl_iface_update_network(wpa_s, ssid, "psk", ppsk);
294     }
295     if (hwaddr_aton(pbssid, ssid->bssid)) {
296         wpa_printf(MSG_ERROR, "fail to parser bssid");
297         return NULL;
298     }
299     ssid->bssid_set = 1;
300     return ssid;
301 }
302 
303 static int hw_magiclink_connect_known_ap(struct wpa_supplicant *wpa_s, char *cmd)
304 {
305     /* cmd: "SSID BSSID PASSWORD FREQUENCY"
306          "P"DIRECT-xx-xxxx" xx:xx:xx:xx:xx:xx "xxxxxxxx" 2412|2437|2462"
307          "P\"DIRECT-XA-send\" 5a:7f:66:ae:a1:66 \"d9hHbPv0\" 2412" */
308     char *pfreq = NULL;
309     char *ppsk = NULL;
310     char *pbssid = NULL;
311     char *pssid = cmd;
312     int freq;
313     int noGc = 0xFF;
314 
315     if (hw_magiclink_connect_parse_param(wpa_s, cmd, &ppsk, &pbssid, &pfreq, &noGc)) {
316         wpa_printf(MSG_DEBUG, "hw_magiclink_connect_parse_param failed");
317         return -1;
318     }
319     struct wpa_ssid *ssid = hw_magiclink_add_network(wpa_s, pssid, pbssid, ppsk);
320     if (!ssid) {
321         wpa_printf(MSG_ERROR, "hw_magiclink_add_network failed");
322         return -1;
323     }
324     freq = atoi(pfreq);
325     if (hw_magiclink_add_new_scan_res(wpa_s, ssid, freq, noGc)) {
326         wpa_printf(MSG_ERROR, "hw_magiclink_add_new_scan_res failed");
327         return -1;
328     }
329 
330     struct os_reltime now;
331     os_get_reltime(&now);
332     wpa_s->last_scan = now;
333     wpa_s->magic_link_freq = freq;
334     hw_magiclink_scan(wpa_s);
335     wpa_s->disconnected = 0;
336     wpa_s->reassociate = 1;
337     ssid->p2p_group = 1;
338     wpa_s->show_group_started = 1;
339     return 0;
340 }
341 
342 int hw_magiclink_p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd)
343 {
344     enum wpa_driver_if_type iftype;
345     char p[256];
346     wpa_printf(MSG_ERROR, "hw_magiclink_p2p_ctrl_connect");
347     if (!wpa_s || !cmd) {
348         wpa_printf(MSG_ERROR, "%s:wpa_s or cmd is null", __func__);
349         return -1;
350     }
351 
352     os_memset(p, 0, sizeof(p));
353     wpa_s->create_p2p_iface = hw_magiclink_create_iface(wpa_s);
354     iftype = WPA_IF_P2P_GROUP;
355     /*
356      * reltek chip don not support create p2p interface, use p2p0
357      */
358 #ifdef CONFIG_SUPPORT_PLATEFORM_REALTEK
359     struct wpa_supplicant *magiclink_wpa_s = wpa_s;
360 #else
361     if (hw_magiclink_add_group_interface(wpa_s, iftype) < 0) {
362         wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
363             "interface for the group");
364         return -1;
365     }
366 
367     struct wpa_supplicant *magiclink_wpa_s = hw_magiclink_init_group_interface(wpa_s, 0);
368     if (!magiclink_wpa_s) {
369         wpa_printf(MSG_ERROR, "P2P: Failed to get magiclink interface");
370         return -1;
371     }
372 #endif
373 
374     wpa_msg(wpa_s, MSG_INFO, "P2P-INTERFACE-CREATED GC %s",  magiclink_wpa_s->ifname);
375     os_snprintf(p, sizeof(p), "P2P-INTERFACE-CREATED GC %s",  magiclink_wpa_s->ifname);
376 #ifdef CONFIG_LIBWPA_VENDOR
377 	struct P2pIfaceCreatedParam p2pIfaceCreatedParam = {};
378 	p2pIfaceCreatedParam.isGo = 0;
379 	wpa_printf(MSG_INFO, "WPA_EVENT_IFACE_CREATED GC %d, ifname %s",
380 		p2pIfaceCreatedParam.isGo, magiclink_wpa_s->ifname);
381 	WpaEventReport(magiclink_wpa_s->ifname, WPA_EVENT_IFACE_CREATED, (void *) &p2pIfaceCreatedParam);
382 #endif
383 
384 #ifdef MTK_SET_MAGIC_LINK_FLAG
385     magiclink_wpa_s->is_magic_link = 1;
386 #endif
387     wpa_s->global->p2p_group_formation = NULL;
388     return hw_magiclink_connect_known_ap(magiclink_wpa_s, cmd);
389 }
390 
391 int hw_wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int network_id,
392                           int persistent, int freq, int max_band) {
393   int vht = wpa_s->conf->p2p_go_vht;
394   int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
395   struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, network_id);
396   if (ssid == NULL) {
397     return wpas_p2p_group_add(wpa_s, persistent, freq, 0, ht40, vht, max_band,
398                               0, 0, false);
399   } else if (ssid->disabled == 2) {
400     return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, ht40, vht,
401                                          max_band, 0, 0, NULL, 0, 0, false);
402   }
403   return -1;
404 }
405 #endif
406 
407