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