• 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 
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 #ifdef CONFIG_MAGICLINK_PC
261     // noGc
262     pos = os_strstr(pos + 1, "\n");
263     if (pos != NULL) {
264         *pos = '\0';
265         *noGc = atoi(pos + 1);
266         wpa_msg(wpa_s, MSG_INFO, "wpa_magiclink noGc is %d",  *noGc);
267     }
268 #endif
269 
270     return 0;
271 }
272 
273 static struct wpa_ssid *hw_magiclink_add_network(struct wpa_supplicant *wpa_s, char *pssid,
274     const char *pbssid, char *ppsk)
275 {
276     struct wpa_ssid *ssid = wpa_config_add_network(wpa_s->conf);
277     if (!ssid) {
278         return NULL;
279     }
280 
281     wpa_config_set_network_defaults(ssid);
282     hw_magiclink_ctrl_iface_update_network(wpa_s, ssid, "ssid", pssid);
283     hw_magiclink_ctrl_iface_update_network(wpa_s, ssid, "priority", "0");
284 
285     if (strcmp(ppsk, "\"\"") == 0) {
286         wpa_printf(MSG_DEBUG, "key_mgmt is NONE");
287         hw_magiclink_ctrl_iface_update_network(wpa_s, ssid, "key_mgmt", "NONE");
288     } else {
289         hw_magiclink_ctrl_iface_update_network(wpa_s, ssid, "key_mgmt", "WPA-PSK");
290         hw_magiclink_ctrl_iface_update_network(wpa_s, ssid, "psk", ppsk);
291     }
292     if (hwaddr_aton(pbssid, ssid->bssid)) {
293         wpa_printf(MSG_ERROR, "fail to parser bssid");
294         return NULL;
295     }
296     ssid->bssid_set = 1;
297     return ssid;
298 }
299 
300 static int hw_magiclink_connect_known_ap(struct wpa_supplicant *wpa_s, char *cmd)
301 {
302     /* cmd: "SSID BSSID PASSWORD FREQUENCY"
303          "P"DIRECT-xx-xxxx" xx:xx:xx:xx:xx:xx "xxxxxxxx" 2412|2437|2462"
304          "P\"DIRECT-XA-send\" 5a:7f:66:ae:a1:66 \"d9hHbPv0\" 2412" */
305     char *pfreq = NULL;
306     char *ppsk = NULL;
307     char *pbssid = NULL;
308     char *pssid = cmd;
309     int freq;
310     int noGc = 0xFF;
311 
312     if (hw_magiclink_connect_parse_param(wpa_s, cmd, &ppsk, &pbssid, &pfreq, &noGc)) {
313         wpa_printf(MSG_DEBUG, "hw_magiclink_connect_parse_param failed");
314         return -1;
315     }
316     struct wpa_ssid *ssid = hw_magiclink_add_network(wpa_s, pssid, pbssid, ppsk);
317     if (!ssid) {
318         wpa_printf(MSG_ERROR, "hw_magiclink_add_network failed");
319         return -1;
320     }
321     freq = atoi(pfreq);
322     if (hw_magiclink_add_new_scan_res(wpa_s, ssid, freq, noGc)) {
323         wpa_printf(MSG_ERROR, "hw_magiclink_add_new_scan_res failed");
324         return -1;
325     }
326 
327     struct os_reltime now;
328     os_get_reltime(&now);
329     wpa_s->last_scan = now;
330     wpa_s->magic_link_freq = freq;
331     hw_magiclink_scan(wpa_s);
332     wpa_s->disconnected = 0;
333     wpa_s->reassociate = 1;
334     ssid->p2p_group = 1;
335     wpa_s->show_group_started = 1;
336     return 0;
337 }
338 
339 int hw_magiclink_p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd)
340 {
341     enum wpa_driver_if_type iftype;
342     char p[256];
343     wpa_printf(MSG_ERROR, "hw_magiclink_p2p_ctrl_connect");
344     if (!wpa_s || !cmd) {
345         wpa_printf(MSG_ERROR, "%s:wpa_s or cmd is null", __func__);
346         return -1;
347     }
348 
349     os_memset(p, 0, sizeof(p));
350     wpa_s->create_p2p_iface = hw_magiclink_create_iface(wpa_s);
351     iftype = WPA_IF_P2P_GROUP;
352     /*
353      * reltek chip don not support create p2p interface, use p2p0
354      */
355 #ifdef CONFIG_SUPPORT_PLATEFORM_REALTEK
356     struct wpa_supplicant *magiclink_wpa_s = wpa_s;
357 #else
358     if (hw_magiclink_add_group_interface(wpa_s, iftype) < 0) {
359         wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
360             "interface for the group");
361         return -1;
362     }
363 
364     struct wpa_supplicant *magiclink_wpa_s = hw_magiclink_init_group_interface(wpa_s, 0);
365     if (!magiclink_wpa_s) {
366         wpa_printf(MSG_ERROR, "P2P: Failed to get magiclink interface");
367         return -1;
368     }
369 #endif
370 
371     wpa_msg(wpa_s, MSG_INFO, "P2P-INTERFACE-CREATED GC %s",  magiclink_wpa_s->ifname);
372     os_snprintf(p, sizeof(p), "P2P-INTERFACE-CREATED GC %s",  magiclink_wpa_s->ifname);
373 #ifdef MTK_SET_MAGIC_LINK_FLAG
374     magiclink_wpa_s->is_magic_link = 1;
375 #endif
376     wpa_s->global->p2p_group_formation = NULL;
377     return hw_magiclink_connect_known_ap(magiclink_wpa_s, cmd);
378 }
379 
380 int hw_wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int network_id,
381                           int persistent, int freq, int max_band) {
382   int vht = wpa_s->conf->p2p_go_vht;
383   int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
384   struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, network_id);
385   if (ssid == NULL) {
386     return wpas_p2p_group_add(wpa_s, persistent, freq, 0, ht40, vht, max_band,
387                               0, 0, false);
388   } else if (ssid->disabled == 2) {
389     return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, ht40, vht,
390                                          max_band, 0, 0, NULL, 0, 0, false);
391   }
392   return -1;
393 }
394 #endif
395 
396