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