aboutsummaryrefslogtreecommitdiffstats
path: root/package/network/services/hostapd/patches/556-wpa_supplicant-support-Multi-AP-backhaul-STA-onboard.patch
blob: 11c65c71a01b05ab83b9f585fa6b89bfab818ec3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
From 6c4c98db9420a3321bbf091cfc254de5eba4b404 Mon Sep 17 00:00:00 2001
From: Davina Lu <ylu@quantenna.com>
Date: Tue, 15 Jan 2019 19:17:51 +0100
Subject: [PATCH] wpa_supplicant: support Multi-AP backhaul STA onboarding

The Wi-Fi Alliance Multi-AP Specification v1.0 allows onboarding of a
backhaul STA through WPS. To enable this, the backhaul STA needs to add
a Multi-AP IE to the WFA vendor extension element in the WSC M1 message
that indicates it supports the Multi-AP backhaul STA role. The registrar
(if it support Multi-AP onboarding) will respond to that with a WSC M8
message that also contains the Multi-AP IE, and that contains the
credentials for the backhaul SSID (which may be different from the SSID
on which WPS is performed).

Introduce a new parameter to wpas_wps_start_pbc() and allow it to be
set via control interface's new multi_ap=1 parameter of WPS_PBC call.
multi_ap_backhaul_sta is set to 1 in the automatically created SSID.
Thus, if the AP does not support Multi-AP, association will fail and
WPS will be terminated.

Only wps_pbc is supported.

The multi_ap argument is only added to the socket interface, not to the
dbus interface.

Signed-off-by: Davina Lu <ylu@quantenna.com>
Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v4: use argument to wps_pbc instead of a global configuration option
 (requested by Jouni)
---
 src/eap_peer/eap_wsc.c                      | 3 +++
 src/wps/wps.h                               | 6 ++++++
 src/wps/wps_enrollee.c                      | 6 +++++-
 wpa_supplicant/ctrl_iface.c                 | 5 ++++-
 wpa_supplicant/dbus/dbus_new_handlers_wps.c | 2 +-
 wpa_supplicant/dbus/dbus_old_handlers_wps.c | 4 ++--
 wpa_supplicant/events.c                     | 2 +-
 wpa_supplicant/p2p_supplicant.c             | 2 +-
 wpa_supplicant/wps_supplicant.c             | 9 +++++++--
 wpa_supplicant/wps_supplicant.h             | 2 +-
 10 files changed, 31 insertions(+), 10 deletions(-)

--- a/src/eap_peer/eap_wsc.c
+++ b/src/eap_peer/eap_wsc.c
@@ -274,6 +274,9 @@ static void * eap_wsc_init(struct eap_sm
 				      cfg.pin, cfg.pin_len, 0);
 	}
 
+	if (os_strstr(phase1, "multi_ap=1"))
+		wps->multi_ap_backhaul_sta = 1;
+
 	/* Use reduced client timeout for WPS to avoid long wait */
 	if (sm->ClientTimeout > 30)
 		sm->ClientTimeout = 30;
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
@@ -613,6 +613,12 @@ struct wps_context {
 	int ap_setup_locked;
 
 	/**
+	 * multi_ap_backhaul_sta - Whether this is a Multi-AP backhaul STA
+	 * enrollee
+	 */
+	int multi_ap_backhaul_sta;
+
+	/**
 	 * uuid - Own UUID
 	 */
 	u8 uuid[16];
--- a/src/wps/wps_enrollee.c
+++ b/src/wps/wps_enrollee.c
@@ -105,6 +105,7 @@ static struct wpabuf * wps_build_m1(stru
 {
 	struct wpabuf *msg;
 	u16 config_methods;
+	u8 multi_ap_backhaul_sta = 0;
 
 	if (random_get_bytes(wps->nonce_e, WPS_NONCE_LEN) < 0)
 		return NULL;
@@ -134,6 +135,9 @@ static struct wpabuf * wps_build_m1(stru
 				    WPS_CONFIG_PHY_PUSHBUTTON);
 	}
 
+	if (wps->wps->multi_ap_backhaul_sta)
+		multi_ap_backhaul_sta = MULTI_AP_BACKHAUL_STA;
+
 	if (wps_build_version(msg) ||
 	    wps_build_msg_type(msg, WPS_M1) ||
 	    wps_build_uuid_e(msg, wps->uuid_e) ||
@@ -152,7 +156,7 @@ static struct wpabuf * wps_build_m1(stru
 	    wps_build_dev_password_id(msg, wps->dev_pw_id) ||
 	    wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
 	    wps_build_os_version(&wps->wps->dev, msg) ||
-	    wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
+	    wps_build_wfa_ext(msg, 0, NULL, 0, multi_ap_backhaul_sta) ||
 	    wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
 		wpabuf_free(msg);
 		return NULL;
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -1167,6 +1167,7 @@ static int wpa_supplicant_ctrl_iface_wps
 #ifdef CONFIG_AP
 	u8 *_p2p_dev_addr = NULL;
 #endif /* CONFIG_AP */
+	int multi_ap = 0;
 
 	if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
 		_bssid = NULL;
@@ -1184,6 +1185,8 @@ static int wpa_supplicant_ctrl_iface_wps
 		wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
 			   cmd);
 		return -1;
+	} else if (os_strncmp(cmd, "multi_ap=", 9) == 0) {
+		multi_ap = atoi(cmd + 9);
 	}
 
 #ifdef CONFIG_AP
@@ -1191,7 +1194,7 @@ static int wpa_supplicant_ctrl_iface_wps
 		return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
 #endif /* CONFIG_AP */
 
-	return wpas_wps_start_pbc(wpa_s, _bssid, 0);
+	return wpas_wps_start_pbc(wpa_s, _bssid, 0, multi_ap);
 }
 
 
--- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
@@ -289,7 +289,7 @@ DBusMessage * wpas_dbus_handler_wps_star
 		if (ret > 0)
 			os_snprintf(npin, sizeof(npin), "%08d", ret);
 	} else {
-		ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0);
+		ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0, 0);
 	}
 
 	if (ret < 0) {
--- a/wpa_supplicant/dbus/dbus_old_handlers_wps.c
+++ b/wpa_supplicant/dbus/dbus_old_handlers_wps.c
@@ -37,9 +37,9 @@ DBusMessage * wpas_dbus_iface_wps_pbc(DB
 		return wpas_dbus_new_invalid_opts_error(message, NULL);
 
 	if (os_strcmp(arg_bssid, "any") == 0)
-		ret = wpas_wps_start_pbc(wpa_s, NULL, 0);
+		ret = wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
 	else if (!hwaddr_aton(arg_bssid, bssid))
-		ret = wpas_wps_start_pbc(wpa_s, bssid, 0);
+		ret = wpas_wps_start_pbc(wpa_s, bssid, 0, 0);
 	else {
 		return wpas_dbus_new_invalid_opts_error(message,
 							"Invalid BSSID");
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -4816,7 +4816,7 @@ void supplicant_event(void *ctx, enum wp
 		break;
 	case EVENT_WPS_BUTTON_PUSHED:
 #ifdef CONFIG_WPS
-		wpas_wps_start_pbc(wpa_s, NULL, 0);
+		wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
 #endif /* CONFIG_WPS */
 		break;
 	case EVENT_AVOID_FREQUENCIES:
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -1649,7 +1649,7 @@ static void wpas_start_wps_enrollee(stru
 	wpa_supplicant_ap_deinit(wpa_s);
 	wpas_copy_go_neg_results(wpa_s, res);
 	if (res->wps_method == WPS_PBC) {
-		wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1);
+		wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1, 0);
 #ifdef CONFIG_WPS_NFC
 	} else if (res->wps_method == WPS_NFC) {
 		wpas_wps_start_nfc(wpa_s, res->peer_device_addr,
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -1137,9 +1137,10 @@ static void wpas_wps_reassoc(struct wpa_
 
 
 int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
-		       int p2p_group)
+		       int p2p_group, int multi_ap_backhaul_sta)
 {
 	struct wpa_ssid *ssid;
+	char phase1[32];
 
 #ifdef CONFIG_AP
 	if (wpa_s->ap_iface) {
@@ -1177,10 +1178,14 @@ int wpas_wps_start_pbc(struct wpa_suppli
 		}
 	}
 #endif /* CONFIG_P2P */
-	if (wpa_config_set(ssid, "phase1", "\"pbc=1\"", 0) < 0)
+	if (os_snprintf(phase1, sizeof(phase1), "pbc=1%s",
+			multi_ap_backhaul_sta ? " multi_ap=1" : "") ||
+	    wpa_config_set_quoted(ssid, "phase1", phase1) < 0)
 		return -1;
 	if (wpa_s->wps_fragment_size)
 		ssid->eap.fragment_size = wpa_s->wps_fragment_size;
+	if (multi_ap_backhaul_sta)
+		ssid->multi_ap_backhaul_sta = 1;
 	wpa_supplicant_wps_event(wpa_s, WPS_EV_PBC_ACTIVE, NULL);
 	eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
 			       wpa_s, NULL);
--- a/wpa_supplicant/wps_supplicant.h
+++ b/wpa_supplicant/wps_supplicant.h
@@ -30,7 +30,7 @@ void wpas_wps_deinit(struct wpa_supplica
 int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s);
 enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid);
 int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
-		       int p2p_group);
+		       int p2p_group, int multi_ap_backhaul_sta);
 int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
 		       const char *pin, int p2p_group, u16 dev_pw_id);
 void wpas_wps_pbc_overlap(struct wpa_supplicant *wpa_s);