xref: /wlan-dirver/utils/sigma-dut/dpp.c (revision ecb49d8b82a0e1604f15dd66d70c20a5557639ef)
1d86e5828SJouni Malinen /*
2d86e5828SJouni Malinen  * Sigma Control API DUT (station/AP/sniffer)
3d86e5828SJouni Malinen  * Copyright (c) 2017, Qualcomm Atheros, Inc.
4c12ea4afSJouni Malinen  * Copyright (c) 2018, The Linux Foundation
5d86e5828SJouni Malinen  * All Rights Reserved.
6d86e5828SJouni Malinen  * Licensed under the Clear BSD license. See README for more details.
7d86e5828SJouni Malinen  */
8d86e5828SJouni Malinen 
9d86e5828SJouni Malinen #include "sigma_dut.h"
101a38cc37SJouni Malinen #include <sys/wait.h>
11d86e5828SJouni Malinen #include "wpa_ctrl.h"
12d86e5828SJouni Malinen #include "wpa_helpers.h"
13d86e5828SJouni Malinen 
141a38cc37SJouni Malinen #ifdef ANDROID
15bc9e055cSSrinivas Dasari char *dpp_qrcode_file = "/sdcard/wpadebug_qrdata.txt";
161a38cc37SJouni Malinen #endif /* ANDROID */
17bc9e055cSSrinivas Dasari 
18d86e5828SJouni Malinen 
19d86e5828SJouni Malinen static int sigma_dut_is_ap(struct sigma_dut *dut)
20d86e5828SJouni Malinen {
21d86e5828SJouni Malinen 	return dut->device_type == AP_unknown ||
22d86e5828SJouni Malinen 		dut->device_type == AP_testbed ||
23d86e5828SJouni Malinen 		dut->device_type == AP_dut;
24d86e5828SJouni Malinen }
25d86e5828SJouni Malinen 
26d86e5828SJouni Malinen 
27d86e5828SJouni Malinen static int dpp_hostapd_run(struct sigma_dut *dut)
28d86e5828SJouni Malinen {
29d86e5828SJouni Malinen 	if (dut->hostapd_running)
30d86e5828SJouni Malinen 		return 0;
31d86e5828SJouni Malinen 
32d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO,
33d86e5828SJouni Malinen 			"Starting hostapd in unconfigured state for DPP");
34d86e5828SJouni Malinen 	snprintf(dut->ap_ssid, sizeof(dut->ap_ssid), "unconfigured");
359149afc1Spriyadharshini gowthaman 	if (!dut->ap_oper_chn)
36d86e5828SJouni Malinen 		dut->ap_channel = 11;
37d86e5828SJouni Malinen 	dut->ap_is_dual = 0;
38fa2d7c3aSpriyadharshini gowthaman 	dut->ap_mode = dut->ap_channel <= 14 ? AP_11ng : AP_11na;
39d86e5828SJouni Malinen 	dut->ap_key_mgmt = AP_OPEN;
40d86e5828SJouni Malinen 	dut->ap_cipher = AP_PLAIN;
41d86e5828SJouni Malinen 	return cmd_ap_config_commit(dut, NULL, NULL) == 1 ? 0 : -1;
42d86e5828SJouni Malinen }
43d86e5828SJouni Malinen 
44d86e5828SJouni Malinen 
45d86e5828SJouni Malinen static const char * dpp_get_curve(struct sigma_cmd *cmd, const char *arg)
46d86e5828SJouni Malinen {
47d86e5828SJouni Malinen 	const char *val = get_param(cmd, arg);
48d86e5828SJouni Malinen 
49d86e5828SJouni Malinen 	if (!val)
50d86e5828SJouni Malinen 		val = "P-256";
51d86e5828SJouni Malinen 	else if (strcasecmp(val, "BP-256R1") == 0)
52d86e5828SJouni Malinen 		val = "BP-256";
53d86e5828SJouni Malinen 	else if (strcasecmp(val, "BP-384R1") == 0)
54d86e5828SJouni Malinen 		val = "BP-384";
55d86e5828SJouni Malinen 	else if (strcasecmp(val, "BP-512R1") == 0)
56d86e5828SJouni Malinen 		val = "BP-512";
57d86e5828SJouni Malinen 
58d86e5828SJouni Malinen 	return val;
59d86e5828SJouni Malinen }
60d86e5828SJouni Malinen 
61d86e5828SJouni Malinen 
62d86e5828SJouni Malinen static int dpp_get_local_bootstrap(struct sigma_dut *dut,
63d86e5828SJouni Malinen 				   struct sigma_conn *conn,
64bc9e055cSSrinivas Dasari 				   struct sigma_cmd *cmd, int send_result,
65bc9e055cSSrinivas Dasari 				   int *success)
66d86e5828SJouni Malinen {
67d86e5828SJouni Malinen 	const char *curve = dpp_get_curve(cmd, "DPPCryptoIdentifier");
68d86e5828SJouni Malinen 	const char *bs = get_param(cmd, "DPPBS");
694161c3f0SJouni Malinen 	const char *chan_list = get_param(cmd, "DPPChannelList");
704161c3f0SJouni Malinen 	char *pos, mac[50], buf[200], resp[1000], hex[2000];
71d86e5828SJouni Malinen 	const char *ifname = get_station_ifname();
72d86e5828SJouni Malinen 
73bc9e055cSSrinivas Dasari 	if (success)
74bc9e055cSSrinivas Dasari 		*success = 0;
75d86e5828SJouni Malinen 	if (strcasecmp(bs, "QR") != 0) {
76d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
77d86e5828SJouni Malinen 			  "errorCode,Unsupported DPPBS");
78d86e5828SJouni Malinen 		return 0;
79d86e5828SJouni Malinen 	}
80d86e5828SJouni Malinen 
81d86e5828SJouni Malinen 	if (sigma_dut_is_ap(dut)) {
82d86e5828SJouni Malinen 		u8 bssid[ETH_ALEN];
83d86e5828SJouni Malinen 
84d86e5828SJouni Malinen 		if (!dut->hostapd_ifname) {
85d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_ERROR,
86d86e5828SJouni Malinen 					"hostapd ifname not specified (-j)");
87d86e5828SJouni Malinen 			return -2;
88d86e5828SJouni Malinen 		}
89d86e5828SJouni Malinen 		ifname = dut->hostapd_ifname;
90d86e5828SJouni Malinen 		if (get_hwaddr(dut->hostapd_ifname, bssid) < 0) {
91d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_ERROR,
92d86e5828SJouni Malinen 					"Could not get MAC address for %s",
93d86e5828SJouni Malinen 					dut->hostapd_ifname);
94d86e5828SJouni Malinen 			return -2;
95d86e5828SJouni Malinen 		}
96d86e5828SJouni Malinen 		snprintf(mac, sizeof(mac), "%02x%02x%02x%02x%02x%02x",
97d86e5828SJouni Malinen 			 bssid[0], bssid[1], bssid[2],
98d86e5828SJouni Malinen 			 bssid[3], bssid[4], bssid[5]);
99d86e5828SJouni Malinen 	} else {
100d86e5828SJouni Malinen 		if (get_wpa_status(ifname, "address", mac, sizeof(mac)) < 0)
101d86e5828SJouni Malinen 			return -2;
102d86e5828SJouni Malinen 	}
103d86e5828SJouni Malinen 
104d86e5828SJouni Malinen 	pos = mac;
105d86e5828SJouni Malinen 	while (*pos) {
106d86e5828SJouni Malinen 		if (*pos == ':')
107d86e5828SJouni Malinen 			memmove(pos, pos + 1, strlen(pos));
108d86e5828SJouni Malinen 		else
109d86e5828SJouni Malinen 			pos++;
110d86e5828SJouni Malinen 	}
111d86e5828SJouni Malinen 
112d86e5828SJouni Malinen 	if (sigma_dut_is_ap(dut) && dpp_hostapd_run(dut) < 0) {
113d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
114d86e5828SJouni Malinen 			  "errorCode,Failed to start hostapd");
115d86e5828SJouni Malinen 		return 0;
116d86e5828SJouni Malinen 	}
117d86e5828SJouni Malinen 
1184161c3f0SJouni Malinen 	if (chan_list &&
1194161c3f0SJouni Malinen 	    (strcmp(chan_list, "0/0") == 0 || chan_list[0] == '\0')) {
1204161c3f0SJouni Malinen 		/* No channel list */
1214161c3f0SJouni Malinen 		snprintf(buf, sizeof(buf),
1224161c3f0SJouni Malinen 			 "DPP_BOOTSTRAP_GEN type=qrcode curve=%s mac=%s",
1234161c3f0SJouni Malinen 			 curve, mac);
1244161c3f0SJouni Malinen 	} else if (chan_list) {
1254161c3f0SJouni Malinen 		/* Channel list override (CTT case) - space separated tuple(s)
1264161c3f0SJouni Malinen 		 * of OperatingClass/Channel; convert to wpa_supplicant/hostapd
1274161c3f0SJouni Malinen 		 * format: comma separated tuples */
1284161c3f0SJouni Malinen 		strlcpy(resp, chan_list, sizeof(resp));
1294161c3f0SJouni Malinen 		for (pos = resp; *pos; pos++) {
1304161c3f0SJouni Malinen 			if (*pos == ' ')
1314161c3f0SJouni Malinen 				*pos = ',';
1324161c3f0SJouni Malinen 		}
1334161c3f0SJouni Malinen 		snprintf(buf, sizeof(buf),
1344161c3f0SJouni Malinen 			 "DPP_BOOTSTRAP_GEN type=qrcode curve=%s chan=%s mac=%s",
1354161c3f0SJouni Malinen 			 curve, resp, mac);
1364161c3f0SJouni Malinen 	} else {
1374161c3f0SJouni Malinen 		/* Default channel list (normal DUT case) */
1384161c3f0SJouni Malinen 		snprintf(buf, sizeof(buf),
1394161c3f0SJouni Malinen 			 "DPP_BOOTSTRAP_GEN type=qrcode curve=%s chan=81/11 mac=%s",
1404161c3f0SJouni Malinen 			 curve, mac);
1414161c3f0SJouni Malinen 	}
1424161c3f0SJouni Malinen 
143d86e5828SJouni Malinen 	if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0)
144d86e5828SJouni Malinen 		return -2;
145d86e5828SJouni Malinen 	if (strncmp(resp, "FAIL", 4) == 0)
146d86e5828SJouni Malinen 		return -2;
147d86e5828SJouni Malinen 	dut->dpp_local_bootstrap = atoi(resp);
148d86e5828SJouni Malinen 	snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d",
149d86e5828SJouni Malinen 		 atoi(resp));
150d86e5828SJouni Malinen 	if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0)
151d86e5828SJouni Malinen 		return -2;
152d86e5828SJouni Malinen 	if (strncmp(resp, "FAIL", 4) == 0)
153d86e5828SJouni Malinen 		return -2;
154d86e5828SJouni Malinen 
155d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", resp);
156bc9e055cSSrinivas Dasari 
157bc9e055cSSrinivas Dasari 	if (send_result) {
158d86e5828SJouni Malinen 		ascii2hexstr(resp, hex);
159d86e5828SJouni Malinen 		snprintf(resp, sizeof(resp), "BootstrappingData,%s", hex);
160d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, resp);
161bc9e055cSSrinivas Dasari 	}
162bc9e055cSSrinivas Dasari 
163bc9e055cSSrinivas Dasari 	if (success)
164bc9e055cSSrinivas Dasari 		*success = 1;
165d86e5828SJouni Malinen 	return 0;
166d86e5828SJouni Malinen }
167d86e5828SJouni Malinen 
168d86e5828SJouni Malinen 
169d86e5828SJouni Malinen static int dpp_set_peer_bootstrap(struct sigma_dut *dut,
170d86e5828SJouni Malinen 				  struct sigma_conn *conn,
171d86e5828SJouni Malinen 				  struct sigma_cmd *cmd)
172d86e5828SJouni Malinen {
173d86e5828SJouni Malinen 	const char *val = get_param(cmd, "DPPBootstrappingdata");
174b1dd21f8SJouni Malinen 	char uri[1000];
175d86e5828SJouni Malinen 	int res;
176d86e5828SJouni Malinen 
177d86e5828SJouni Malinen 	if (!val) {
178d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
179d86e5828SJouni Malinen 			  "errorCode,Missing DPPBootstrappingdata");
180d86e5828SJouni Malinen 		return 0;
181d86e5828SJouni Malinen 	}
182d86e5828SJouni Malinen 
183d86e5828SJouni Malinen 	res = parse_hexstr(val, (unsigned char *) uri, sizeof(uri));
184d86e5828SJouni Malinen 	if (res < 0 || (size_t) res >= sizeof(uri))
185d86e5828SJouni Malinen 		return -2;
186d86e5828SJouni Malinen 	uri[res] = '\0';
187d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", uri);
188b1dd21f8SJouni Malinen 	free(dut->dpp_peer_uri);
189b1dd21f8SJouni Malinen 	dut->dpp_peer_uri = strdup(uri);
190d86e5828SJouni Malinen 
191d86e5828SJouni Malinen 	return 1;
192d86e5828SJouni Malinen }
193d86e5828SJouni Malinen 
194d86e5828SJouni Malinen 
195d86e5828SJouni Malinen static int dpp_hostapd_conf_update(struct sigma_dut *dut,
196d86e5828SJouni Malinen 				   struct sigma_conn *conn, const char *ifname,
197d86e5828SJouni Malinen 				   struct wpa_ctrl *ctrl)
198d86e5828SJouni Malinen {
199d86e5828SJouni Malinen 	int res;
200d86e5828SJouni Malinen 	char buf[2000], buf2[2500], *pos, *pos2;
201b4c5e3b8SJouni Malinen 	const char *conf_data_events[] = {
202b4c5e3b8SJouni Malinen 		"DPP-CONNECTOR",
203b4c5e3b8SJouni Malinen 		"DPP-CONFOBJ-PASS",
204b4c5e3b8SJouni Malinen 		"DPP-CONFOBJ-PSK",
205b4c5e3b8SJouni Malinen 		NULL
206b4c5e3b8SJouni Malinen 	};
207d86e5828SJouni Malinen 
208d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO,
209d86e5828SJouni Malinen 			"Update hostapd configuration based on DPP Config Object");
210d86e5828SJouni Malinen 
211d86e5828SJouni Malinen 	if (wpa_command(ifname, "SET wpa 2") < 0 ||
212d86e5828SJouni Malinen 	    wpa_command(ifname, "SET wpa_key_mgmt DPP") < 0 ||
2130d34723dSJouni Malinen 	    wpa_command(ifname, "SET ieee80211w 1") < 0 ||
214d86e5828SJouni Malinen 	    wpa_command(ifname, "SET rsn_pairwise CCMP") < 0) {
215d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
216d86e5828SJouni Malinen 			  "errorCode,Failed to update AP security parameters");
217d86e5828SJouni Malinen 		goto out;
218d86e5828SJouni Malinen 	}
219d86e5828SJouni Malinen 
220d86e5828SJouni Malinen 	res = get_wpa_cli_event(dut, ctrl, "DPP-CONFOBJ-SSID",
221d86e5828SJouni Malinen 				buf, sizeof(buf));
222d86e5828SJouni Malinen 	if (res < 0) {
223d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
224d86e5828SJouni Malinen 			  "errorCode,No DPP-CONFOBJ-SSID");
225d86e5828SJouni Malinen 		goto out;
226d86e5828SJouni Malinen 	}
227d86e5828SJouni Malinen 	pos = strchr(buf, ' ');
228d86e5828SJouni Malinen 	if (!pos)
229d86e5828SJouni Malinen 		return -2;
230d86e5828SJouni Malinen 	pos++;
231d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO,
232d86e5828SJouni Malinen 			"DPP: Config Object SSID: %s", pos);
233d86e5828SJouni Malinen 	snprintf(buf2, sizeof(buf2), "SET ssid %s", pos);
234d86e5828SJouni Malinen 	if (wpa_command(ifname, buf2) < 0) {
235d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
236d86e5828SJouni Malinen 			  "errorCode,Failed to update AP SSID");
237d86e5828SJouni Malinen 		goto out;
238d86e5828SJouni Malinen 	}
239d86e5828SJouni Malinen 
240b4c5e3b8SJouni Malinen 	res = get_wpa_cli_events(dut, ctrl, conf_data_events, buf, sizeof(buf));
241d86e5828SJouni Malinen 	if (res < 0) {
242d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
243b4c5e3b8SJouni Malinen 			  "errorCode,No DPP-CONNECTOR/DPP-CONFOBJ-PASS/PSK");
244d86e5828SJouni Malinen 		goto out;
245d86e5828SJouni Malinen 	}
246b4c5e3b8SJouni Malinen 
247b4c5e3b8SJouni Malinen 	if (!strstr(buf, "DPP-CONNECTOR")) {
248b4c5e3b8SJouni Malinen 		if (wpa_command(ifname, "SET wpa_key_mgmt WPA-PSK") < 0) {
249b4c5e3b8SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
250b4c5e3b8SJouni Malinen 				  "errorCode,Failed to update AP security parameters");
251b4c5e3b8SJouni Malinen 			goto out;
252b4c5e3b8SJouni Malinen 		}
253b4c5e3b8SJouni Malinen 
254b4c5e3b8SJouni Malinen 		pos = strchr(buf, ' ');
255b4c5e3b8SJouni Malinen 		if (!pos)
256b4c5e3b8SJouni Malinen 			return -2;
257b4c5e3b8SJouni Malinen 		pos++;
258b4c5e3b8SJouni Malinen 		if (strstr(buf, "DPP-CONFOBJ-PASS")) {
259b4c5e3b8SJouni Malinen 			char pass[64];
260b4c5e3b8SJouni Malinen 			int pass_len;
261b4c5e3b8SJouni Malinen 
262b4c5e3b8SJouni Malinen 			pass_len = parse_hexstr(pos, (u8 *) pass, sizeof(pass));
263fddb7eadSJouni Malinen 			if (pass_len < 0 || (size_t) pass_len >= sizeof(pass))
264b4c5e3b8SJouni Malinen 				return -2;
265b4c5e3b8SJouni Malinen 			pass[pass_len] = '\0';
266b4c5e3b8SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
267b4c5e3b8SJouni Malinen 					"DPP: Passphrase: %s", pass);
268b4c5e3b8SJouni Malinen 			snprintf(buf2, sizeof(buf2), "SET wpa_passphrase %s",
269b4c5e3b8SJouni Malinen 				 pass);
270b4c5e3b8SJouni Malinen 			if (wpa_command(ifname, buf2) < 0) {
271b4c5e3b8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
272b4c5e3b8SJouni Malinen 					  "errorCode,Failed to set passphrase");
273b4c5e3b8SJouni Malinen 				goto out;
274b4c5e3b8SJouni Malinen 			}
275b4c5e3b8SJouni Malinen 		} else if (strstr(buf, "DPP-CONFOBJ-PSK")) {
276b4c5e3b8SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
277b4c5e3b8SJouni Malinen 					"DPP: PSK: %s", pos);
278b4c5e3b8SJouni Malinen 			snprintf(buf2, sizeof(buf2), "SET wpa_psk %s", pos);
279b4c5e3b8SJouni Malinen 			if (wpa_command(ifname, buf2) < 0) {
280b4c5e3b8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
281b4c5e3b8SJouni Malinen 					  "errorCode,Failed to set PSK");
282b4c5e3b8SJouni Malinen 				goto out;
283b4c5e3b8SJouni Malinen 			}
284b4c5e3b8SJouni Malinen 		}
285b4c5e3b8SJouni Malinen 
286b4c5e3b8SJouni Malinen 		goto skip_dpp_akm;
287b4c5e3b8SJouni Malinen 	}
288b4c5e3b8SJouni Malinen 
289d86e5828SJouni Malinen 	pos = strchr(buf, ' ');
290d86e5828SJouni Malinen 	if (!pos)
291d86e5828SJouni Malinen 		return -2;
292d86e5828SJouni Malinen 	pos++;
293d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO, "DPP: Connector: %s", pos);
294d86e5828SJouni Malinen 	snprintf(buf2, sizeof(buf2), "SET dpp_connector %s", pos);
295d86e5828SJouni Malinen 	if (wpa_command(ifname, buf2) < 0) {
296d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
297d86e5828SJouni Malinen 			  "errorCode,Failed to update AP Connector");
298d86e5828SJouni Malinen 		goto out;
299d86e5828SJouni Malinen 	}
300d86e5828SJouni Malinen 
301d86e5828SJouni Malinen 	res = get_wpa_cli_event(dut, ctrl, "DPP-C-SIGN-KEY",
302d86e5828SJouni Malinen 				buf, sizeof(buf));
303d86e5828SJouni Malinen 	if (res < 0) {
304d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
305d86e5828SJouni Malinen 			  "errorCode,No DPP-C-SIGN-KEY");
306d86e5828SJouni Malinen 		goto out;
307d86e5828SJouni Malinen 	}
308d86e5828SJouni Malinen 	pos = strchr(buf, ' ');
309d86e5828SJouni Malinen 	if (!pos)
310d86e5828SJouni Malinen 		return -2;
311d86e5828SJouni Malinen 	pos++;
312d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO, "DPP: C-sign-key: %s", pos);
313d86e5828SJouni Malinen 	snprintf(buf2, sizeof(buf2), "SET dpp_csign %s", pos);
314d86e5828SJouni Malinen 	if (wpa_command(ifname, buf2) < 0) {
315d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
316d86e5828SJouni Malinen 			  "errorCode,Failed to update AP C-sign-key");
317d86e5828SJouni Malinen 		goto out;
318d86e5828SJouni Malinen 	}
319d86e5828SJouni Malinen 
320d86e5828SJouni Malinen 	res = get_wpa_cli_event(dut, ctrl, "DPP-NET-ACCESS-KEY",
321d86e5828SJouni Malinen 				buf, sizeof(buf));
322d86e5828SJouni Malinen 	if (res < 0) {
323d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
324d86e5828SJouni Malinen 			  "errorCode,No DPP-NET-ACCESS-KEY");
325d86e5828SJouni Malinen 		goto out;
326d86e5828SJouni Malinen 	}
327d86e5828SJouni Malinen 	pos = strchr(buf, ' ');
328d86e5828SJouni Malinen 	if (!pos)
329d86e5828SJouni Malinen 		return -2;
330d86e5828SJouni Malinen 	pos++;
331d86e5828SJouni Malinen 	pos2 = strchr(pos, ' ');
332d86e5828SJouni Malinen 	if (pos2)
333d86e5828SJouni Malinen 		*pos2++ = '\0';
334d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO, "DPP: netAccessKey: %s", pos);
335d86e5828SJouni Malinen 	snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey %s", pos);
336d86e5828SJouni Malinen 	if (wpa_command(ifname, buf2) < 0) {
337d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
338d86e5828SJouni Malinen 			  "errorCode,Failed to update AP netAccessKey");
339d86e5828SJouni Malinen 		goto out;
340d86e5828SJouni Malinen 	}
341d86e5828SJouni Malinen 	if (pos2) {
342d86e5828SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_INFO,
343d86e5828SJouni Malinen 				"DPP: netAccessKey expiry: %s", pos2);
344d86e5828SJouni Malinen 		snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey_expiry %s",
345d86e5828SJouni Malinen 			 pos2);
346d86e5828SJouni Malinen 		if (wpa_command(ifname, buf2) < 0) {
347d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
348d86e5828SJouni Malinen 				  "errorCode,Failed to update AP netAccessKey expiry");
349d86e5828SJouni Malinen 			goto out;
350d86e5828SJouni Malinen 		}
351d86e5828SJouni Malinen 	}
352b4c5e3b8SJouni Malinen skip_dpp_akm:
353d86e5828SJouni Malinen 
354d86e5828SJouni Malinen 	if (wpa_command(ifname, "DISABLE") < 0 ||
355d86e5828SJouni Malinen 	    wpa_command(ifname, "ENABLE") < 0) {
356d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
357d86e5828SJouni Malinen 			  "errorCode,Failed to update AP configuration");
358d86e5828SJouni Malinen 		goto out;
359d86e5828SJouni Malinen 	}
360d86e5828SJouni Malinen 
361d86e5828SJouni Malinen 	res = get_wpa_cli_event(dut, ctrl, "AP-ENABLED", buf, sizeof(buf));
362d86e5828SJouni Malinen 	if (res < 0) {
363d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,No AP-ENABLED");
364d86e5828SJouni Malinen 		goto out;
365d86e5828SJouni Malinen 	}
366d86e5828SJouni Malinen 
367d86e5828SJouni Malinen 	return 1;
368d86e5828SJouni Malinen out:
369d86e5828SJouni Malinen 	return 0;
370d86e5828SJouni Malinen }
371d86e5828SJouni Malinen 
372d86e5828SJouni Malinen 
373772299f1SJouni Malinen struct dpp_test_info {
374772299f1SJouni Malinen 	const char *step;
375772299f1SJouni Malinen 	const char *frame;
376772299f1SJouni Malinen 	const char *attr;
377772299f1SJouni Malinen 	int value;
378772299f1SJouni Malinen };
379772299f1SJouni Malinen 
380772299f1SJouni Malinen static const struct dpp_test_info dpp_tests[] = {
381772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationRequest", "WrappedData", 1 },
382772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "WrappedData", 2 },
383f96fcee3SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "PrimaryWrappedData", 2 },
384772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationConfirm", "WrappedData", 3 },
385772299f1SJouni Malinen 	{ "InvalidValue", "PKEXCRRequest", "WrappedData", 4 },
386772299f1SJouni Malinen 	{ "InvalidValue", "PKEXCRResponse", "WrappedData", 5 },
387772299f1SJouni Malinen 	{ "InvalidValue", "ConfigurationRequest", "WrappedData", 6 },
388772299f1SJouni Malinen 	{ "InvalidValue", "ConfigurationResponse", "WrappedData", 7 },
389772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationRequest", "InitCapabilities", 8 },
390772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationRequest", "RespBSKeyHash", 10 },
391772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationRequest", "InitBSKeyHash", 11 },
392772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationRequest", "InitProtocolKey", 12 },
393772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationRequest", "InitNonce", 13 },
394772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationRequest", "InitCapabilities", 14 },
395772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationRequest", "WrappedData", 15 },
396772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "DPPStatus", 16 },
397772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "RespBSKeyHash", 17 },
398772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "InitBSKeyHash", 18 },
399772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "RespProtocolKey", 19 },
400772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "RespNonce", 20 },
401772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "InitNonce", 21 },
402772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "RespCapabilities",
403772299f1SJouni Malinen 	  22 },
404772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "RespAuthTag", 23 },
405772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "WrappedData", 24 },
406f96fcee3SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "PrimaryWrappedData",
407f96fcee3SJouni Malinen 	  24 },
408772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationConfirm", "DPPStatus", 25 },
409772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationConfirm", "RespBSKeyHash", 26 },
410772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationConfirm", "InitBSKeyHash", 27 },
411772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationConfirm", "InitAuthTag", 28 },
412772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationConfirm", "WrappedData", 29 },
413772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "InitNonce", 30 },
414772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "RespCapabilities", 31 },
415772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "RespAuthTag", 32 },
416772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationConfirm", "InitAuthTag", 33 },
417772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXExchangeRequest", "FiniteCyclicGroup", 34 },
418772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXExchangeRequest", "EncryptedKey", 35 },
419772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXExchangeResponse", "DPPStatus", 36 },
420772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXExchangeResponse", "EncryptedKey", 37 },
421772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXCRRequest", "BSKey", 38 },
422772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXCRRequest", "InitAuthTag", 39 },
423772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXCRRequest", "WrappedData", 40 },
424772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXCRResponse", "BSKey", 41 },
425772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXCRResponse", "RespAuthTag", 42 },
426772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXCRResponse", "WrappedData", 43 },
427772299f1SJouni Malinen 	{ "InvalidValue", "PKEXExchangeRequest", "EncryptedKey", 44 },
428772299f1SJouni Malinen 	{ "InvalidValue", "PKEXExchangeResponse", "EncryptedKey", 45 },
429772299f1SJouni Malinen 	{ "InvalidValue", "PKEXExchangeResponse", "DPPStatus", 46 },
430772299f1SJouni Malinen 	{ "InvalidValue", "PKEXCRRequest", "BSKey", 47 },
431772299f1SJouni Malinen 	{ "InvalidValue", "PKEXCRResponse", "BSKey", 48 },
432772299f1SJouni Malinen 	{ "InvalidValue", "PKEXCRRequest", "InitAuthTag", 49 },
433772299f1SJouni Malinen 	{ "InvalidValue", "PKEXCRResponse", "RespAuthTag", 50 },
434772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationRequest", "EnrolleeNonce", 51 },
435772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationRequest", "ConfigAttr", 52 },
436772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationRequest", "WrappedData", 53 },
437772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationResponse", "EnrolleeNonce", 54 },
438772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationResponse", "ConfigObj", 55 },
439772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationResponse", "DPPStatus", 56 },
440772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationResponse", "WrappedData", 57 },
441772299f1SJouni Malinen 	{ "InvalidValue", "ConfigurationResponse", "DPPStatus", 58 },
442772299f1SJouni Malinen 	{ "InvalidValue", "ConfigurationResponse", "EnrolleeNonce", 59 },
44353558e0fSJouni Malinen 	{ "MissingAttribute", "PeerDiscoveryRequest", "TransactionID", 60 },
44453558e0fSJouni Malinen 	{ "MissingAttribute", "PeerDiscoveryRequest", "Connector", 61 },
44553558e0fSJouni Malinen 	{ "MissingAttribute", "PeerDiscoveryResponse", "TransactionID", 62 },
44653558e0fSJouni Malinen 	{ "MissingAttribute", "PeerDiscoveryResponse", "DPPStatus", 63 },
44753558e0fSJouni Malinen 	{ "MissingAttribute", "PeerDiscoveryResponse", "Connector", 64 },
448ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationRequest", "InitProtocolKey", 66 },
449ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "RespProtocolKey", 67 },
450ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationRequest", "RespBSKeyHash", 68 },
451ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationRequest", "InitBSKeyHash", 69 },
452ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "RespBSKeyHash", 70 },
453ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "InitBSKeyHash", 71 },
454ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationConfirm", "RespBSKeyHash", 72 },
455ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationConfirm", "InitBSKeyHash", 73 },
456ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "DPPStatus", 74 },
457ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationConfirm", "DPPStatus", 75 },
458ae624487SJouni Malinen 	{ "InvalidValue", "ConfigurationRequest", "ConfigAttr", 76 },
459ae624487SJouni Malinen 	{ "InvalidValue", "PeerDiscoveryResponse", "TransactionID", 77 },
460ae624487SJouni Malinen 	{ "InvalidValue", "PeerDiscoveryResponse", "DPPStatus", 78 },
461ae624487SJouni Malinen 	{ "InvalidValue", "PeerDiscoveryResponse", "Connector", 79 },
462ae624487SJouni Malinen 	{ "InvalidValue", "PeerDiscoveryRequest", "Connector", 80 },
46367795a76SJouni Malinen 	{ "InvalidValue", "AuthenticationRequest", "InitNonce", 81 },
464188839b6SJouni Malinen 	{ "InvalidValue", "PeerDiscoveryRequest", "TransactionID", 82 },
465188839b6SJouni Malinen 	{ "InvalidValue", "ConfigurationRequest", "EnrolleeNonce", 83 },
4663a6b92a6SJouni Malinen 	{ "Timeout", "PKEXExchangeResponse", NULL, 84 },
4673a6b92a6SJouni Malinen 	{ "Timeout", "PKEXCRRequest", NULL, 85 },
4683a6b92a6SJouni Malinen 	{ "Timeout", "PKEXCRResponse", NULL, 86 },
4693a6b92a6SJouni Malinen 	{ "Timeout", "AuthenticationRequest", NULL, 87 },
4703a6b92a6SJouni Malinen 	{ "Timeout", "AuthenticationResponse", NULL, 88 },
4713a6b92a6SJouni Malinen 	{ "Timeout", "AuthenticationConfirm", NULL, 89 },
4723a6b92a6SJouni Malinen 	{ "Timeout", "ConfigurationRequest", NULL, 90 },
473772299f1SJouni Malinen 	{ NULL, NULL, NULL, 0 }
474772299f1SJouni Malinen };
475772299f1SJouni Malinen 
476772299f1SJouni Malinen 
477772299f1SJouni Malinen static int dpp_get_test(const char *step, const char *frame, const char *attr)
478772299f1SJouni Malinen {
479772299f1SJouni Malinen 	int i;
480772299f1SJouni Malinen 
481772299f1SJouni Malinen 	for (i = 0; dpp_tests[i].step; i++) {
482772299f1SJouni Malinen 		if (strcasecmp(step, dpp_tests[i].step) == 0 &&
483772299f1SJouni Malinen 		    strcasecmp(frame, dpp_tests[i].frame) == 0 &&
4843a6b92a6SJouni Malinen 		    ((!attr && dpp_tests[i].attr == NULL) ||
4853a6b92a6SJouni Malinen 		     (attr && strcasecmp(attr, dpp_tests[i].attr) == 0)))
486772299f1SJouni Malinen 			return dpp_tests[i].value;
487772299f1SJouni Malinen 	}
488772299f1SJouni Malinen 
489772299f1SJouni Malinen 	return -1;
490772299f1SJouni Malinen }
491772299f1SJouni Malinen 
492772299f1SJouni Malinen 
4936792ff4dSJouni Malinen static int dpp_wait_tx(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
4946792ff4dSJouni Malinen 		       int frame_type)
4956792ff4dSJouni Malinen {
4966792ff4dSJouni Malinen 	char buf[200], tmp[20];
4976792ff4dSJouni Malinen 	int res;
4986792ff4dSJouni Malinen 
4996792ff4dSJouni Malinen 	snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
5006792ff4dSJouni Malinen 	for (;;) {
5016792ff4dSJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf));
5026792ff4dSJouni Malinen 		if (res < 0)
5036792ff4dSJouni Malinen 			return -1;
5046792ff4dSJouni Malinen 		if (strstr(buf, tmp) != NULL)
5056792ff4dSJouni Malinen 			break;
5066792ff4dSJouni Malinen 	}
5076792ff4dSJouni Malinen 
5086792ff4dSJouni Malinen 	return 0;
5096792ff4dSJouni Malinen }
5106792ff4dSJouni Malinen 
5116792ff4dSJouni Malinen 
512772299f1SJouni Malinen static int dpp_wait_tx_status(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
513772299f1SJouni Malinen 			      int frame_type)
514772299f1SJouni Malinen {
515772299f1SJouni Malinen 	char buf[200], tmp[20];
516772299f1SJouni Malinen 	int res;
517772299f1SJouni Malinen 
518772299f1SJouni Malinen 	snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
519772299f1SJouni Malinen 	for (;;) {
520772299f1SJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf));
521772299f1SJouni Malinen 		if (res < 0)
522772299f1SJouni Malinen 			return -1;
523772299f1SJouni Malinen 		if (strstr(buf, tmp) != NULL)
524772299f1SJouni Malinen 			break;
525772299f1SJouni Malinen 	}
526772299f1SJouni Malinen 
527772299f1SJouni Malinen 	res = get_wpa_cli_event(dut, ctrl, "DPP-TX-STATUS",
528772299f1SJouni Malinen 				buf, sizeof(buf));
529772299f1SJouni Malinen 	if (res < 0 || strstr(buf, "result=FAILED") != NULL)
530772299f1SJouni Malinen 		return -1;
531772299f1SJouni Malinen 
532772299f1SJouni Malinen 	return 0;
533772299f1SJouni Malinen }
534772299f1SJouni Malinen 
535772299f1SJouni Malinen 
5363a6b92a6SJouni Malinen static int dpp_wait_rx(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
5373e4344e7SJouni Malinen 		       int frame_type, unsigned int max_wait)
5383a6b92a6SJouni Malinen {
5393a6b92a6SJouni Malinen 	char buf[200], tmp[20];
5403a6b92a6SJouni Malinen 	int res;
5419a3415c2SJouni Malinen 	unsigned int old_timeout;
5429a3415c2SJouni Malinen 
5439a3415c2SJouni Malinen 	old_timeout = dut->default_timeout;
5449a3415c2SJouni Malinen 	if (max_wait > 0 && dut->default_timeout > max_wait)
5459a3415c2SJouni Malinen 		dut->default_timeout = max_wait;
5463a6b92a6SJouni Malinen 
5473a6b92a6SJouni Malinen 	snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
5483a6b92a6SJouni Malinen 	for (;;) {
5493a6b92a6SJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "DPP-RX", buf, sizeof(buf));
5509a3415c2SJouni Malinen 		if (res < 0) {
5519a3415c2SJouni Malinen 			dut->default_timeout = old_timeout;
5523a6b92a6SJouni Malinen 			return -1;
5539a3415c2SJouni Malinen 		}
5543a6b92a6SJouni Malinen 		if (strstr(buf, tmp) != NULL)
5553a6b92a6SJouni Malinen 			break;
5563a6b92a6SJouni Malinen 	}
5573a6b92a6SJouni Malinen 
5589a3415c2SJouni Malinen 	dut->default_timeout = old_timeout;
5599a3415c2SJouni Malinen 	return 0;
5609a3415c2SJouni Malinen }
5619a3415c2SJouni Malinen 
5629a3415c2SJouni Malinen 
5639a3415c2SJouni Malinen static int dpp_wait_rx_conf_req(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
5643e4344e7SJouni Malinen 				unsigned int max_wait)
5659a3415c2SJouni Malinen {
5669a3415c2SJouni Malinen 	char buf[200];
5679a3415c2SJouni Malinen 	int res;
5689a3415c2SJouni Malinen 	unsigned int old_timeout;
5699a3415c2SJouni Malinen 
5709a3415c2SJouni Malinen 	old_timeout = dut->default_timeout;
5719a3415c2SJouni Malinen 	if (max_wait > 0 && dut->default_timeout > max_wait)
5729a3415c2SJouni Malinen 		dut->default_timeout = max_wait;
5739a3415c2SJouni Malinen 
5749a3415c2SJouni Malinen 	for (;;) {
5759a3415c2SJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-REQ-RX",
5769a3415c2SJouni Malinen 					buf, sizeof(buf));
5779a3415c2SJouni Malinen 		if (res < 0) {
5789a3415c2SJouni Malinen 			dut->default_timeout = old_timeout;
5799a3415c2SJouni Malinen 			return -1;
5809a3415c2SJouni Malinen 		}
5819a3415c2SJouni Malinen 
5829a3415c2SJouni Malinen 		break;
5839a3415c2SJouni Malinen 	}
5849a3415c2SJouni Malinen 
5859a3415c2SJouni Malinen 	dut->default_timeout = old_timeout;
5863a6b92a6SJouni Malinen 	return 0;
5873a6b92a6SJouni Malinen }
5883a6b92a6SJouni Malinen 
5893a6b92a6SJouni Malinen 
590bc9e055cSSrinivas Dasari static int dpp_scan_peer_qrcode(struct sigma_dut *dut)
591d86e5828SJouni Malinen {
5921a38cc37SJouni Malinen #ifdef ANDROID
593bc9e055cSSrinivas Dasari 	char buf[100];
594bc9e055cSSrinivas Dasari 	char *buf2 = NULL;
595bc9e055cSSrinivas Dasari 	FILE *fp = NULL;
596bc9e055cSSrinivas Dasari 	uint32_t length;
597bc9e055cSSrinivas Dasari 	unsigned int count;
598bc9e055cSSrinivas Dasari 
599bc9e055cSSrinivas Dasari 	unlink(dpp_qrcode_file);
600bc9e055cSSrinivas Dasari 
601bc9e055cSSrinivas Dasari 	snprintf(buf, sizeof(buf),
60207458342SJouni Malinen 		 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeReadActivity");
603bc9e055cSSrinivas Dasari 	if (system(buf) != 0) {
60407458342SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
60507458342SJouni Malinen 				"Failed to launch QR Code scanner");
606d86e5828SJouni Malinen 		return -1;
607d86e5828SJouni Malinen 	}
608d86e5828SJouni Malinen 
609bc9e055cSSrinivas Dasari 	count = 0;
610bc9e055cSSrinivas Dasari 	while (!(fp = fopen(dpp_qrcode_file, "r"))) {
611bc9e055cSSrinivas Dasari 		if (count > dut->default_timeout) {
612bc9e055cSSrinivas Dasari 			sigma_dut_print(dut, DUT_MSG_ERROR,
613bc9e055cSSrinivas Dasari 					"Failed to open dpp_qrcode_file - QR Code scanning timed out");
614bc9e055cSSrinivas Dasari 			return -1;
615bc9e055cSSrinivas Dasari 		}
616bc9e055cSSrinivas Dasari 
617bc9e055cSSrinivas Dasari 		sleep(1);
618bc9e055cSSrinivas Dasari 		count++;
619bc9e055cSSrinivas Dasari 	}
620bc9e055cSSrinivas Dasari 
621bc9e055cSSrinivas Dasari 	if (fseek(fp, 0, SEEK_END) < 0 || (length = ftell(fp)) <= 0 ||
622bc9e055cSSrinivas Dasari 	    fseek(fp, 0, SEEK_SET) < 0) {
623bc9e055cSSrinivas Dasari 		sigma_dut_print(dut, DUT_MSG_ERROR,
624bc9e055cSSrinivas Dasari 				"Failed to get QR Code result file length");
625bc9e055cSSrinivas Dasari 		fclose(fp);
626bc9e055cSSrinivas Dasari 		return -1;
627bc9e055cSSrinivas Dasari 	}
628bc9e055cSSrinivas Dasari 
629bc9e055cSSrinivas Dasari 	buf2 = malloc(length + 1);
630bc9e055cSSrinivas Dasari 	if (!buf2) {
631bc9e055cSSrinivas Dasari 		fclose(fp);
632bc9e055cSSrinivas Dasari 		return -1;
633bc9e055cSSrinivas Dasari 	}
634bc9e055cSSrinivas Dasari 
635bc9e055cSSrinivas Dasari 	if (fread(buf2, 1, length, fp) != length) {
636bc9e055cSSrinivas Dasari 		fclose(fp);
637bc9e055cSSrinivas Dasari 		free(buf2);
638bc9e055cSSrinivas Dasari 		return -1;
639bc9e055cSSrinivas Dasari 	}
640bc9e055cSSrinivas Dasari 
641bc9e055cSSrinivas Dasari 	fclose(fp);
642bc9e055cSSrinivas Dasari 	buf2[length] = '\0';
643bc9e055cSSrinivas Dasari 
644bc9e055cSSrinivas Dasari 	free(dut->dpp_peer_uri);
645bc9e055cSSrinivas Dasari 	dut->dpp_peer_uri = strdup(buf2);
646bc9e055cSSrinivas Dasari 	free(buf2);
647bc9e055cSSrinivas Dasari 	return 0;
6481a38cc37SJouni Malinen #else /* ANDROID */
6491a38cc37SJouni Malinen 	pid_t pid;
6501a38cc37SJouni Malinen 	int pid_status;
6511a38cc37SJouni Malinen 	int pipe_out[2];
6521a38cc37SJouni Malinen 	char buf[4000], *pos;
6531a38cc37SJouni Malinen 	ssize_t len;
6541a38cc37SJouni Malinen 	int res = -1, ret;
6551a38cc37SJouni Malinen 	struct timeval tv;
6561a38cc37SJouni Malinen 	fd_set rfd;
6571a38cc37SJouni Malinen 
6581a38cc37SJouni Malinen 	if (pipe(pipe_out) != 0) {
6591a38cc37SJouni Malinen 		perror("pipe");
6601a38cc37SJouni Malinen 		return -1;
6611a38cc37SJouni Malinen 	}
6621a38cc37SJouni Malinen 
6631a38cc37SJouni Malinen 	pid = fork();
6641a38cc37SJouni Malinen 	if (pid < 0) {
6651a38cc37SJouni Malinen 		perror("fork");
6661a38cc37SJouni Malinen 		close(pipe_out[0]);
6671a38cc37SJouni Malinen 		close(pipe_out[1]);
6681a38cc37SJouni Malinen 		return -1;
6691a38cc37SJouni Malinen 	}
6701a38cc37SJouni Malinen 
6711a38cc37SJouni Malinen 	if (pid == 0) {
6721a38cc37SJouni Malinen 		char *argv[4] = { "zbarcam", "--raw", "--prescale=320x240",
6731a38cc37SJouni Malinen 				  NULL };
6741a38cc37SJouni Malinen 
6751a38cc37SJouni Malinen 		dup2(pipe_out[1], STDOUT_FILENO);
6761a38cc37SJouni Malinen 		close(pipe_out[0]);
6771a38cc37SJouni Malinen 		close(pipe_out[1]);
6781a38cc37SJouni Malinen 		execv("/usr/bin/zbarcam", argv);
6791a38cc37SJouni Malinen 		perror("execv");
6801a38cc37SJouni Malinen 		exit(0);
6811a38cc37SJouni Malinen 		return -1;
6821a38cc37SJouni Malinen 	}
6831a38cc37SJouni Malinen 
6841a38cc37SJouni Malinen 	close(pipe_out[1]);
6851a38cc37SJouni Malinen 
6861a38cc37SJouni Malinen 	FD_ZERO(&rfd);
6871a38cc37SJouni Malinen 	FD_SET(pipe_out[0], &rfd);
6881a38cc37SJouni Malinen 	tv.tv_sec = dut->default_timeout;
6891a38cc37SJouni Malinen 	tv.tv_usec = 0;
6901a38cc37SJouni Malinen 
6911a38cc37SJouni Malinen 	ret = select(pipe_out[0] + 1, &rfd, NULL, NULL, &tv);
6921a38cc37SJouni Malinen 	if (ret < 0) {
6931a38cc37SJouni Malinen 		perror("select");
6941a38cc37SJouni Malinen 		goto out;
6951a38cc37SJouni Malinen 	}
6961a38cc37SJouni Malinen 	if (ret == 0) {
6971a38cc37SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG,
6981a38cc37SJouni Malinen 				"QR Code scanning timed out");
6991a38cc37SJouni Malinen 		goto out;
7001a38cc37SJouni Malinen 	}
7011a38cc37SJouni Malinen 
7021a38cc37SJouni Malinen 	len = read(pipe_out[0], buf, sizeof(buf));
7031a38cc37SJouni Malinen 	if (len <= 0)
7041a38cc37SJouni Malinen 		goto out;
7051a38cc37SJouni Malinen 	if (len == sizeof(buf))
7061a38cc37SJouni Malinen 		len--;
7071a38cc37SJouni Malinen 	buf[len] = '\0';
7081a38cc37SJouni Malinen 	pos = strchr(buf, '\n');
7091a38cc37SJouni Malinen 	if (pos)
7101a38cc37SJouni Malinen 		*pos = '\0';
7111a38cc37SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "URI from QR scanner: %s", buf);
7121a38cc37SJouni Malinen 
7131a38cc37SJouni Malinen 	free(dut->dpp_peer_uri);
7141a38cc37SJouni Malinen 	dut->dpp_peer_uri = strdup(buf);
7151a38cc37SJouni Malinen 	res = 0;
7161a38cc37SJouni Malinen out:
7171a38cc37SJouni Malinen 	close(pipe_out[0]);
7181a38cc37SJouni Malinen 	kill(pid, SIGTERM);
7191a38cc37SJouni Malinen 	waitpid(pid, &pid_status, 0);
7201a38cc37SJouni Malinen 
7211a38cc37SJouni Malinen 	return res;
7221a38cc37SJouni Malinen #endif /* ANDROID */
723bc9e055cSSrinivas Dasari }
724bc9e055cSSrinivas Dasari 
725bc9e055cSSrinivas Dasari 
726bc9e055cSSrinivas Dasari static int dpp_display_own_qrcode(struct sigma_dut *dut)
727bc9e055cSSrinivas Dasari {
728bc9e055cSSrinivas Dasari 	char buf[200], resp[2000];
729bc9e055cSSrinivas Dasari 	const char *ifname = get_station_ifname();
7301a38cc37SJouni Malinen #ifdef ANDROID
731bc9e055cSSrinivas Dasari 	FILE *fp;
7321a38cc37SJouni Malinen #else /* ANDROID */
7331a38cc37SJouni Malinen 	pid_t pid;
7341a38cc37SJouni Malinen 	int pid_status;
7351a38cc37SJouni Malinen #endif /* ANDROID */
736bc9e055cSSrinivas Dasari 
737bc9e055cSSrinivas Dasari 	snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d",
738bc9e055cSSrinivas Dasari 		 dut->dpp_local_bootstrap);
739bc9e055cSSrinivas Dasari 	if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 ||
740bc9e055cSSrinivas Dasari 	    strncmp(resp, "FAIL", 4) == 0)
741bc9e055cSSrinivas Dasari 		return -2;
7421a38cc37SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Own bootstrap URI: %s", resp);
743bc9e055cSSrinivas Dasari 
7441a38cc37SJouni Malinen #ifdef ANDROID
745bc9e055cSSrinivas Dasari 	unlink(dpp_qrcode_file);
746bc9e055cSSrinivas Dasari 
747bc9e055cSSrinivas Dasari 	fp = fopen(dpp_qrcode_file, "w");
748bc9e055cSSrinivas Dasari 	if (!fp) {
749bc9e055cSSrinivas Dasari 		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open file %s",
750bc9e055cSSrinivas Dasari 				dpp_qrcode_file);
751bc9e055cSSrinivas Dasari 		return -2;
752bc9e055cSSrinivas Dasari 	}
753bc9e055cSSrinivas Dasari 
754bc9e055cSSrinivas Dasari 	fwrite(resp, 1, strlen(resp), fp);
755bc9e055cSSrinivas Dasari 	fclose(fp);
756bc9e055cSSrinivas Dasari 
757bc9e055cSSrinivas Dasari 	snprintf(buf, sizeof(buf),
758bc9e055cSSrinivas Dasari 		 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeDisplayActivity");
759bc9e055cSSrinivas Dasari 	if (system(buf) != 0) {
760bc9e055cSSrinivas Dasari 		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to display QR Code");
761bc9e055cSSrinivas Dasari 		return -1;
762bc9e055cSSrinivas Dasari 	}
7631a38cc37SJouni Malinen #else /* ANDROID */
7641a38cc37SJouni Malinen 	pid = fork();
7651a38cc37SJouni Malinen 	if (pid < 0) {
7661a38cc37SJouni Malinen 		perror("fork");
7671a38cc37SJouni Malinen 		return -1;
7681a38cc37SJouni Malinen 	}
7691a38cc37SJouni Malinen 
7701a38cc37SJouni Malinen 	if (pid == 0) {
7711a38cc37SJouni Malinen 		char *argv[3] = { "qr", resp, NULL };
7721a38cc37SJouni Malinen 
7731a38cc37SJouni Malinen 		execv("/usr/bin/qr", argv);
7741a38cc37SJouni Malinen 		perror("execv");
7751a38cc37SJouni Malinen 		exit(0);
7761a38cc37SJouni Malinen 		return -1;
7771a38cc37SJouni Malinen 	}
7781a38cc37SJouni Malinen 
7791a38cc37SJouni Malinen 	waitpid(pid, &pid_status, 0);
7801a38cc37SJouni Malinen #endif /* ANDROID */
781bc9e055cSSrinivas Dasari 
782bc9e055cSSrinivas Dasari 	return 0;
783bc9e055cSSrinivas Dasari }
784bc9e055cSSrinivas Dasari 
785d86e5828SJouni Malinen 
786d86e5828SJouni Malinen static int dpp_automatic_dpp(struct sigma_dut *dut,
787d86e5828SJouni Malinen 			     struct sigma_conn *conn,
788d86e5828SJouni Malinen 			     struct sigma_cmd *cmd)
789d86e5828SJouni Malinen {
790d86e5828SJouni Malinen 	const char *bs = get_param(cmd, "DPPBS");
791d86e5828SJouni Malinen 	const char *auth_role = get_param(cmd, "DPPAuthRole");
792d86e5828SJouni Malinen 	const char *prov_role = get_param(cmd, "DPPProvisioningRole");
793d86e5828SJouni Malinen 	const char *pkex_code = get_param(cmd, "DPPPKEXCode");
794d86e5828SJouni Malinen 	const char *pkex_code_id = get_param(cmd, "DPPPKEXCodeIdentifier");
795d86e5828SJouni Malinen 	const char *wait_conn = get_param(cmd, "DPPWaitForConnect");
796d86e5828SJouni Malinen 	const char *self_conf = get_param(cmd, "DPPSelfConfigure");
797772299f1SJouni Malinen 	const char *step = get_param(cmd, "DPPStep");
798772299f1SJouni Malinen 	const char *frametype = get_param(cmd, "DPPFrameType");
799772299f1SJouni Malinen 	const char *attr = get_param(cmd, "DPPIEAttribute");
800bc9e055cSSrinivas Dasari 	const char *action_type = get_param(cmd, "DPPActionType");
801d86e5828SJouni Malinen 	const char *role;
802d86e5828SJouni Malinen 	const char *val;
803d86e5828SJouni Malinen 	const char *conf_role;
804d86e5828SJouni Malinen 	int conf_index = -1;
805d86e5828SJouni Malinen 	char buf[2000];
806d86e5828SJouni Malinen 	char conf_ssid[100];
807d86e5828SJouni Malinen 	char conf_pass[100];
808d86e5828SJouni Malinen 	char pkex_identifier[200];
809d86e5828SJouni Malinen 	struct wpa_ctrl *ctrl;
810d86e5828SJouni Malinen 	int res;
811d86e5828SJouni Malinen 	unsigned int old_timeout;
812d86e5828SJouni Malinen 	int own_pkex_id = -1;
813d86e5828SJouni Malinen 	const char *ifname = get_station_ifname();
814d86e5828SJouni Malinen 	const char *auth_events[] = {
815d86e5828SJouni Malinen 		"DPP-AUTH-SUCCESS",
816d86e5828SJouni Malinen 		"DPP-NOT-COMPATIBLE",
817d86e5828SJouni Malinen 		"DPP-RESPONSE-PENDING",
818d86e5828SJouni Malinen 		"DPP-SCAN-PEER-QR-CODE",
819bc9e055cSSrinivas Dasari 		"DPP-AUTH-DIRECTION",
820d86e5828SJouni Malinen 		NULL
821d86e5828SJouni Malinen 	};
822d86e5828SJouni Malinen 	const char *conf_events[] = {
823d86e5828SJouni Malinen 		"DPP-CONF-RECEIVED",
824d86e5828SJouni Malinen 		"DPP-CONF-SENT",
825d86e5828SJouni Malinen 		"DPP-CONF-FAILED",
826d86e5828SJouni Malinen 		NULL
827d86e5828SJouni Malinen 	};
828d86e5828SJouni Malinen 	const char *conn_events[] = {
829d86e5828SJouni Malinen 		"PMKSA-CACHE-ADDED",
830d86e5828SJouni Malinen 		"CTRL-EVENT-CONNECTED",
831d86e5828SJouni Malinen 		NULL
832d86e5828SJouni Malinen 	};
8333d291f70SJouni Malinen 	const char *groups_override = NULL;
834772299f1SJouni Malinen 	const char *result;
835d1e22f76SJouni Malinen 	int check_mutual = 0;
836e89cdbf5SJouni Malinen 	int enrollee_ap;
837f2fa0d00SJouni Malinen 	int force_gas_fragm = 0;
838d86e5828SJouni Malinen 
839d86e5828SJouni Malinen 	if (!wait_conn)
840d86e5828SJouni Malinen 		wait_conn = "no";
841d86e5828SJouni Malinen 	if (!self_conf)
842d86e5828SJouni Malinen 		self_conf = "no";
843d86e5828SJouni Malinen 
844d86e5828SJouni Malinen 	if (!auth_role) {
845d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
846d86e5828SJouni Malinen 			  "errorCode,Missing DPPAuthRole");
847d86e5828SJouni Malinen 		return 0;
848d86e5828SJouni Malinen 	}
849d86e5828SJouni Malinen 
850d86e5828SJouni Malinen 	if (!prov_role) {
851d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
852d86e5828SJouni Malinen 			  "errorCode,Missing DPPProvisioningRole");
853d86e5828SJouni Malinen 		return 0;
854d86e5828SJouni Malinen 	}
855d86e5828SJouni Malinen 
856e89cdbf5SJouni Malinen 	val = get_param(cmd, "DPPConfEnrolleeRole");
857e89cdbf5SJouni Malinen 	if (val)
858e89cdbf5SJouni Malinen 		enrollee_ap = strcasecmp(val, "AP") == 0;
859e89cdbf5SJouni Malinen 	else
860e89cdbf5SJouni Malinen 		enrollee_ap = sigma_dut_is_ap(dut);
861e89cdbf5SJouni Malinen 
8623a6b92a6SJouni Malinen 	if ((step || frametype) && (!step || !frametype)) {
863772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
864772299f1SJouni Malinen 			  "errorCode,Invalid DPPStep,DPPFrameType,DPPIEAttribute combination");
865772299f1SJouni Malinen 		return 0;
866772299f1SJouni Malinen 	}
867772299f1SJouni Malinen 
868d86e5828SJouni Malinen 	if (sigma_dut_is_ap(dut)) {
869d86e5828SJouni Malinen 		if (!dut->hostapd_ifname) {
870d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_ERROR,
871d86e5828SJouni Malinen 					"hostapd ifname not specified (-j)");
872d86e5828SJouni Malinen 			return -2;
873d86e5828SJouni Malinen 		}
874d86e5828SJouni Malinen 		ifname = dut->hostapd_ifname;
875d86e5828SJouni Malinen 
876d86e5828SJouni Malinen 		if (dpp_hostapd_run(dut) < 0) {
877d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
878d86e5828SJouni Malinen 				  "errorCode,Failed to start hostapd");
879d86e5828SJouni Malinen 			return 0;
880d86e5828SJouni Malinen 		}
881d86e5828SJouni Malinen 	}
882d86e5828SJouni Malinen 
88367acb0cfSJouni Malinen 	if (strcasecmp(prov_role, "Configurator") == 0 ||
88467acb0cfSJouni Malinen 	    strcasecmp(prov_role, "Both") == 0) {
885d86e5828SJouni Malinen 		if (dut->dpp_conf_id < 0) {
886d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
887d86e5828SJouni Malinen 				 "DPP_CONFIGURATOR_ADD curve=%s",
888d86e5828SJouni Malinen 				 dpp_get_curve(cmd, "DPPSigningKeyECC"));
889d86e5828SJouni Malinen 			if (wpa_command_resp(ifname, buf,
890d86e5828SJouni Malinen 					     buf, sizeof(buf)) < 0) {
891d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
892d86e5828SJouni Malinen 					  "errorCode,Failed to set up configurator");
893d86e5828SJouni Malinen 				return 0;
894d86e5828SJouni Malinen 			}
895d86e5828SJouni Malinen 			dut->dpp_conf_id = atoi(buf);
896d86e5828SJouni Malinen 		}
89767acb0cfSJouni Malinen 		if (strcasecmp(prov_role, "Configurator") == 0)
898d86e5828SJouni Malinen 			role = "configurator";
89967acb0cfSJouni Malinen 		else
90067acb0cfSJouni Malinen 			role = "either";
901d86e5828SJouni Malinen 	} else if (strcasecmp(prov_role, "Enrollee") == 0) {
902d86e5828SJouni Malinen 		role = "enrollee";
903d86e5828SJouni Malinen 	} else {
904d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
905d86e5828SJouni Malinen 			  "errorCode,Unknown DPPProvisioningRole");
906d86e5828SJouni Malinen 		return 0;
907d86e5828SJouni Malinen 	}
908d86e5828SJouni Malinen 
909d86e5828SJouni Malinen 	pkex_identifier[0] = '\0';
910d86e5828SJouni Malinen 	if (strcasecmp(bs, "PKEX") == 0) {
9114f47a272SJouni Malinen 		if (sigma_dut_is_ap(dut) && dut->ap_channel != 6) {
9124f47a272SJouni Malinen 			/* For now, have to make operating channel match DPP
9134f47a272SJouni Malinen 			 * listen channel. This should be removed once hostapd
9144f47a272SJouni Malinen 			 * has support for DPP listen on non-operating channel.
9154f47a272SJouni Malinen 			 */
9164f47a272SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
9174f47a272SJouni Malinen 					"Update hostapd operating channel to match listen needs");
9184f47a272SJouni Malinen 			dut->ap_channel = 6;
919b4de1962Spriyadharshini gowthaman 
920b4de1962Spriyadharshini gowthaman 			if (get_driver_type() == DRIVER_OPENWRT) {
921b4de1962Spriyadharshini gowthaman 				snprintf(buf, sizeof(buf),
922b4de1962Spriyadharshini gowthaman 					 "iwconfig %s channel %d",
923b4de1962Spriyadharshini gowthaman 					 dut->hostapd_ifname, dut->ap_channel);
924b4de1962Spriyadharshini gowthaman 				run_system(dut, buf);
925b4de1962Spriyadharshini gowthaman 			}
926b4de1962Spriyadharshini gowthaman 
9274f47a272SJouni Malinen 			if (wpa_command(ifname, "SET channel 6") < 0 ||
9284f47a272SJouni Malinen 			    wpa_command(ifname, "DISABLE") < 0 ||
9294f47a272SJouni Malinen 			    wpa_command(ifname, "ENABLE") < 0) {
9304f47a272SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
9314f47a272SJouni Malinen 					  "errorCode,Failed to update channel");
9324f47a272SJouni Malinen 				return 0;
9334f47a272SJouni Malinen 			}
9344f47a272SJouni Malinen 		}
9354f47a272SJouni Malinen 
936d86e5828SJouni Malinen 		if (!pkex_code) {
937d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
938d86e5828SJouni Malinen 				  "errorCode,Missing DPPPKEXCode");
939d86e5828SJouni Malinen 			return 0;
940d86e5828SJouni Malinen 		}
941d86e5828SJouni Malinen 
942d86e5828SJouni Malinen 		if (pkex_code_id)
943d86e5828SJouni Malinen 			snprintf(pkex_identifier, sizeof(pkex_identifier),
944d86e5828SJouni Malinen 				 "identifier=%s ", pkex_code_id);
945d86e5828SJouni Malinen 
946d86e5828SJouni Malinen 		snprintf(buf, sizeof(buf),
947d86e5828SJouni Malinen 			 "DPP_BOOTSTRAP_GEN type=pkex curve=%s",
948d86e5828SJouni Malinen 			 dpp_get_curve(cmd, "DPPCryptoIdentifier"));
949d86e5828SJouni Malinen 		if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) {
950d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
951d86e5828SJouni Malinen 				  "errorCode,Failed to set up PKEX");
952d86e5828SJouni Malinen 			return 0;
953d86e5828SJouni Malinen 		}
954d86e5828SJouni Malinen 		own_pkex_id = atoi(buf);
955d86e5828SJouni Malinen 	}
956d86e5828SJouni Malinen 
957d86e5828SJouni Malinen 	ctrl = open_wpa_mon(ifname);
958d86e5828SJouni Malinen 	if (!ctrl) {
959d86e5828SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
960d86e5828SJouni Malinen 				"Failed to open wpa_supplicant monitor connection");
961d86e5828SJouni Malinen 		return -2;
962d86e5828SJouni Malinen 	}
963d86e5828SJouni Malinen 
964d86e5828SJouni Malinen 	old_timeout = dut->default_timeout;
965d86e5828SJouni Malinen 	val = get_param(cmd, "DPPTimeout");
966d86e5828SJouni Malinen 	if (val && atoi(val) > 0) {
967d86e5828SJouni Malinen 		dut->default_timeout = atoi(val);
968d86e5828SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u",
969d86e5828SJouni Malinen 				dut->default_timeout);
970d86e5828SJouni Malinen 	}
971d86e5828SJouni Malinen 
972d86e5828SJouni Malinen 	conf_ssid[0] = '\0';
973d86e5828SJouni Malinen 	conf_pass[0] = '\0';
974d86e5828SJouni Malinen 	val = get_param(cmd, "DPPConfIndex");
975d86e5828SJouni Malinen 	if (val)
976d86e5828SJouni Malinen 		conf_index = atoi(val);
977d86e5828SJouni Malinen 	switch (conf_index) {
978258cc26aSJouni Malinen 	case -1:
979258cc26aSJouni Malinen 		conf_role = NULL;
980258cc26aSJouni Malinen 		break;
981d86e5828SJouni Malinen 	case 1:
982d86e5828SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
983d86e5828SJouni Malinen 		snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
984e89cdbf5SJouni Malinen 		if (enrollee_ap) {
985d86e5828SJouni Malinen 			conf_role = "ap-dpp";
9863d291f70SJouni Malinen 			groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"ap\"}]";
9873d291f70SJouni Malinen 		} else {
988d86e5828SJouni Malinen 			conf_role = "sta-dpp";
9893d291f70SJouni Malinen 			groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"sta\"}]";
9903d291f70SJouni Malinen 		}
991d86e5828SJouni Malinen 		break;
992d86e5828SJouni Malinen 	case 2:
993d86e5828SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
994d86e5828SJouni Malinen 		snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
9958f81cdfaSJouni Malinen 		snprintf(conf_pass, sizeof(conf_pass),
9968f81cdfaSJouni Malinen 			 "psk=10506e102ad1e7f95112f6b127675bb8344dacacea60403f3fa4055aec85b0fc");
997e89cdbf5SJouni Malinen 		if (enrollee_ap)
998d86e5828SJouni Malinen 			conf_role = "ap-psk";
999d86e5828SJouni Malinen 		else
1000d86e5828SJouni Malinen 			conf_role = "sta-psk";
1001d86e5828SJouni Malinen 		break;
1002d86e5828SJouni Malinen 	case 3:
1003d86e5828SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
1004d86e5828SJouni Malinen 		snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1005d86e5828SJouni Malinen 		ascii2hexstr("ThisIsDppPassphrase", buf);
1006d86e5828SJouni Malinen 		snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
1007e89cdbf5SJouni Malinen 		if (enrollee_ap)
1008d86e5828SJouni Malinen 			conf_role = "ap-psk";
1009d86e5828SJouni Malinen 		else
1010d86e5828SJouni Malinen 			conf_role = "sta-psk";
1011d86e5828SJouni Malinen 		break;
10123d291f70SJouni Malinen 	case 4:
10133d291f70SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
10143d291f70SJouni Malinen 		snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1015e89cdbf5SJouni Malinen 		if (enrollee_ap) {
10163d291f70SJouni Malinen 			conf_role = "ap-dpp";
10173d291f70SJouni Malinen 			groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA2\",\"netRole\":\"ap\"}]";
10183d291f70SJouni Malinen 		} else {
10193d291f70SJouni Malinen 			conf_role = "sta-dpp";
10203d291f70SJouni Malinen 			groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA2\",\"netRole\":\"sta\"}]";
10213d291f70SJouni Malinen 		}
10223d291f70SJouni Malinen 		break;
10237d031c77SJouni Malinen 	case 5:
10247d031c77SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
10257d031c77SJouni Malinen 		snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
10267d031c77SJouni Malinen 		ascii2hexstr("ThisIsDppPassphrase", buf);
10277d031c77SJouni Malinen 		snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
10287d031c77SJouni Malinen 		if (enrollee_ap)
10297d031c77SJouni Malinen 			conf_role = "ap-sae";
10307d031c77SJouni Malinen 		else
10317d031c77SJouni Malinen 			conf_role = "sta-sae";
10327d031c77SJouni Malinen 		break;
10337d031c77SJouni Malinen 	case 6:
10347d031c77SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
10357d031c77SJouni Malinen 		snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
10367d031c77SJouni Malinen 		ascii2hexstr("ThisIsDppPassphrase", buf);
10377d031c77SJouni Malinen 		snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
10387d031c77SJouni Malinen 		if (enrollee_ap)
10397d031c77SJouni Malinen 			conf_role = "ap-psk-sae";
10407d031c77SJouni Malinen 		else
10417d031c77SJouni Malinen 			conf_role = "sta-psk-sae";
10427d031c77SJouni Malinen 		break;
1043f2fa0d00SJouni Malinen 	case 7:
1044f2fa0d00SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
1045f2fa0d00SJouni Malinen 		snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1046f2fa0d00SJouni Malinen 		if (enrollee_ap) {
1047f2fa0d00SJouni Malinen 			conf_role = "ap-dpp";
1048f2fa0d00SJouni Malinen 			groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"ap\"}]";
1049f2fa0d00SJouni Malinen 		} else {
1050f2fa0d00SJouni Malinen 			conf_role = "sta-dpp";
1051f2fa0d00SJouni Malinen 			groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"sta\"}]";
1052f2fa0d00SJouni Malinen 		}
1053f2fa0d00SJouni Malinen 		force_gas_fragm = 1;
1054f2fa0d00SJouni Malinen 		break;
1055f7490768SJouni Malinen 	default:
1056f7490768SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
1057f7490768SJouni Malinen 			  "errorCode,Unsupported DPPConfIndex");
1058f7490768SJouni Malinen 		goto out;
1059d86e5828SJouni Malinen 	}
1060d86e5828SJouni Malinen 
10613d291f70SJouni Malinen 	if (groups_override) {
10622b2230fbSJouni Malinen 		snprintf(buf, sizeof(buf), "SET dpp_groups_override %s",
10632b2230fbSJouni Malinen 			 groups_override);
10643d291f70SJouni Malinen 		if (wpa_command(ifname, buf) < 0) {
10653d291f70SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
10663d291f70SJouni Malinen 				  "errorCode,Failed to set cred:groups");
10673d291f70SJouni Malinen 			goto out;
10683d291f70SJouni Malinen 		}
10693d291f70SJouni Malinen 	}
10703d291f70SJouni Malinen 
10712b2230fbSJouni Malinen 	if (force_gas_fragm) {
10722b2230fbSJouni Malinen 		char spaces[1500];
10732b2230fbSJouni Malinen 
10742b2230fbSJouni Malinen 		memset(spaces, ' ', sizeof(spaces));
10752b2230fbSJouni Malinen 		spaces[sizeof(spaces) - 1] = '\0';
10762b2230fbSJouni Malinen 
10772b2230fbSJouni Malinen 		snprintf(buf, sizeof(buf),
10782b2230fbSJouni Malinen 			 "SET dpp_discovery_override {\"ssid\":\"DPPNET01\"}%s",
10792b2230fbSJouni Malinen 			 spaces);
10802b2230fbSJouni Malinen 		if (wpa_command(ifname, buf) < 0) {
10812b2230fbSJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
10822b2230fbSJouni Malinen 				  "errorCode,Failed to set discovery override");
10832b2230fbSJouni Malinen 			goto out;
10842b2230fbSJouni Malinen 		}
10852b2230fbSJouni Malinen 	}
10862b2230fbSJouni Malinen 
1087772299f1SJouni Malinen 	if (step) {
1088772299f1SJouni Malinen 		int test;
1089772299f1SJouni Malinen 
1090772299f1SJouni Malinen 		test = dpp_get_test(step, frametype, attr);
1091772299f1SJouni Malinen 		if (test <= 0) {
1092772299f1SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1093772299f1SJouni Malinen 				  "errorCode,Unsupported DPPStep/DPPFrameType/DPPIEAttribute");
1094772299f1SJouni Malinen 			goto out;
1095772299f1SJouni Malinen 		}
1096772299f1SJouni Malinen 
1097772299f1SJouni Malinen 		snprintf(buf, sizeof(buf), "SET dpp_test %d", test);
1098772299f1SJouni Malinen 		if (wpa_command(ifname, buf) < 0) {
1099772299f1SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1100772299f1SJouni Malinen 				  "errorCode,Failed to set dpp_test");
1101772299f1SJouni Malinen 			goto out;
1102772299f1SJouni Malinen 		}
1103772299f1SJouni Malinen 	} else {
1104772299f1SJouni Malinen 		wpa_command(ifname, "SET dpp_test 0");
1105772299f1SJouni Malinen 	}
1106772299f1SJouni Malinen 
1107fbb268d7SJouni Malinen 	if (strcasecmp(self_conf, "Yes") == 0) {
1108fbb268d7SJouni Malinen 		if (strcasecmp(prov_role, "Configurator") != 0) {
1109fbb268d7SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1110fbb268d7SJouni Malinen 				  "errorCode,Invalid DPPSelfConfigure use - only allowed for Configurator role");
1111fbb268d7SJouni Malinen 			goto out;
1112fbb268d7SJouni Malinen 		}
1113fbb268d7SJouni Malinen 		if (!conf_role) {
1114fbb268d7SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1115fbb268d7SJouni Malinen 				  "errorCode,Missing DPPConfIndex");
1116fbb268d7SJouni Malinen 			goto out;
1117fbb268d7SJouni Malinen 		}
1118fbb268d7SJouni Malinen 
1119fbb268d7SJouni Malinen 		snprintf(buf, sizeof(buf),
1120fbb268d7SJouni Malinen 			 "DPP_CONFIGURATOR_SIGN  conf=%s %s %s configurator=%d",
1121fbb268d7SJouni Malinen 			 conf_role, conf_ssid, conf_pass, dut->dpp_conf_id);
1122fbb268d7SJouni Malinen 		if (wpa_command(ifname, buf) < 0) {
1123fbb268d7SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1124fbb268d7SJouni Malinen 				  "errorCode,Failed to initiate DPP self-configuration");
1125fbb268d7SJouni Malinen 			goto out;
1126fbb268d7SJouni Malinen 		}
1127174db64fSJouni Malinen 		if (sigma_dut_is_ap(dut))
1128174db64fSJouni Malinen 			goto update_ap;
1129fbb268d7SJouni Malinen 		goto wait_connect;
1130fbb268d7SJouni Malinen 	} else if (strcasecmp(auth_role, "Initiator") == 0) {
1131d86e5828SJouni Malinen 		char own_txt[20];
1132b1dd21f8SJouni Malinen 		int dpp_peer_bootstrap = -1;
1133b5ab828bSJouni Malinen 		char neg_freq[30];
1134b5ab828bSJouni Malinen 
1135d1e22f76SJouni Malinen 		val = get_param(cmd, "DPPAuthDirection");
1136d1e22f76SJouni Malinen 		check_mutual = val && strcasecmp(val, "Mutual") == 0;
1137d1e22f76SJouni Malinen 
1138b5ab828bSJouni Malinen 		neg_freq[0] = '\0';
1139b5ab828bSJouni Malinen 		val = get_param(cmd, "DPPSubsequentChannel");
1140b5ab828bSJouni Malinen 		if (val) {
1141b5ab828bSJouni Malinen 			int opclass, channel, freq;
1142b5ab828bSJouni Malinen 
1143b5ab828bSJouni Malinen 			opclass = atoi(val);
1144b5ab828bSJouni Malinen 			val = strchr(val, '/');
1145b5ab828bSJouni Malinen 			if (opclass == 0 || !val) {
1146b5ab828bSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1147b5ab828bSJouni Malinen 					  "errorCode,Invalid DPPSubsequentChannel");
1148b5ab828bSJouni Malinen 				goto out;
1149b5ab828bSJouni Malinen 			}
1150b5ab828bSJouni Malinen 			val++;
1151b5ab828bSJouni Malinen 			channel = atoi(val);
1152b5ab828bSJouni Malinen 
1153b5ab828bSJouni Malinen 			/* Ignoring opclass for now; could use it here for more
1154b5ab828bSJouni Malinen 			 * robust frequency determination. */
1155b5ab828bSJouni Malinen 			freq = channel_to_freq(channel);
1156b5ab828bSJouni Malinen 			if (!freq) {
1157b5ab828bSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1158b5ab828bSJouni Malinen 					  "errorCode,Unsupported DPPSubsequentChannel channel");
1159b5ab828bSJouni Malinen 				goto out;
1160b5ab828bSJouni Malinen 			}
1161b5ab828bSJouni Malinen 			snprintf(neg_freq, sizeof(neg_freq), " neg_freq=%d",
1162b5ab828bSJouni Malinen 				 freq);
1163b5ab828bSJouni Malinen 		}
1164b1dd21f8SJouni Malinen 
1165b1dd21f8SJouni Malinen 		if (strcasecmp(bs, "QR") == 0) {
1166b1dd21f8SJouni Malinen 			if (!dut->dpp_peer_uri) {
1167b1dd21f8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1168b1dd21f8SJouni Malinen 					  "errorCode,Missing peer bootstrapping info");
1169b1dd21f8SJouni Malinen 				goto out;
1170b1dd21f8SJouni Malinen 			}
1171b1dd21f8SJouni Malinen 
1172b1dd21f8SJouni Malinen 			snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1173b1dd21f8SJouni Malinen 				 dut->dpp_peer_uri);
1174b1dd21f8SJouni Malinen 			if (wpa_command_resp(ifname, buf, buf,
11753c27aa82SJouni Malinen 					     sizeof(buf)) < 0 ||
11763c27aa82SJouni Malinen 			    strncmp(buf, "FAIL", 4) == 0) {
1177b1dd21f8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1178b1dd21f8SJouni Malinen 					  "errorCode,Failed to parse URI");
1179b1dd21f8SJouni Malinen 				goto out;
1180b1dd21f8SJouni Malinen 			}
1181b1dd21f8SJouni Malinen 			dpp_peer_bootstrap = atoi(buf);
1182b1dd21f8SJouni Malinen 		}
1183d86e5828SJouni Malinen 
118463d5041cSJouni Malinen 		if (dut->dpp_local_bootstrap >= 0)
1185d86e5828SJouni Malinen 			snprintf(own_txt, sizeof(own_txt), " own=%d",
1186d86e5828SJouni Malinen 				 dut->dpp_local_bootstrap);
1187d86e5828SJouni Malinen 		else
1188d86e5828SJouni Malinen 			own_txt[0] = '\0';
1189d86e5828SJouni Malinen 		if (strcasecmp(bs, "QR") == 0 &&
119067acb0cfSJouni Malinen 		    (strcasecmp(prov_role, "Configurator") == 0 ||
119167acb0cfSJouni Malinen 		     strcasecmp(prov_role, "Both") == 0)) {
1192258cc26aSJouni Malinen 			if (!conf_role) {
1193258cc26aSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1194258cc26aSJouni Malinen 					  "errorCode,Missing DPPConfIndex");
1195258cc26aSJouni Malinen 				goto out;
1196258cc26aSJouni Malinen 			}
1197d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
1198b5ab828bSJouni Malinen 				 "DPP_AUTH_INIT peer=%d%s role=%s conf=%s %s %s configurator=%d%s",
1199b1dd21f8SJouni Malinen 				 dpp_peer_bootstrap, own_txt, role,
1200d86e5828SJouni Malinen 				 conf_role, conf_ssid, conf_pass,
1201b5ab828bSJouni Malinen 				 dut->dpp_conf_id, neg_freq);
1202d86e5828SJouni Malinen 		} else if (strcasecmp(bs, "QR") == 0) {
1203d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
1204b5ab828bSJouni Malinen 				 "DPP_AUTH_INIT peer=%d%s role=%s%s",
1205b5ab828bSJouni Malinen 				 dpp_peer_bootstrap, own_txt, role, neg_freq);
1206d86e5828SJouni Malinen 		} else if (strcasecmp(bs, "PKEX") == 0 &&
120767acb0cfSJouni Malinen 			   (strcasecmp(prov_role, "Configurator") == 0 ||
120867acb0cfSJouni Malinen 			    strcasecmp(prov_role, "Both") == 0)) {
1209258cc26aSJouni Malinen 			if (!conf_role) {
1210258cc26aSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1211258cc26aSJouni Malinen 					  "errorCode,Missing DPPConfIndex");
1212258cc26aSJouni Malinen 				goto out;
1213258cc26aSJouni Malinen 			}
1214d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
1215d86e5828SJouni Malinen 				 "DPP_PKEX_ADD own=%d init=1 role=%s conf=%s %s %s configurator=%d %scode=%s",
1216d86e5828SJouni Malinen 				 own_pkex_id, role, conf_role,
1217d86e5828SJouni Malinen 				 conf_ssid, conf_pass, dut->dpp_conf_id,
1218d86e5828SJouni Malinen 				 pkex_identifier, pkex_code);
1219d86e5828SJouni Malinen 		} else if (strcasecmp(bs, "PKEX") == 0) {
1220d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
1221d86e5828SJouni Malinen 				 "DPP_PKEX_ADD own=%d init=1 role=%s %scode=%s",
1222d86e5828SJouni Malinen 				 own_pkex_id, role, pkex_identifier, pkex_code);
1223d551c6fcSJouni Malinen 		} else {
1224d551c6fcSJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1225d551c6fcSJouni Malinen 				  "errorCode,Unsupported DPPBS");
1226d551c6fcSJouni Malinen 			goto out;
1227d86e5828SJouni Malinen 		}
1228d86e5828SJouni Malinen 		if (wpa_command(ifname, buf) < 0) {
1229d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1230d86e5828SJouni Malinen 				  "errorCode,Failed to initiate DPP authentication");
1231d86e5828SJouni Malinen 			goto out;
1232d86e5828SJouni Malinen 		}
1233d86e5828SJouni Malinen 	} else if (strcasecmp(auth_role, "Responder") == 0) {
123467f096aaSJouni Malinen 		const char *delay_qr_resp;
123563d5041cSJouni Malinen 		int mutual;
1236d3afc5cbSJouni Malinen 		int freq = 2462; /* default: channel 11 */
1237d3afc5cbSJouni Malinen 
123806cfcb3eSJouni Malinen 		if (strcasecmp(bs, "PKEX") == 0) {
123906cfcb3eSJouni Malinen 			/* default: channel 6 for PKEX */
124006cfcb3eSJouni Malinen 			freq = 2437;
124106cfcb3eSJouni Malinen 		}
124206cfcb3eSJouni Malinen 
124367f096aaSJouni Malinen 		delay_qr_resp = get_param(cmd, "DPPDelayQRResponse");
124467f096aaSJouni Malinen 
124563d5041cSJouni Malinen 		val = get_param(cmd, "DPPAuthDirection");
124663d5041cSJouni Malinen 		mutual = val && strcasecmp(val, "Mutual") == 0;
124763d5041cSJouni Malinen 
1248d3afc5cbSJouni Malinen 		val = get_param(cmd, "DPPListenChannel");
1249d3afc5cbSJouni Malinen 		if (val) {
1250d3afc5cbSJouni Malinen 			freq = channel_to_freq(atoi(val));
1251d3afc5cbSJouni Malinen 			if (freq == 0) {
1252d3afc5cbSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1253d3afc5cbSJouni Malinen 					  "errorCode,Unsupported DPPListenChannel value");
1254d3afc5cbSJouni Malinen 				goto out;
1255d3afc5cbSJouni Malinen 			}
1256d3afc5cbSJouni Malinen 		}
1257d86e5828SJouni Malinen 
1258b1dd21f8SJouni Malinen 		if (!delay_qr_resp && dut->dpp_peer_uri) {
1259b1dd21f8SJouni Malinen 			snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1260b1dd21f8SJouni Malinen 				 dut->dpp_peer_uri);
1261b1dd21f8SJouni Malinen 			if (wpa_command_resp(ifname, buf, buf,
1262b1dd21f8SJouni Malinen 					     sizeof(buf)) < 0) {
1263b1dd21f8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1264b1dd21f8SJouni Malinen 					  "errorCode,Failed to parse URI");
1265b1dd21f8SJouni Malinen 				goto out;
1266b1dd21f8SJouni Malinen 			}
1267b1dd21f8SJouni Malinen 		}
1268b1dd21f8SJouni Malinen 
1269d86e5828SJouni Malinen 		if (strcasecmp(prov_role, "Configurator") == 0) {
1270258cc26aSJouni Malinen 			if (!conf_role) {
1271258cc26aSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1272258cc26aSJouni Malinen 					  "errorCode,Missing DPPConfIndex");
1273258cc26aSJouni Malinen 				goto out;
1274258cc26aSJouni Malinen 			}
1275d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
1276d86e5828SJouni Malinen 				 "SET dpp_configurator_params  conf=%s %s %s configurator=%d",
1277d86e5828SJouni Malinen 				 conf_role, conf_ssid, conf_pass,
1278d86e5828SJouni Malinen 				 dut->dpp_conf_id);
1279d86e5828SJouni Malinen 			if (wpa_command(ifname, buf) < 0) {
1280d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1281d86e5828SJouni Malinen 					  "errorCode,Failed to set configurator parameters");
1282d86e5828SJouni Malinen 				goto out;
1283d86e5828SJouni Malinen 			}
1284d86e5828SJouni Malinen 		}
1285d86e5828SJouni Malinen 		if (strcasecmp(bs, "PKEX") == 0) {
1286d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
1287d86e5828SJouni Malinen 				 "DPP_PKEX_ADD own=%d role=%s %scode=%s",
1288d86e5828SJouni Malinen 				 own_pkex_id, role, pkex_identifier, pkex_code);
1289d86e5828SJouni Malinen 			if (wpa_command(ifname, buf) < 0) {
1290d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1291d86e5828SJouni Malinen 					  "errorCode,Failed to configure DPP PKEX");
1292d86e5828SJouni Malinen 				goto out;
1293d86e5828SJouni Malinen 			}
1294d86e5828SJouni Malinen 		}
1295d86e5828SJouni Malinen 
1296fd7359aeSJouni Malinen 		snprintf(buf, sizeof(buf), "DPP_LISTEN %d role=%s%s",
1297fd7359aeSJouni Malinen 			 freq, role,
1298fd7359aeSJouni Malinen 			 (strcasecmp(bs, "QR") == 0 && mutual) ?
1299fd7359aeSJouni Malinen 			 " qr=mutual" : "");
1300d86e5828SJouni Malinen 		if (wpa_command(ifname, buf) < 0) {
1301d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1302d86e5828SJouni Malinen 				  "errorCode,Failed to start DPP listen");
1303d86e5828SJouni Malinen 			goto out;
1304d86e5828SJouni Malinen 		}
1305b1dd21f8SJouni Malinen 
1306b4de1962Spriyadharshini gowthaman 		if (get_driver_type() == DRIVER_OPENWRT) {
1307b4de1962Spriyadharshini gowthaman 			snprintf(buf, sizeof(buf), "iwconfig %s channel %d",
1308b4de1962Spriyadharshini gowthaman 				 dut->hostapd_ifname, freq_to_channel(freq));
1309b4de1962Spriyadharshini gowthaman 			run_system(dut, buf);
1310b4de1962Spriyadharshini gowthaman 		}
1311b4de1962Spriyadharshini gowthaman 
1312b1dd21f8SJouni Malinen 		if (delay_qr_resp && mutual && dut->dpp_peer_uri) {
1313b1dd21f8SJouni Malinen 			int wait_time = atoi(delay_qr_resp);
1314b1dd21f8SJouni Malinen 
1315b1dd21f8SJouni Malinen 			res = get_wpa_cli_events(dut, ctrl, auth_events,
1316b1dd21f8SJouni Malinen 						 buf, sizeof(buf));
1317b1dd21f8SJouni Malinen 			if (res < 0) {
1318b1dd21f8SJouni Malinen 				send_resp(dut, conn, SIGMA_COMPLETE,
1319b1dd21f8SJouni Malinen 					  "BootstrapResult,OK,AuthResult,Timeout");
1320b1dd21f8SJouni Malinen 				goto out;
1321b1dd21f8SJouni Malinen 			}
1322b1dd21f8SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
1323b1dd21f8SJouni Malinen 					"DPP auth result: %s", buf);
1324b1dd21f8SJouni Malinen 			if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) {
1325b1dd21f8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1326b1dd21f8SJouni Malinen 					  "errorCode,No scan request for peer QR Code seen");
1327b1dd21f8SJouni Malinen 				goto out;
1328b1dd21f8SJouni Malinen 			}
1329b1dd21f8SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
1330b1dd21f8SJouni Malinen 					"Waiting %d second(s) before processing peer URI",
1331b1dd21f8SJouni Malinen 					wait_time);
1332b1dd21f8SJouni Malinen 			sleep(wait_time);
1333b1dd21f8SJouni Malinen 
1334b1dd21f8SJouni Malinen 			snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1335b1dd21f8SJouni Malinen 				 dut->dpp_peer_uri);
1336b1dd21f8SJouni Malinen 			if (wpa_command_resp(ifname, buf, buf,
1337b1dd21f8SJouni Malinen 					     sizeof(buf)) < 0) {
1338b1dd21f8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1339b1dd21f8SJouni Malinen 					  "errorCode,Failed to parse URI");
1340b1dd21f8SJouni Malinen 				goto out;
1341b1dd21f8SJouni Malinen 			}
1342bc9e055cSSrinivas Dasari 		} else if (mutual && action_type &&
1343bc9e055cSSrinivas Dasari 			   strcasecmp(action_type, "ManualDPP") == 0) {
1344bc9e055cSSrinivas Dasari 			res = get_wpa_cli_events(dut, ctrl, auth_events,
1345bc9e055cSSrinivas Dasari 						 buf, sizeof(buf));
1346bc9e055cSSrinivas Dasari 			if (res < 0) {
1347bc9e055cSSrinivas Dasari 				send_resp(dut, conn, SIGMA_COMPLETE,
1348bc9e055cSSrinivas Dasari 					  "BootstrapResult,OK,AuthResult,Timeout");
1349bc9e055cSSrinivas Dasari 				goto out;
1350bc9e055cSSrinivas Dasari 			}
1351bc9e055cSSrinivas Dasari 			sigma_dut_print(dut, DUT_MSG_DEBUG,
1352bc9e055cSSrinivas Dasari 					"DPP auth result: %s", buf);
1353bc9e055cSSrinivas Dasari 			if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) {
1354bc9e055cSSrinivas Dasari 				send_resp(dut, conn, SIGMA_ERROR,
1355bc9e055cSSrinivas Dasari 					  "errorCode,No scan request for peer QR Code seen");
1356bc9e055cSSrinivas Dasari 				goto out;
1357bc9e055cSSrinivas Dasari 			}
1358bc9e055cSSrinivas Dasari 
1359bc9e055cSSrinivas Dasari 			if (dpp_scan_peer_qrcode(dut) < 0) {
1360bc9e055cSSrinivas Dasari 				send_resp(dut, conn, SIGMA_ERROR,
1361bc9e055cSSrinivas Dasari 					  "errorCode,Failed to scan peer QR Code");
1362bc9e055cSSrinivas Dasari 				goto out;
1363bc9e055cSSrinivas Dasari 			}
1364bc9e055cSSrinivas Dasari 
1365bc9e055cSSrinivas Dasari 			snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1366bc9e055cSSrinivas Dasari 				 dut->dpp_peer_uri);
1367bc9e055cSSrinivas Dasari 			if (wpa_command_resp(ifname, buf, buf,
1368bc9e055cSSrinivas Dasari 					     sizeof(buf)) < 0) {
1369bc9e055cSSrinivas Dasari 				send_resp(dut, conn, SIGMA_ERROR,
1370bc9e055cSSrinivas Dasari 					  "errorCode,Failed to parse URI");
1371bc9e055cSSrinivas Dasari 				goto out;
1372bc9e055cSSrinivas Dasari 			}
1373b1dd21f8SJouni Malinen 		}
1374d86e5828SJouni Malinen 	} else {
1375d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
1376d86e5828SJouni Malinen 			  "errorCode,Unknown DPPAuthRole");
1377d86e5828SJouni Malinen 		goto out;
1378d86e5828SJouni Malinen 	}
1379d86e5828SJouni Malinen 
13803a6b92a6SJouni Malinen 	if (step && strcasecmp(step, "Timeout") == 0) {
13813a6b92a6SJouni Malinen 		result = "errorCode,Unexpected state";
13823a6b92a6SJouni Malinen 
13833a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "PKEXExchangeResponse") == 0) {
13849a3415c2SJouni Malinen 			if (dpp_wait_rx(dut, ctrl, 8, -1) < 0)
13853a6b92a6SJouni Malinen 				result = "BootstrapResult,Timeout";
13863a6b92a6SJouni Malinen 			else
13873a6b92a6SJouni Malinen 				result = "BootstrapResult,Errorsent";
13883a6b92a6SJouni Malinen 		}
13893a6b92a6SJouni Malinen 
13903a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "PKEXCRRequest") == 0) {
13919a3415c2SJouni Malinen 			if (dpp_wait_rx(dut, ctrl, 9, -1) < 0)
13923a6b92a6SJouni Malinen 				result = "BootstrapResult,Timeout";
13933a6b92a6SJouni Malinen 			else
13943a6b92a6SJouni Malinen 				result = "BootstrapResult,Errorsent";
13953a6b92a6SJouni Malinen 		}
13963a6b92a6SJouni Malinen 
13973a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "PKEXCRResponse") == 0) {
13989a3415c2SJouni Malinen 			if (dpp_wait_rx(dut, ctrl, 10, -1) < 0)
13993a6b92a6SJouni Malinen 				result = "BootstrapResult,Timeout";
14003a6b92a6SJouni Malinen 			else
14013a6b92a6SJouni Malinen 				result = "BootstrapResult,Errorsent";
14023a6b92a6SJouni Malinen 		}
14033a6b92a6SJouni Malinen 
14043a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "AuthenticationRequest") == 0) {
14059a3415c2SJouni Malinen 			if (dpp_wait_rx(dut, ctrl, 0, -1) < 0)
14063a6b92a6SJouni Malinen 				result = "BootstrapResult,OK,AuthResult,Timeout";
14073a6b92a6SJouni Malinen 			else
14083a6b92a6SJouni Malinen 				result = "BootstrapResult,OK,AuthResult,Errorsent";
14093a6b92a6SJouni Malinen 		}
14103a6b92a6SJouni Malinen 
14113a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "AuthenticationResponse") == 0) {
14129a3415c2SJouni Malinen 			if (dpp_wait_rx(dut, ctrl, 1, -1) < 0)
14133a6b92a6SJouni Malinen 				result = "BootstrapResult,OK,AuthResult,Timeout";
14143a6b92a6SJouni Malinen 			else
14153a6b92a6SJouni Malinen 				result = "BootstrapResult,OK,AuthResult,Errorsent";
14163a6b92a6SJouni Malinen 		}
14173a6b92a6SJouni Malinen 
14183a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "AuthenticationConfirm") == 0) {
1419*ecb49d8bSDeepak Dhamdhere 			if (strcasecmp(auth_role, "Initiator") == 0) {
1420*ecb49d8bSDeepak Dhamdhere 				if (dpp_wait_tx_status(dut, ctrl, 2) < 0)
1421*ecb49d8bSDeepak Dhamdhere 					result = "BootstrapResult,OK,AuthResult,Timeout";
1422*ecb49d8bSDeepak Dhamdhere 				else if (dpp_wait_rx_conf_req(dut, ctrl, 5) <
1423*ecb49d8bSDeepak Dhamdhere 					 0)
1424*ecb49d8bSDeepak Dhamdhere 					result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
1425*ecb49d8bSDeepak Dhamdhere 				else
1426*ecb49d8bSDeepak Dhamdhere 					result = "BootstrapResult,OK,AuthResult,OK,LastFrameReceived,ConfigurationRequest";
1427*ecb49d8bSDeepak Dhamdhere 			} else {
14289a3415c2SJouni Malinen 				if (dpp_wait_rx(dut, ctrl, 2, -1) < 0)
14293a6b92a6SJouni Malinen 					result = "BootstrapResult,OK,AuthResult,Timeout";
14303a6b92a6SJouni Malinen 				else
1431*ecb49d8bSDeepak Dhamdhere 					result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm";
1432*ecb49d8bSDeepak Dhamdhere 			}
14333a6b92a6SJouni Malinen 		}
14343a6b92a6SJouni Malinen 
14353a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "ConfigurationRequest") == 0) {
14363a6b92a6SJouni Malinen 			if (get_wpa_cli_event(dut, ctrl, "DPP-CONF-FAILED",
14373a6b92a6SJouni Malinen 					      buf, sizeof(buf)) < 0)
14383a6b92a6SJouni Malinen 				result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
14393a6b92a6SJouni Malinen 			else
14403a6b92a6SJouni Malinen 				result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
14413a6b92a6SJouni Malinen 		}
14423a6b92a6SJouni Malinen 
14433a6b92a6SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
14443a6b92a6SJouni Malinen 		goto out;
14453a6b92a6SJouni Malinen 	}
14463a6b92a6SJouni Malinen 
1447772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "PKEXExchangeRequest") == 0) {
1448772299f1SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 7) < 0)
1449772299f1SJouni Malinen 			result = "BootstrapResult,Timeout";
1450772299f1SJouni Malinen 		else
1451772299f1SJouni Malinen 			result = "BootstrapResult,Errorsent";
1452772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
1453772299f1SJouni Malinen 		goto out;
1454772299f1SJouni Malinen 	}
1455772299f1SJouni Malinen 
1456772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "PKEXExchangeResponse") == 0) {
1457772299f1SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 8) < 0)
1458772299f1SJouni Malinen 			result = "BootstrapResult,Timeout";
1459772299f1SJouni Malinen 		else
1460772299f1SJouni Malinen 			result = "BootstrapResult,Errorsent";
1461772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
1462772299f1SJouni Malinen 		goto out;
1463772299f1SJouni Malinen 	}
1464772299f1SJouni Malinen 
1465772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "PKEXCRRequest") == 0) {
1466772299f1SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 9) < 0)
1467772299f1SJouni Malinen 			result = "BootstrapResult,Timeout";
1468772299f1SJouni Malinen 		else
1469772299f1SJouni Malinen 			result = "BootstrapResult,Errorsent";
1470772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
1471772299f1SJouni Malinen 		goto out;
1472772299f1SJouni Malinen 	}
1473772299f1SJouni Malinen 
1474772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "PKEXCRResponse") == 0) {
1475772299f1SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 10) < 0)
1476772299f1SJouni Malinen 			result = "BootstrapResult,Timeout";
1477772299f1SJouni Malinen 		else
1478772299f1SJouni Malinen 			result = "BootstrapResult,Errorsent";
1479772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
1480772299f1SJouni Malinen 		goto out;
1481772299f1SJouni Malinen 	}
1482772299f1SJouni Malinen 
14836792ff4dSJouni Malinen 	if (!frametype && strcasecmp(bs, "PKEX") == 0 &&
14846792ff4dSJouni Malinen 	    strcasecmp(auth_role, "Responder") == 0) {
14856792ff4dSJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 10) < 0) {
14866792ff4dSJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
14876792ff4dSJouni Malinen 				  "BootstrapResult,Timeout");
14886792ff4dSJouni Malinen 			goto out;
14896792ff4dSJouni Malinen 		}
14906792ff4dSJouni Malinen 	}
14916792ff4dSJouni Malinen 
14926792ff4dSJouni Malinen 	if (!frametype && strcasecmp(bs, "PKEX") == 0 &&
14936792ff4dSJouni Malinen 	    strcasecmp(auth_role, "Initiator") == 0) {
14946792ff4dSJouni Malinen 		if (dpp_wait_tx(dut, ctrl, 0) < 0) {
14956792ff4dSJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
14966792ff4dSJouni Malinen 				  "BootstrapResult,Timeout");
14976792ff4dSJouni Malinen 			goto out;
14986792ff4dSJouni Malinen 		}
14996792ff4dSJouni Malinen 	}
15006792ff4dSJouni Malinen 
1501772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "AuthenticationRequest") == 0) {
15029a3415c2SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 0) < 0) {
15039a3415c2SJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
15049a3415c2SJouni Malinen 				  "BootstrapResult,OK,AuthResult,Timeout");
15059a3415c2SJouni Malinen 			goto out;
15069a3415c2SJouni Malinen 		}
15079a3415c2SJouni Malinen 
15089a3415c2SJouni Malinen 		if (dpp_wait_rx(dut, ctrl, 1, 5) < 0)
15099a3415c2SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,None";
1510b9f1eb9bSDeepak Dhamdhere 		else if	(get_wpa_cli_events(dut, ctrl, auth_events,
1511b9f1eb9bSDeepak Dhamdhere 					    buf, sizeof(buf)) >= 0 &&
1512b9f1eb9bSDeepak Dhamdhere 			 strstr(buf, "DPP-RESPONSE-PENDING") != NULL)
1513b9f1eb9bSDeepak Dhamdhere 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponseWithStatusPending";
1514772299f1SJouni Malinen 		else
15159a3415c2SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
1516772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
1517772299f1SJouni Malinen 		goto out;
1518772299f1SJouni Malinen 	}
1519772299f1SJouni Malinen 
1520772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "AuthenticationResponse") == 0) {
15219a3415c2SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 1) < 0) {
15229a3415c2SJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
15239a3415c2SJouni Malinen 				  "BootstrapResult,OK,AuthResult,Timeout");
15249a3415c2SJouni Malinen 			goto out;
15259a3415c2SJouni Malinen 		}
15269a3415c2SJouni Malinen 
15279a3415c2SJouni Malinen 		if (dpp_wait_rx(dut, ctrl, 2, 5) < 0)
15289a3415c2SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationRequest";
1529772299f1SJouni Malinen 		else
15309a3415c2SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm";
1531772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
1532772299f1SJouni Malinen 		goto out;
1533772299f1SJouni Malinen 	}
1534772299f1SJouni Malinen 
1535bc9e055cSSrinivas Dasari 	res = get_wpa_cli_events(dut, ctrl, auth_events, buf, sizeof(buf));
1536bc9e055cSSrinivas Dasari 	if (res < 0) {
1537bc9e055cSSrinivas Dasari 		send_resp(dut, conn, SIGMA_COMPLETE,
1538bc9e055cSSrinivas Dasari 			  "BootstrapResult,OK,AuthResult,Timeout");
1539bc9e055cSSrinivas Dasari 		goto out;
1540bc9e055cSSrinivas Dasari 	}
1541bc9e055cSSrinivas Dasari 	sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
1542bc9e055cSSrinivas Dasari 
1543bc9e055cSSrinivas Dasari 	if (strstr(buf, "DPP-RESPONSE-PENDING")) {
1544bc9e055cSSrinivas Dasari 		/* Display own QR code in manual mode */
1545bc9e055cSSrinivas Dasari 		if (action_type && strcasecmp(action_type, "ManualDPP") == 0 &&
1546bc9e055cSSrinivas Dasari 		    dpp_display_own_qrcode(dut) < 0) {
1547bc9e055cSSrinivas Dasari 			send_resp(dut, conn, SIGMA_ERROR,
1548bc9e055cSSrinivas Dasari 				  "errorCode,Failed to display own QR code");
1549bc9e055cSSrinivas Dasari 			goto out;
1550bc9e055cSSrinivas Dasari 		}
1551bc9e055cSSrinivas Dasari 
1552bc9e055cSSrinivas Dasari 		/* Wait for the actual result after the peer has scanned the
1553bc9e055cSSrinivas Dasari 		 * QR Code. */
1554bc9e055cSSrinivas Dasari 		res = get_wpa_cli_events(dut, ctrl, auth_events,
1555d1e22f76SJouni Malinen 					 buf, sizeof(buf));
1556d1e22f76SJouni Malinen 		if (res < 0) {
1557d1e22f76SJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
1558d1e22f76SJouni Malinen 				  "BootstrapResult,OK,AuthResult,Timeout");
1559d1e22f76SJouni Malinen 			goto out;
1560d1e22f76SJouni Malinen 		}
1561bc9e055cSSrinivas Dasari 
1562bc9e055cSSrinivas Dasari 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
1563bc9e055cSSrinivas Dasari 	}
1564bc9e055cSSrinivas Dasari 
1565bc9e055cSSrinivas Dasari 	if (check_mutual) {
1566a98426a2SJouni Malinen 		if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
1567a98426a2SJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
1568a98426a2SJouni Malinen 				  "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
1569a98426a2SJouni Malinen 			goto out;
1570a98426a2SJouni Malinen 		}
1571a98426a2SJouni Malinen 
1572bc9e055cSSrinivas Dasari 		if (!strstr(buf, "DPP-AUTH-DIRECTION")) {
1573bc9e055cSSrinivas Dasari 			send_resp(dut, conn, SIGMA_ERROR,
1574bc9e055cSSrinivas Dasari 				  "errorCode,No event for auth direction seen");
1575bc9e055cSSrinivas Dasari 			goto out;
1576bc9e055cSSrinivas Dasari 		}
1577bc9e055cSSrinivas Dasari 
1578d1e22f76SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth direction: %s",
1579d1e22f76SJouni Malinen 				buf);
1580d1e22f76SJouni Malinen 		if (strstr(buf, "mutual=1") == NULL) {
1581d1e22f76SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1582d1e22f76SJouni Malinen 				  "errorCode,Peer did not use mutual authentication");
1583d1e22f76SJouni Malinen 			goto out;
1584d1e22f76SJouni Malinen 		}
1585d1e22f76SJouni Malinen 	}
1586d1e22f76SJouni Malinen 
1587772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "AuthenticationConfirm") == 0) {
15889a3415c2SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 2) < 0) {
15899a3415c2SJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
15909a3415c2SJouni Malinen 				  "BootstrapResult,OK,AuthResult,Timeout");
15919a3415c2SJouni Malinen 			goto out;
15929a3415c2SJouni Malinen 		}
15939a3415c2SJouni Malinen 
15949a3415c2SJouni Malinen 		if (dpp_wait_rx_conf_req(dut, ctrl, 5) < 0)
15959a3415c2SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
1596772299f1SJouni Malinen 		else
15979a3415c2SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,ConfigurationRequest";
1598772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
1599772299f1SJouni Malinen 		goto out;
1600772299f1SJouni Malinen 	}
1601772299f1SJouni Malinen 
1602bc9e055cSSrinivas Dasari 	if (strstr(buf, "DPP-AUTH-DIRECTION")) {
16032e9c8a46SJouni Malinen 		res = get_wpa_cli_events(dut, ctrl, auth_events,
16042e9c8a46SJouni Malinen 					 buf, sizeof(buf));
16052e9c8a46SJouni Malinen 		if (res < 0) {
16062e9c8a46SJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
16072e9c8a46SJouni Malinen 				  "BootstrapResult,OK,AuthResult,Timeout");
16082e9c8a46SJouni Malinen 			goto out;
16092e9c8a46SJouni Malinen 		}
1610bc9e055cSSrinivas Dasari 
1611bc9e055cSSrinivas Dasari 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
16122e9c8a46SJouni Malinen 	}
16132e9c8a46SJouni Malinen 
1614d86e5828SJouni Malinen 	if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
1615d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
1616d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
1617d86e5828SJouni Malinen 		goto out;
1618d86e5828SJouni Malinen 	}
1619d86e5828SJouni Malinen 
1620d86e5828SJouni Malinen 	if (!strstr(buf, "DPP-AUTH-SUCCESS")) {
1621d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
1622d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,FAILED");
1623d86e5828SJouni Malinen 		goto out;
1624d86e5828SJouni Malinen 	}
1625d86e5828SJouni Malinen 
1626772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "ConfigurationRequest") == 0) {
1627772299f1SJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE",
1628772299f1SJouni Malinen 					buf, sizeof(buf));
1629772299f1SJouni Malinen 		if (res < 0)
1630772299f1SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1631772299f1SJouni Malinen 		else
1632772299f1SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
1633772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
1634772299f1SJouni Malinen 		goto out;
1635772299f1SJouni Malinen 	}
1636772299f1SJouni Malinen 
1637772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "ConfigurationResponse") == 0) {
1638772299f1SJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-SENT",
1639772299f1SJouni Malinen 					buf, sizeof(buf));
1640772299f1SJouni Malinen 		if (res < 0)
1641772299f1SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1642772299f1SJouni Malinen 		else
16439b4f275cSDeepak Dhamdhere 			result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent,LastFrameReceived,ConfigurationRequest";
1644772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
1645772299f1SJouni Malinen 		goto out;
1646772299f1SJouni Malinen 	}
1647772299f1SJouni Malinen 
1648d86e5828SJouni Malinen 	res = get_wpa_cli_events(dut, ctrl, conf_events, buf, sizeof(buf));
1649d86e5828SJouni Malinen 	if (res < 0) {
1650d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
1651d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout");
1652d86e5828SJouni Malinen 		goto out;
1653d86e5828SJouni Malinen 	}
1654d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP conf result: %s", buf);
1655d86e5828SJouni Malinen 
1656d86e5828SJouni Malinen 	if (!strstr(buf, "DPP-CONF-SENT") &&
1657d86e5828SJouni Malinen 	    !strstr(buf, "DPP-CONF-RECEIVED")) {
1658d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
1659d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,OK,ConfResult,FAILED");
1660d86e5828SJouni Malinen 		goto out;
1661d86e5828SJouni Malinen 	}
1662d86e5828SJouni Malinen 
1663d86e5828SJouni Malinen 	if (sigma_dut_is_ap(dut) &&
1664d86e5828SJouni Malinen 	    strcasecmp(prov_role, "Enrollee") == 0) {
1665174db64fSJouni Malinen 	update_ap:
1666d86e5828SJouni Malinen 		res = dpp_hostapd_conf_update(dut, conn, ifname, ctrl);
1667d86e5828SJouni Malinen 		if (res == 0)
1668d86e5828SJouni Malinen 			goto out;
1669d86e5828SJouni Malinen 		if (res < 0) {
1670d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR, NULL);
1671d86e5828SJouni Malinen 			goto out;
1672d86e5828SJouni Malinen 		}
1673d86e5828SJouni Malinen 	}
1674d86e5828SJouni Malinen 
1675d86e5828SJouni Malinen 	if (strcasecmp(wait_conn, "Yes") == 0 &&
1676d86e5828SJouni Malinen 	    !sigma_dut_is_ap(dut) &&
1677d86e5828SJouni Malinen 	    strcasecmp(prov_role, "Enrollee") == 0) {
1678fbb268d7SJouni Malinen 	wait_connect:
167953558e0fSJouni Malinen 		if (frametype && strcasecmp(frametype,
168053558e0fSJouni Malinen 					    "PeerDiscoveryRequest") == 0) {
168153558e0fSJouni Malinen 			if (dpp_wait_tx_status(dut, ctrl, 5) < 0)
168253558e0fSJouni Malinen 				result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout";
168353558e0fSJouni Malinen 			else
168453558e0fSJouni Malinen 				result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent";
168553558e0fSJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE, result);
168653558e0fSJouni Malinen 			goto out;
168753558e0fSJouni Malinen 		}
168853558e0fSJouni Malinen 
1689d86e5828SJouni Malinen 		res = get_wpa_cli_events(dut, ctrl, conn_events,
1690d86e5828SJouni Malinen 					 buf, sizeof(buf));
1691d86e5828SJouni Malinen 		if (res < 0) {
1692d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
1693d86e5828SJouni Malinen 				  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout,NetworkConnectResult,Timeout");
1694d86e5828SJouni Malinen 			goto out;
1695d86e5828SJouni Malinen 		}
1696d86e5828SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP connect result: %s",
1697d86e5828SJouni Malinen 				buf);
1698d86e5828SJouni Malinen 
1699d86e5828SJouni Malinen 		if (strstr(buf, "PMKSA-CACHE-ADDED")) {
1700d86e5828SJouni Malinen 			res = get_wpa_cli_events(dut, ctrl, conn_events,
1701d86e5828SJouni Malinen 						 buf, sizeof(buf));
1702d86e5828SJouni Malinen 			if (res < 0) {
1703d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_COMPLETE,
1704d86e5828SJouni Malinen 					  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
1705d86e5828SJouni Malinen 				goto out;
1706d86e5828SJouni Malinen 			}
1707d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
1708d86e5828SJouni Malinen 					"DPP connect result: %s", buf);
1709d86e5828SJouni Malinen 			if (strstr(buf, "CTRL-EVENT-CONNECTED"))
1710d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_COMPLETE,
1711d86e5828SJouni Malinen 					  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK");
1712d86e5828SJouni Malinen 			else
1713d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_COMPLETE,
1714d86e5828SJouni Malinen 					  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
1715d86e5828SJouni Malinen 			goto out;
1716d86e5828SJouni Malinen 		}
1717d86e5828SJouni Malinen 
1718d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
1719d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK");
1720d86e5828SJouni Malinen 		goto out;
1721d86e5828SJouni Malinen 	}
1722d86e5828SJouni Malinen 
172353558e0fSJouni Malinen 	if (strcasecmp(wait_conn, "Yes") == 0 &&
172453558e0fSJouni Malinen 	    frametype && strcasecmp(frametype, "PeerDiscoveryResponse") == 0) {
172553558e0fSJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 6) < 0)
172653558e0fSJouni Malinen 			result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout";
172753558e0fSJouni Malinen 		else
172853558e0fSJouni Malinen 			result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent";
172953558e0fSJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
173053558e0fSJouni Malinen 		goto out;
173153558e0fSJouni Malinen 	}
173253558e0fSJouni Malinen 
1733d86e5828SJouni Malinen 	send_resp(dut, conn, SIGMA_COMPLETE,
1734d86e5828SJouni Malinen 		  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK");
1735d86e5828SJouni Malinen out:
1736d86e5828SJouni Malinen 	wpa_ctrl_detach(ctrl);
1737d86e5828SJouni Malinen 	wpa_ctrl_close(ctrl);
1738d86e5828SJouni Malinen 	dut->default_timeout = old_timeout;
1739d86e5828SJouni Malinen 	return 0;
1740d86e5828SJouni Malinen }
1741d86e5828SJouni Malinen 
1742d86e5828SJouni Malinen 
1743bc9e055cSSrinivas Dasari static int dpp_manual_dpp(struct sigma_dut *dut,
1744bc9e055cSSrinivas Dasari 			  struct sigma_conn *conn,
1745bc9e055cSSrinivas Dasari 			  struct sigma_cmd *cmd)
1746bc9e055cSSrinivas Dasari {
1747bc9e055cSSrinivas Dasari 	const char *auth_role = get_param(cmd, "DPPAuthRole");
1748bc9e055cSSrinivas Dasari 	int res = -1, success;
1749bc9e055cSSrinivas Dasari 	const char *val;
1750bc9e055cSSrinivas Dasari 	unsigned int old_timeout;
1751bc9e055cSSrinivas Dasari 
1752bc9e055cSSrinivas Dasari 	if (!auth_role) {
1753bc9e055cSSrinivas Dasari 		send_resp(dut, conn, SIGMA_ERROR,
1754bc9e055cSSrinivas Dasari 			  "errorCode,Missing DPPAuthRole");
1755bc9e055cSSrinivas Dasari 		return 0;
1756bc9e055cSSrinivas Dasari 	}
1757bc9e055cSSrinivas Dasari 
1758bc9e055cSSrinivas Dasari 	old_timeout = dut->default_timeout;
1759bc9e055cSSrinivas Dasari 	val = get_param(cmd, "DPPTimeout");
1760bc9e055cSSrinivas Dasari 	if (val && atoi(val) > 0) {
1761bc9e055cSSrinivas Dasari 		dut->default_timeout = atoi(val);
1762bc9e055cSSrinivas Dasari 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u",
1763bc9e055cSSrinivas Dasari 				dut->default_timeout);
1764bc9e055cSSrinivas Dasari 	}
1765bc9e055cSSrinivas Dasari 
1766bc9e055cSSrinivas Dasari 	res = dpp_get_local_bootstrap(dut, conn, cmd, 0, &success);
1767bc9e055cSSrinivas Dasari 	if (res || !success)
1768bc9e055cSSrinivas Dasari 		goto out;
1769bc9e055cSSrinivas Dasari 
1770bc9e055cSSrinivas Dasari 	if (strcasecmp(auth_role, "Responder") == 0) {
1771bc9e055cSSrinivas Dasari 		res = dpp_display_own_qrcode(dut);
1772bc9e055cSSrinivas Dasari 		if (res < 0)
1773bc9e055cSSrinivas Dasari 			goto out;
1774bc9e055cSSrinivas Dasari 
1775bc9e055cSSrinivas Dasari 		res = dpp_automatic_dpp(dut, conn, cmd);
1776bc9e055cSSrinivas Dasari 		goto out;
1777bc9e055cSSrinivas Dasari 	}
1778bc9e055cSSrinivas Dasari 
1779bc9e055cSSrinivas Dasari 	if (strcasecmp(auth_role, "Initiator") == 0) {
1780bc9e055cSSrinivas Dasari 		res = dpp_scan_peer_qrcode(dut);
17811a38cc37SJouni Malinen 		if (res < 0) {
17821a38cc37SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
17831a38cc37SJouni Malinen 				  "errorCode,Failed to scan peer QR Code");
17841a38cc37SJouni Malinen 			res = 0;
1785bc9e055cSSrinivas Dasari 			goto out;
17861a38cc37SJouni Malinen 		}
1787bc9e055cSSrinivas Dasari 
1788bc9e055cSSrinivas Dasari 		res = dpp_automatic_dpp(dut, conn, cmd);
1789bc9e055cSSrinivas Dasari 		goto out;
1790bc9e055cSSrinivas Dasari 	}
1791bc9e055cSSrinivas Dasari 
1792bc9e055cSSrinivas Dasari 	send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unknown DPPAuthRole");
1793bc9e055cSSrinivas Dasari 	res = 0;
1794bc9e055cSSrinivas Dasari out:
1795bc9e055cSSrinivas Dasari 	dut->default_timeout = old_timeout;
1796bc9e055cSSrinivas Dasari 	return res;
1797bc9e055cSSrinivas Dasari }
1798bc9e055cSSrinivas Dasari 
1799bc9e055cSSrinivas Dasari 
1800d86e5828SJouni Malinen int dpp_dev_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1801d86e5828SJouni Malinen 			struct sigma_cmd *cmd)
1802d86e5828SJouni Malinen {
1803d86e5828SJouni Malinen 	const char *type = get_param(cmd, "DPPActionType");
1804d86e5828SJouni Malinen 	const char *bs = get_param(cmd, "DPPBS");
1805d86e5828SJouni Malinen 
1806d86e5828SJouni Malinen 	if (!bs) {
1807d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
1808d86e5828SJouni Malinen 			  "errorCode,Missing DPPBS");
1809d86e5828SJouni Malinen 		return 0;
1810d86e5828SJouni Malinen 	}
1811d86e5828SJouni Malinen 
1812d86e5828SJouni Malinen 	if (!type) {
1813d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
1814d86e5828SJouni Malinen 			  "errorCode,Missing DPPActionType");
1815d86e5828SJouni Malinen 		return 0;
1816d86e5828SJouni Malinen 	}
1817d86e5828SJouni Malinen 
1818d86e5828SJouni Malinen 	if (strcasecmp(type, "GetLocalBootstrap") == 0)
1819bc9e055cSSrinivas Dasari 		return dpp_get_local_bootstrap(dut, conn, cmd, 1, NULL);
1820d86e5828SJouni Malinen 	if (strcasecmp(type, "SetPeerBootstrap") == 0)
1821d86e5828SJouni Malinen 		return dpp_set_peer_bootstrap(dut, conn, cmd);
1822d86e5828SJouni Malinen 	if (strcasecmp(type, "ManualDPP") == 0)
1823d86e5828SJouni Malinen 		return dpp_manual_dpp(dut, conn, cmd);
1824d86e5828SJouni Malinen 	if (strcasecmp(type, "AutomaticDPP") == 0)
1825d86e5828SJouni Malinen 		return dpp_automatic_dpp(dut, conn, cmd);
1826d86e5828SJouni Malinen 
1827d86e5828SJouni Malinen 	send_resp(dut, conn, SIGMA_ERROR,
1828d86e5828SJouni Malinen 		  "errorCode,Unsupported DPPActionType");
1829d86e5828SJouni Malinen 	return 0;
1830d86e5828SJouni Malinen }
1831