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