xref: /wlan-dirver/utils/sigma-dut/dpp.c (revision ec5a4a44070259b68205369ce4723eef73ff863c)
1d86e5828SJouni Malinen /*
2d86e5828SJouni Malinen  * Sigma Control API DUT (station/AP/sniffer)
3d86e5828SJouni Malinen  * Copyright (c) 2017, Qualcomm Atheros, Inc.
4*ec5a4a44SJouni Malinen  * Copyright (c) 2018-2020, 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 
14*ec5a4a44SJouni Malinen extern char *sigma_wpas_ctrl;
15*ec5a4a44SJouni Malinen 
161a38cc37SJouni Malinen #ifdef ANDROID
17bc9e055cSSrinivas Dasari char *dpp_qrcode_file = "/sdcard/wpadebug_qrdata.txt";
181a38cc37SJouni Malinen #endif /* ANDROID */
19bc9e055cSSrinivas Dasari 
20d86e5828SJouni Malinen 
21d86e5828SJouni Malinen static int sigma_dut_is_ap(struct sigma_dut *dut)
22d86e5828SJouni Malinen {
23d86e5828SJouni Malinen 	return dut->device_type == AP_unknown ||
24d86e5828SJouni Malinen 		dut->device_type == AP_testbed ||
25d86e5828SJouni Malinen 		dut->device_type == AP_dut;
26d86e5828SJouni Malinen }
27d86e5828SJouni Malinen 
28d86e5828SJouni Malinen 
29d86e5828SJouni Malinen static int dpp_hostapd_run(struct sigma_dut *dut)
30d86e5828SJouni Malinen {
31d86e5828SJouni Malinen 	if (dut->hostapd_running)
32d86e5828SJouni Malinen 		return 0;
33d86e5828SJouni Malinen 
34d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO,
35d86e5828SJouni Malinen 			"Starting hostapd in unconfigured state for DPP");
36d86e5828SJouni Malinen 	snprintf(dut->ap_ssid, sizeof(dut->ap_ssid), "unconfigured");
379149afc1Spriyadharshini gowthaman 	if (!dut->ap_oper_chn)
38d86e5828SJouni Malinen 		dut->ap_channel = 11;
39d86e5828SJouni Malinen 	dut->ap_is_dual = 0;
40fa2d7c3aSpriyadharshini gowthaman 	dut->ap_mode = dut->ap_channel <= 14 ? AP_11ng : AP_11na;
41d86e5828SJouni Malinen 	dut->ap_key_mgmt = AP_OPEN;
42d86e5828SJouni Malinen 	dut->ap_cipher = AP_PLAIN;
43d2e9bb3eSJouni Malinen 	if (!dut->ap_dpp_conf_addr || !dut->ap_dpp_conf_pkhash)
44d2e9bb3eSJouni Malinen 		dut->ap_start_disabled = 1;
45d86e5828SJouni Malinen 	return cmd_ap_config_commit(dut, NULL, NULL) == 1 ? 0 : -1;
46d86e5828SJouni Malinen }
47d86e5828SJouni Malinen 
48d86e5828SJouni Malinen 
49d2e9bb3eSJouni Malinen static int dpp_hostapd_beacon(struct sigma_dut *dut)
50d2e9bb3eSJouni Malinen {
51d2e9bb3eSJouni Malinen 	const char *ifname = dut->hostapd_ifname;
52d2e9bb3eSJouni Malinen 
53d2e9bb3eSJouni Malinen 	if (!dut->ap_start_disabled)
54d2e9bb3eSJouni Malinen 		return 0;
55d2e9bb3eSJouni Malinen 
56d2e9bb3eSJouni Malinen 	if (!ifname ||
57d2e9bb3eSJouni Malinen 	    wpa_command(ifname, "SET start_disabled 0") < 0 ||
58d2e9bb3eSJouni Malinen 	    wpa_command(ifname, "DISABLE") < 0 ||
59d2e9bb3eSJouni Malinen 	    wpa_command(ifname, "ENABLE") < 0)
60d2e9bb3eSJouni Malinen 		return -1;
61d2e9bb3eSJouni Malinen 
62d2e9bb3eSJouni Malinen 	dut->ap_start_disabled = 0;
63d2e9bb3eSJouni Malinen 	return 0;
64d2e9bb3eSJouni Malinen }
65d2e9bb3eSJouni Malinen 
66d2e9bb3eSJouni Malinen 
67d86e5828SJouni Malinen static const char * dpp_get_curve(struct sigma_cmd *cmd, const char *arg)
68d86e5828SJouni Malinen {
69d86e5828SJouni Malinen 	const char *val = get_param(cmd, arg);
70d86e5828SJouni Malinen 
71d86e5828SJouni Malinen 	if (!val)
72d86e5828SJouni Malinen 		val = "P-256";
73d86e5828SJouni Malinen 	else if (strcasecmp(val, "BP-256R1") == 0)
74d86e5828SJouni Malinen 		val = "BP-256";
75d86e5828SJouni Malinen 	else if (strcasecmp(val, "BP-384R1") == 0)
76d86e5828SJouni Malinen 		val = "BP-384";
77d86e5828SJouni Malinen 	else if (strcasecmp(val, "BP-512R1") == 0)
78d86e5828SJouni Malinen 		val = "BP-512";
79d86e5828SJouni Malinen 
80d86e5828SJouni Malinen 	return val;
81d86e5828SJouni Malinen }
82d86e5828SJouni Malinen 
83d86e5828SJouni Malinen 
8489cf6d64SJouni Malinen static enum sigma_cmd_result
8589cf6d64SJouni Malinen dpp_get_local_bootstrap(struct sigma_dut *dut, struct sigma_conn *conn,
8689cf6d64SJouni Malinen 			struct sigma_cmd *cmd, int send_result, int *success)
87d86e5828SJouni Malinen {
88d86e5828SJouni Malinen 	const char *curve = dpp_get_curve(cmd, "DPPCryptoIdentifier");
89d86e5828SJouni Malinen 	const char *bs = get_param(cmd, "DPPBS");
904161c3f0SJouni Malinen 	const char *chan_list = get_param(cmd, "DPPChannelList");
914161c3f0SJouni Malinen 	char *pos, mac[50], buf[200], resp[1000], hex[2000];
92016ae6c8SJouni Malinen 	const char *ifname = get_station_ifname(dut);
933aa72861SJouni Malinen 	int res;
946f4ce416SJouni Malinen 	const char *type;
95d86e5828SJouni Malinen 
96bc9e055cSSrinivas Dasari 	if (success)
97bc9e055cSSrinivas Dasari 		*success = 0;
986f4ce416SJouni Malinen 	if (strcasecmp(bs, "QR") == 0) {
996f4ce416SJouni Malinen 		type = "qrcode";
1006f4ce416SJouni Malinen 	} else if (strcasecmp(bs, "NFC") == 0) {
1016f4ce416SJouni Malinen 		type ="nfc-uri";
1026f4ce416SJouni Malinen 	} else {
103d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
104d86e5828SJouni Malinen 			  "errorCode,Unsupported DPPBS");
10589cf6d64SJouni Malinen 		return STATUS_SENT_ERROR;
106d86e5828SJouni Malinen 	}
107d86e5828SJouni Malinen 
108d86e5828SJouni Malinen 	if (sigma_dut_is_ap(dut)) {
109d86e5828SJouni Malinen 		u8 bssid[ETH_ALEN];
110d86e5828SJouni Malinen 
111d86e5828SJouni Malinen 		if (!dut->hostapd_ifname) {
112d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_ERROR,
113d86e5828SJouni Malinen 					"hostapd ifname not specified (-j)");
11489cf6d64SJouni Malinen 			return ERROR_SEND_STATUS;
115d86e5828SJouni Malinen 		}
116d86e5828SJouni Malinen 		ifname = dut->hostapd_ifname;
117d86e5828SJouni Malinen 		if (get_hwaddr(dut->hostapd_ifname, bssid) < 0) {
118d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_ERROR,
119d86e5828SJouni Malinen 					"Could not get MAC address for %s",
120d86e5828SJouni Malinen 					dut->hostapd_ifname);
12189cf6d64SJouni Malinen 			return ERROR_SEND_STATUS;
122d86e5828SJouni Malinen 		}
123d86e5828SJouni Malinen 		snprintf(mac, sizeof(mac), "%02x%02x%02x%02x%02x%02x",
124d86e5828SJouni Malinen 			 bssid[0], bssid[1], bssid[2],
125d86e5828SJouni Malinen 			 bssid[3], bssid[4], bssid[5]);
126d86e5828SJouni Malinen 	} else {
1274046416bSJouni Malinen 		if (get_wpa_status(ifname, "address", mac, sizeof(mac)) < 0) {
1284046416bSJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1294046416bSJouni Malinen 				  "errorCode,Failed to get own MAC address from wpa_supplicant");
1304046416bSJouni Malinen 			return STATUS_SENT_ERROR;
1314046416bSJouni Malinen 		}
132d86e5828SJouni Malinen 	}
133d86e5828SJouni Malinen 
134d86e5828SJouni Malinen 	pos = mac;
135d86e5828SJouni Malinen 	while (*pos) {
136d86e5828SJouni Malinen 		if (*pos == ':')
137d86e5828SJouni Malinen 			memmove(pos, pos + 1, strlen(pos));
138d86e5828SJouni Malinen 		else
139d86e5828SJouni Malinen 			pos++;
140d86e5828SJouni Malinen 	}
141d86e5828SJouni Malinen 
142d86e5828SJouni Malinen 	if (sigma_dut_is_ap(dut) && dpp_hostapd_run(dut) < 0) {
143d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
144d86e5828SJouni Malinen 			  "errorCode,Failed to start hostapd");
14589cf6d64SJouni Malinen 		return STATUS_SENT_ERROR;
146d86e5828SJouni Malinen 	}
147d86e5828SJouni Malinen 
1484161c3f0SJouni Malinen 	if (chan_list &&
1494161c3f0SJouni Malinen 	    (strcmp(chan_list, "0/0") == 0 || chan_list[0] == '\0')) {
1504161c3f0SJouni Malinen 		/* No channel list */
1513aa72861SJouni Malinen 		res = snprintf(buf, sizeof(buf),
1526f4ce416SJouni Malinen 			       "DPP_BOOTSTRAP_GEN type=%s curve=%s mac=%s",
1536f4ce416SJouni Malinen 			       type, curve, mac);
1544161c3f0SJouni Malinen 	} else if (chan_list) {
1554161c3f0SJouni Malinen 		/* Channel list override (CTT case) - space separated tuple(s)
1564161c3f0SJouni Malinen 		 * of OperatingClass/Channel; convert to wpa_supplicant/hostapd
1574161c3f0SJouni Malinen 		 * format: comma separated tuples */
1584161c3f0SJouni Malinen 		strlcpy(resp, chan_list, sizeof(resp));
1594161c3f0SJouni Malinen 		for (pos = resp; *pos; pos++) {
1604161c3f0SJouni Malinen 			if (*pos == ' ')
1614161c3f0SJouni Malinen 				*pos = ',';
1624161c3f0SJouni Malinen 		}
1633aa72861SJouni Malinen 		res = snprintf(buf, sizeof(buf),
1646f4ce416SJouni Malinen 			       "DPP_BOOTSTRAP_GEN type=%s curve=%s chan=%s mac=%s",
1656f4ce416SJouni Malinen 			       type, curve, resp, mac);
1664161c3f0SJouni Malinen 	} else {
167f8d81aa4SJouni Malinen 		int channel = 11;
168f8d81aa4SJouni Malinen 
1694161c3f0SJouni Malinen 		/* Default channel list (normal DUT case) */
170f8d81aa4SJouni Malinen 		if (sigma_dut_is_ap(dut) && dut->hostapd_running &&
171f8d81aa4SJouni Malinen 		    dut->ap_oper_chn &&
172f8d81aa4SJouni Malinen 		    dut->ap_channel > 0 && dut->ap_channel <= 13)
173f8d81aa4SJouni Malinen 			channel = dut->ap_channel;
1743aa72861SJouni Malinen 		res = snprintf(buf, sizeof(buf),
1756f4ce416SJouni Malinen 			       "DPP_BOOTSTRAP_GEN type=%s curve=%s chan=81/%d mac=%s",
1766f4ce416SJouni Malinen 			       type, curve, channel, mac);
1774161c3f0SJouni Malinen 	}
1784161c3f0SJouni Malinen 
1793aa72861SJouni Malinen 	if (res < 0 || res >= sizeof(buf) ||
18089cf6d64SJouni Malinen 	    wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 ||
18189cf6d64SJouni Malinen 	    strncmp(resp, "FAIL", 4) == 0)
18289cf6d64SJouni Malinen 		return ERROR_SEND_STATUS;
183d86e5828SJouni Malinen 	dut->dpp_local_bootstrap = atoi(resp);
184d86e5828SJouni Malinen 	snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d",
185d86e5828SJouni Malinen 		 atoi(resp));
18689cf6d64SJouni Malinen 	if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 ||
18789cf6d64SJouni Malinen 	    strncmp(resp, "FAIL", 4) == 0)
18889cf6d64SJouni Malinen 		return ERROR_SEND_STATUS;
189d86e5828SJouni Malinen 
190d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", resp);
191bc9e055cSSrinivas Dasari 
192bc9e055cSSrinivas Dasari 	if (send_result) {
193d86e5828SJouni Malinen 		ascii2hexstr(resp, hex);
1943aa72861SJouni Malinen 		res = snprintf(resp, sizeof(resp), "BootstrappingData,%s", hex);
1953aa72861SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
1963aa72861SJouni Malinen 			  res >= 0 && res < sizeof(resp) ? resp : NULL);
197bc9e055cSSrinivas Dasari 	}
198bc9e055cSSrinivas Dasari 
199bc9e055cSSrinivas Dasari 	if (success)
200bc9e055cSSrinivas Dasari 		*success = 1;
20189cf6d64SJouni Malinen 	return STATUS_SENT;
202d86e5828SJouni Malinen }
203d86e5828SJouni Malinen 
204d86e5828SJouni Malinen 
20589cf6d64SJouni Malinen static enum sigma_cmd_result dpp_set_peer_bootstrap(struct sigma_dut *dut,
206d86e5828SJouni Malinen 						    struct sigma_conn *conn,
207d86e5828SJouni Malinen 						    struct sigma_cmd *cmd)
208d86e5828SJouni Malinen {
209d86e5828SJouni Malinen 	const char *val = get_param(cmd, "DPPBootstrappingdata");
210b1dd21f8SJouni Malinen 	char uri[1000];
211d86e5828SJouni Malinen 	int res;
212d86e5828SJouni Malinen 
213d86e5828SJouni Malinen 	if (!val) {
214d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
215d86e5828SJouni Malinen 			  "errorCode,Missing DPPBootstrappingdata");
21689cf6d64SJouni Malinen 		return STATUS_SENT_ERROR;
217d86e5828SJouni Malinen 	}
218d86e5828SJouni Malinen 
219d86e5828SJouni Malinen 	res = parse_hexstr(val, (unsigned char *) uri, sizeof(uri));
220d86e5828SJouni Malinen 	if (res < 0 || (size_t) res >= sizeof(uri))
22189cf6d64SJouni Malinen 		return ERROR_SEND_STATUS;
222d86e5828SJouni Malinen 	uri[res] = '\0';
223d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", uri);
224b1dd21f8SJouni Malinen 	free(dut->dpp_peer_uri);
225b1dd21f8SJouni Malinen 	dut->dpp_peer_uri = strdup(uri);
226d86e5828SJouni Malinen 
22789cf6d64SJouni Malinen 	return SUCCESS_SEND_STATUS;
228d86e5828SJouni Malinen }
229d86e5828SJouni Malinen 
230d86e5828SJouni Malinen 
231d86e5828SJouni Malinen static int dpp_hostapd_conf_update(struct sigma_dut *dut,
232d86e5828SJouni Malinen 				   struct sigma_conn *conn, const char *ifname,
233d86e5828SJouni Malinen 				   struct wpa_ctrl *ctrl)
234d86e5828SJouni Malinen {
235d86e5828SJouni Malinen 	int res;
236d86e5828SJouni Malinen 	char buf[2000], buf2[2500], *pos, *pos2;
237b4c5e3b8SJouni Malinen 	const char *conf_data_events[] = {
238b4c5e3b8SJouni Malinen 		"DPP-CONNECTOR",
239b4c5e3b8SJouni Malinen 		"DPP-CONFOBJ-PASS",
240b4c5e3b8SJouni Malinen 		"DPP-CONFOBJ-PSK",
2410cd6e363SJouni Malinen 		"DPP-C-SIGN-KEY",
2420cd6e363SJouni Malinen 		"DPP-NET-ACCESS-KEY",
243b4c5e3b8SJouni Malinen 		NULL
244b4c5e3b8SJouni Malinen 	};
24520465812SJouni Malinen 	unsigned int old_timeout;
2460cd6e363SJouni Malinen 	int legacy_akm, dpp_akm;
2470cd6e363SJouni Malinen 	char *connector = NULL, *psk = NULL, *csign = NULL,
2480cd6e363SJouni Malinen 		*net_access_key = NULL;
2490cd6e363SJouni Malinen 	char pass[64];
2500cd6e363SJouni Malinen 	int pass_len = 0;
2510cd6e363SJouni Malinen 	int ret = 0;
252d86e5828SJouni Malinen 
253d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO,
254d86e5828SJouni Malinen 			"Update hostapd configuration based on DPP Config Object");
255d86e5828SJouni Malinen 
256d86e5828SJouni Malinen 	if (wpa_command(ifname, "SET wpa 2") < 0 ||
257d86e5828SJouni Malinen 	    wpa_command(ifname, "SET wpa_key_mgmt DPP") < 0 ||
2580d34723dSJouni Malinen 	    wpa_command(ifname, "SET ieee80211w 1") < 0 ||
259d86e5828SJouni Malinen 	    wpa_command(ifname, "SET rsn_pairwise CCMP") < 0) {
260d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
261d86e5828SJouni Malinen 			  "errorCode,Failed to update AP security parameters");
262d86e5828SJouni Malinen 		goto out;
263d86e5828SJouni Malinen 	}
264d86e5828SJouni Malinen 
2650cd6e363SJouni Malinen 	res = get_wpa_cli_event(dut, ctrl, "DPP-CONFOBJ-AKM", buf, sizeof(buf));
2660cd6e363SJouni Malinen 	if (res < 0) {
2670cd6e363SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
2680cd6e363SJouni Malinen 			  "errorCode,No DPP-CONFOBJ-AKM");
2690cd6e363SJouni Malinen 		goto out;
2700cd6e363SJouni Malinen 	}
2710cd6e363SJouni Malinen 	pos = strchr(buf, ' ');
2720cd6e363SJouni Malinen 	if (!pos)
2730cd6e363SJouni Malinen 		return -2;
2740cd6e363SJouni Malinen 	pos++;
2750cd6e363SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO,
2760cd6e363SJouni Malinen 			"DPP: Config Object AKM: %s", pos);
2770cd6e363SJouni Malinen 	legacy_akm = strstr(pos, "psk") != NULL || strstr(pos, "sae") != NULL;
2780cd6e363SJouni Malinen 	dpp_akm = strstr(pos, "dpp") != NULL;
2790cd6e363SJouni Malinen 
280d86e5828SJouni Malinen 	res = get_wpa_cli_event(dut, ctrl, "DPP-CONFOBJ-SSID",
281d86e5828SJouni Malinen 				buf, sizeof(buf));
282d86e5828SJouni Malinen 	if (res < 0) {
283d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
284d86e5828SJouni Malinen 			  "errorCode,No DPP-CONFOBJ-SSID");
285d86e5828SJouni Malinen 		goto out;
286d86e5828SJouni Malinen 	}
287d86e5828SJouni Malinen 	pos = strchr(buf, ' ');
288d86e5828SJouni Malinen 	if (!pos)
289d86e5828SJouni Malinen 		return -2;
290d86e5828SJouni Malinen 	pos++;
291d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO,
292d86e5828SJouni Malinen 			"DPP: Config Object SSID: %s", pos);
293d86e5828SJouni Malinen 	snprintf(buf2, sizeof(buf2), "SET ssid %s", pos);
294d86e5828SJouni Malinen 	if (wpa_command(ifname, buf2) < 0) {
295d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
296d86e5828SJouni Malinen 			  "errorCode,Failed to update AP SSID");
297d86e5828SJouni Malinen 		goto out;
298d86e5828SJouni Malinen 	}
299d86e5828SJouni Malinen 
300a7631f10SJouni Malinen 	if (wpa_command(ifname, "SET utf8_ssid 1") < 0) {
301a7631f10SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
302a7631f10SJouni Malinen 			  "errorCode,Failed to update AP UTF-8 SSID capa");
303a7631f10SJouni Malinen 		goto out;
304a7631f10SJouni Malinen 	}
305a7631f10SJouni Malinen 
3060cd6e363SJouni Malinen 	while ((dpp_akm && (!connector || !csign || !net_access_key)) ||
3070cd6e363SJouni Malinen 	       (legacy_akm && !pass_len && !psk)) {
3080cd6e363SJouni Malinen 		res = get_wpa_cli_events(dut, ctrl, conf_data_events,
3090cd6e363SJouni Malinen 					 buf, sizeof(buf));
310d86e5828SJouni Malinen 		if (res < 0) {
311d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
3120cd6e363SJouni Malinen 				  "errorCode,Not all config object information received");
313d86e5828SJouni Malinen 			goto out;
314d86e5828SJouni Malinen 		}
315b4c5e3b8SJouni Malinen 
3160cd6e363SJouni Malinen 		if (strstr(buf, "DPP-CONNECTOR")) {
3170cd6e363SJouni Malinen 			pos = strchr(buf, ' ');
3180cd6e363SJouni Malinen 			if (!pos) {
3190cd6e363SJouni Malinen 				ret = -2;
3200cd6e363SJouni Malinen 				goto out;
3210cd6e363SJouni Malinen 			}
3220cd6e363SJouni Malinen 			pos++;
3230cd6e363SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO, "DPP: Connector: %s",
3240cd6e363SJouni Malinen 					pos);
3250cd6e363SJouni Malinen 			if (!connector)
3260cd6e363SJouni Malinen 				connector = strdup(pos);
3270cd6e363SJouni Malinen 		} else if (strstr(buf, "DPP-C-SIGN-KEY")) {
3280cd6e363SJouni Malinen 			pos = strchr(buf, ' ');
3290cd6e363SJouni Malinen 			if (!pos) {
3300cd6e363SJouni Malinen 				ret = -2;
3310cd6e363SJouni Malinen 				goto out;
3320cd6e363SJouni Malinen 			}
3330cd6e363SJouni Malinen 			pos++;
3340cd6e363SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
3350cd6e363SJouni Malinen 					"DPP: C-sign-key: %s", pos);
3360cd6e363SJouni Malinen 			if (!csign)
3370cd6e363SJouni Malinen 				csign = strdup(pos);
3380cd6e363SJouni Malinen 		} else if (strstr(buf, "DPP-NET-ACCESS-KEY")) {
3390cd6e363SJouni Malinen 			pos = strchr(buf, ' ');
3400cd6e363SJouni Malinen 			if (!pos) {
3410cd6e363SJouni Malinen 				ret = -2;
3420cd6e363SJouni Malinen 				goto out;
3430cd6e363SJouni Malinen 			}
3440cd6e363SJouni Malinen 			pos++;
3450cd6e363SJouni Malinen 			if (!net_access_key)
3460cd6e363SJouni Malinen 				net_access_key = strdup(pos);
3470cd6e363SJouni Malinen 		} else if (strstr(buf, "DPP-CONFOBJ-PASS")) {
3480cd6e363SJouni Malinen 			pos = strchr(buf, ' ');
3490cd6e363SJouni Malinen 			if (!pos) {
3500cd6e363SJouni Malinen 				ret = -2;
3510cd6e363SJouni Malinen 				goto out;
3520cd6e363SJouni Malinen 			}
3530cd6e363SJouni Malinen 			pos++;
3540cd6e363SJouni Malinen 			pass_len = parse_hexstr(pos, (u8 *) pass, sizeof(pass));
3550cd6e363SJouni Malinen 			if (pass_len < 0 || (size_t) pass_len >= sizeof(pass)) {
3560cd6e363SJouni Malinen 				ret = -2;
3570cd6e363SJouni Malinen 				goto out;
3580cd6e363SJouni Malinen 			}
3590cd6e363SJouni Malinen 			pass[pass_len] = '\0';
3600cd6e363SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
3610cd6e363SJouni Malinen 					"DPP: Passphrase: %s", pass);
3620cd6e363SJouni Malinen 		} else if (strstr(buf, "DPP-CONFOBJ-PSK")) {
3630cd6e363SJouni Malinen 			pos = strchr(buf, ' ');
3640cd6e363SJouni Malinen 			if (!pos) {
3650cd6e363SJouni Malinen 				ret = -2;
3660cd6e363SJouni Malinen 				goto out;
3670cd6e363SJouni Malinen 			}
3680cd6e363SJouni Malinen 			pos++;
3690cd6e363SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO, "DPP: PSK: %s", pos);
3700cd6e363SJouni Malinen 			if (!psk)
3710cd6e363SJouni Malinen 				psk = strdup(pos);
3720cd6e363SJouni Malinen 		}
3730cd6e363SJouni Malinen 	}
3740cd6e363SJouni Malinen 
3750cd6e363SJouni Malinen 	if ((!connector || !dpp_akm) &&
3760cd6e363SJouni Malinen 	    wpa_command(ifname, "SET wpa_key_mgmt WPA-PSK") < 0) {
377b4c5e3b8SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
378b4c5e3b8SJouni Malinen 			  "errorCode,Failed to update AP security parameters");
379b4c5e3b8SJouni Malinen 		goto out;
380b4c5e3b8SJouni Malinen 	}
381b4c5e3b8SJouni Malinen 
3820cd6e363SJouni Malinen 	if (connector && dpp_akm && legacy_akm &&
3830cd6e363SJouni Malinen 	    wpa_command(ifname, "SET wpa_key_mgmt DPP WPA-PSK") < 0) {
3840cd6e363SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
3850cd6e363SJouni Malinen 			  "errorCode,Failed to update AP security parameters");
3860cd6e363SJouni Malinen 		goto out;
3870cd6e363SJouni Malinen 	}
388b4c5e3b8SJouni Malinen 
3890cd6e363SJouni Malinen 	if (pass_len) {
390b4c5e3b8SJouni Malinen 		snprintf(buf2, sizeof(buf2), "SET wpa_passphrase %s",
391b4c5e3b8SJouni Malinen 			 pass);
392b4c5e3b8SJouni Malinen 		if (wpa_command(ifname, buf2) < 0) {
393b4c5e3b8SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
394b4c5e3b8SJouni Malinen 				  "errorCode,Failed to set passphrase");
395b4c5e3b8SJouni Malinen 			goto out;
396b4c5e3b8SJouni Malinen 		}
3970cd6e363SJouni Malinen 	} else if (psk) {
3980cd6e363SJouni Malinen 		snprintf(buf2, sizeof(buf2), "SET wpa_psk %s", psk);
399b4c5e3b8SJouni Malinen 		if (wpa_command(ifname, buf2) < 0) {
400b4c5e3b8SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
401b4c5e3b8SJouni Malinen 				  "errorCode,Failed to set PSK");
402b4c5e3b8SJouni Malinen 			goto out;
403b4c5e3b8SJouni Malinen 		}
404b4c5e3b8SJouni Malinen 	}
405b4c5e3b8SJouni Malinen 
4060cd6e363SJouni Malinen 	if (connector) {
4070cd6e363SJouni Malinen 		snprintf(buf2, sizeof(buf2), "SET dpp_connector %s", connector);
408d86e5828SJouni Malinen 		if (wpa_command(ifname, buf2) < 0) {
409d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
410d86e5828SJouni Malinen 				  "errorCode,Failed to update AP Connector");
411d86e5828SJouni Malinen 			goto out;
412d86e5828SJouni Malinen 		}
413d86e5828SJouni Malinen 	}
4140cd6e363SJouni Malinen 
4150cd6e363SJouni Malinen 	if (csign) {
4160cd6e363SJouni Malinen 		snprintf(buf2, sizeof(buf2), "SET dpp_csign %s", csign);
417d86e5828SJouni Malinen 		if (wpa_command(ifname, buf2) < 0) {
418d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
419d86e5828SJouni Malinen 				  "errorCode,Failed to update AP C-sign-key");
420d86e5828SJouni Malinen 			goto out;
421d86e5828SJouni Malinen 		}
422d86e5828SJouni Malinen 	}
4230cd6e363SJouni Malinen 
4240cd6e363SJouni Malinen 	if (net_access_key) {
4250cd6e363SJouni Malinen 		pos2 = strchr(net_access_key, ' ');
426d86e5828SJouni Malinen 		if (pos2)
427d86e5828SJouni Malinen 			*pos2++ = '\0';
4280cd6e363SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_INFO, "DPP: netAccessKey: %s",
4290cd6e363SJouni Malinen 				net_access_key);
4300cd6e363SJouni Malinen 		snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey %s",
4310cd6e363SJouni Malinen 			 net_access_key);
432d86e5828SJouni Malinen 		if (wpa_command(ifname, buf2) < 0) {
433d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
434d86e5828SJouni Malinen 				  "errorCode,Failed to update AP netAccessKey");
435d86e5828SJouni Malinen 			goto out;
436d86e5828SJouni Malinen 		}
437d86e5828SJouni Malinen 		if (pos2) {
438d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
439d86e5828SJouni Malinen 					"DPP: netAccessKey expiry: %s", pos2);
4400cd6e363SJouni Malinen 			snprintf(buf2, sizeof(buf2),
4410cd6e363SJouni Malinen 				 "SET dpp_netaccesskey_expiry %s", pos2);
442d86e5828SJouni Malinen 			if (wpa_command(ifname, buf2) < 0) {
443d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
444d86e5828SJouni Malinen 					  "errorCode,Failed to update AP netAccessKey expiry");
445d86e5828SJouni Malinen 				goto out;
446d86e5828SJouni Malinen 			}
447d86e5828SJouni Malinen 		}
4480cd6e363SJouni Malinen 	}
449d86e5828SJouni Malinen 
450d2e9bb3eSJouni Malinen 	if (wpa_command(ifname, "SET start_disabled 0") < 0 &&
451d2e9bb3eSJouni Malinen 	    dut->ap_start_disabled) {
452d2e9bb3eSJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
453d2e9bb3eSJouni Malinen 			  "errorCode,Failed to update AP security parameters");
454d2e9bb3eSJouni Malinen 		goto out;
455d2e9bb3eSJouni Malinen 	}
456d2e9bb3eSJouni Malinen 	dut->ap_start_disabled = 0;
457d2e9bb3eSJouni Malinen 
45820465812SJouni Malinen 	/* Wait for a possible Configuration Result to be sent */
45920465812SJouni Malinen 	old_timeout = dut->default_timeout;
46020465812SJouni Malinen 	dut->default_timeout = 1;
46120465812SJouni Malinen 	get_wpa_cli_event(dut, ctrl, "DPP-TX-STATUS", buf, sizeof(buf));
46220465812SJouni Malinen 	dut->default_timeout = old_timeout;
463d86e5828SJouni Malinen 	if (wpa_command(ifname, "DISABLE") < 0 ||
464d86e5828SJouni Malinen 	    wpa_command(ifname, "ENABLE") < 0) {
465d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
466d86e5828SJouni Malinen 			  "errorCode,Failed to update AP configuration");
467d86e5828SJouni Malinen 		goto out;
468d86e5828SJouni Malinen 	}
469d86e5828SJouni Malinen 
470d86e5828SJouni Malinen 	res = get_wpa_cli_event(dut, ctrl, "AP-ENABLED", buf, sizeof(buf));
471d86e5828SJouni Malinen 	if (res < 0) {
472d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,No AP-ENABLED");
473d86e5828SJouni Malinen 		goto out;
474d86e5828SJouni Malinen 	}
475d86e5828SJouni Malinen 
4760cd6e363SJouni Malinen 	ret = 1;
477d86e5828SJouni Malinen out:
4780cd6e363SJouni Malinen 	free(connector);
4790cd6e363SJouni Malinen 	free(psk);
4800cd6e363SJouni Malinen 	free(csign);
4810cd6e363SJouni Malinen 	free(net_access_key);
4820cd6e363SJouni Malinen 	return ret;
483d86e5828SJouni Malinen }
484d86e5828SJouni Malinen 
485d86e5828SJouni Malinen 
486772299f1SJouni Malinen struct dpp_test_info {
487772299f1SJouni Malinen 	const char *step;
488772299f1SJouni Malinen 	const char *frame;
489772299f1SJouni Malinen 	const char *attr;
490772299f1SJouni Malinen 	int value;
491772299f1SJouni Malinen };
492772299f1SJouni Malinen 
493772299f1SJouni Malinen static const struct dpp_test_info dpp_tests[] = {
494772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationRequest", "WrappedData", 1 },
495772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "WrappedData", 2 },
496f96fcee3SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "PrimaryWrappedData", 2 },
497772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationConfirm", "WrappedData", 3 },
498772299f1SJouni Malinen 	{ "InvalidValue", "PKEXCRRequest", "WrappedData", 4 },
499772299f1SJouni Malinen 	{ "InvalidValue", "PKEXCRResponse", "WrappedData", 5 },
500772299f1SJouni Malinen 	{ "InvalidValue", "ConfigurationRequest", "WrappedData", 6 },
501772299f1SJouni Malinen 	{ "InvalidValue", "ConfigurationResponse", "WrappedData", 7 },
502772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationRequest", "InitCapabilities", 8 },
503772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationRequest", "RespBSKeyHash", 10 },
504772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationRequest", "InitBSKeyHash", 11 },
505772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationRequest", "InitProtocolKey", 12 },
506772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationRequest", "InitNonce", 13 },
507772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationRequest", "InitCapabilities", 14 },
508772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationRequest", "WrappedData", 15 },
509772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "DPPStatus", 16 },
510772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "RespBSKeyHash", 17 },
511772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "InitBSKeyHash", 18 },
512772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "RespProtocolKey", 19 },
513772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "RespNonce", 20 },
514772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "InitNonce", 21 },
515772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "RespCapabilities",
516772299f1SJouni Malinen 	  22 },
517772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "RespAuthTag", 23 },
518772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "WrappedData", 24 },
519f96fcee3SJouni Malinen 	{ "MissingAttribute", "AuthenticationResponse", "PrimaryWrappedData",
520f96fcee3SJouni Malinen 	  24 },
521772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationConfirm", "DPPStatus", 25 },
522772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationConfirm", "RespBSKeyHash", 26 },
523772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationConfirm", "InitBSKeyHash", 27 },
524772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationConfirm", "InitAuthTag", 28 },
525772299f1SJouni Malinen 	{ "MissingAttribute", "AuthenticationConfirm", "WrappedData", 29 },
526772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "InitNonce", 30 },
527772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "RespCapabilities", 31 },
528772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "RespAuthTag", 32 },
529772299f1SJouni Malinen 	{ "InvalidValue", "AuthenticationConfirm", "InitAuthTag", 33 },
530772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXExchangeRequest", "FiniteCyclicGroup", 34 },
531772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXExchangeRequest", "EncryptedKey", 35 },
532772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXExchangeResponse", "DPPStatus", 36 },
533772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXExchangeResponse", "EncryptedKey", 37 },
534772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXCRRequest", "BSKey", 38 },
535772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXCRRequest", "InitAuthTag", 39 },
536772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXCRRequest", "WrappedData", 40 },
537772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXCRResponse", "BSKey", 41 },
538772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXCRResponse", "RespAuthTag", 42 },
539772299f1SJouni Malinen 	{ "MissingAttribute", "PKEXCRResponse", "WrappedData", 43 },
540772299f1SJouni Malinen 	{ "InvalidValue", "PKEXExchangeRequest", "EncryptedKey", 44 },
541772299f1SJouni Malinen 	{ "InvalidValue", "PKEXExchangeResponse", "EncryptedKey", 45 },
542772299f1SJouni Malinen 	{ "InvalidValue", "PKEXExchangeResponse", "DPPStatus", 46 },
543772299f1SJouni Malinen 	{ "InvalidValue", "PKEXCRRequest", "BSKey", 47 },
544772299f1SJouni Malinen 	{ "InvalidValue", "PKEXCRResponse", "BSKey", 48 },
545772299f1SJouni Malinen 	{ "InvalidValue", "PKEXCRRequest", "InitAuthTag", 49 },
546772299f1SJouni Malinen 	{ "InvalidValue", "PKEXCRResponse", "RespAuthTag", 50 },
547772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationRequest", "EnrolleeNonce", 51 },
548772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationRequest", "ConfigAttr", 52 },
549772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationRequest", "WrappedData", 53 },
550772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationResponse", "EnrolleeNonce", 54 },
551772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationResponse", "ConfigObj", 55 },
552772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationResponse", "DPPStatus", 56 },
553772299f1SJouni Malinen 	{ "MissingAttribute", "ConfigurationResponse", "WrappedData", 57 },
554772299f1SJouni Malinen 	{ "InvalidValue", "ConfigurationResponse", "DPPStatus", 58 },
555772299f1SJouni Malinen 	{ "InvalidValue", "ConfigurationResponse", "EnrolleeNonce", 59 },
55653558e0fSJouni Malinen 	{ "MissingAttribute", "PeerDiscoveryRequest", "TransactionID", 60 },
55753558e0fSJouni Malinen 	{ "MissingAttribute", "PeerDiscoveryRequest", "Connector", 61 },
55853558e0fSJouni Malinen 	{ "MissingAttribute", "PeerDiscoveryResponse", "TransactionID", 62 },
55953558e0fSJouni Malinen 	{ "MissingAttribute", "PeerDiscoveryResponse", "DPPStatus", 63 },
56053558e0fSJouni Malinen 	{ "MissingAttribute", "PeerDiscoveryResponse", "Connector", 64 },
561ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationRequest", "InitProtocolKey", 66 },
562ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "RespProtocolKey", 67 },
563ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationRequest", "RespBSKeyHash", 68 },
564ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationRequest", "InitBSKeyHash", 69 },
565ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "RespBSKeyHash", 70 },
566ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "InitBSKeyHash", 71 },
567ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationConfirm", "RespBSKeyHash", 72 },
568ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationConfirm", "InitBSKeyHash", 73 },
569ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationResponse", "DPPStatus", 74 },
570ae624487SJouni Malinen 	{ "InvalidValue", "AuthenticationConfirm", "DPPStatus", 75 },
571ae624487SJouni Malinen 	{ "InvalidValue", "ConfigurationRequest", "ConfigAttr", 76 },
572ae624487SJouni Malinen 	{ "InvalidValue", "PeerDiscoveryResponse", "TransactionID", 77 },
573ae624487SJouni Malinen 	{ "InvalidValue", "PeerDiscoveryResponse", "DPPStatus", 78 },
574ae624487SJouni Malinen 	{ "InvalidValue", "PeerDiscoveryResponse", "Connector", 79 },
575ae624487SJouni Malinen 	{ "InvalidValue", "PeerDiscoveryRequest", "Connector", 80 },
57667795a76SJouni Malinen 	{ "InvalidValue", "AuthenticationRequest", "InitNonce", 81 },
577188839b6SJouni Malinen 	{ "InvalidValue", "PeerDiscoveryRequest", "TransactionID", 82 },
578188839b6SJouni Malinen 	{ "InvalidValue", "ConfigurationRequest", "EnrolleeNonce", 83 },
5793a6b92a6SJouni Malinen 	{ "Timeout", "PKEXExchangeResponse", NULL, 84 },
5803a6b92a6SJouni Malinen 	{ "Timeout", "PKEXCRRequest", NULL, 85 },
5813a6b92a6SJouni Malinen 	{ "Timeout", "PKEXCRResponse", NULL, 86 },
5823a6b92a6SJouni Malinen 	{ "Timeout", "AuthenticationRequest", NULL, 87 },
5833a6b92a6SJouni Malinen 	{ "Timeout", "AuthenticationResponse", NULL, 88 },
5843a6b92a6SJouni Malinen 	{ "Timeout", "AuthenticationConfirm", NULL, 89 },
5853a6b92a6SJouni Malinen 	{ "Timeout", "ConfigurationRequest", NULL, 90 },
586772299f1SJouni Malinen 	{ NULL, NULL, NULL, 0 }
587772299f1SJouni Malinen };
588772299f1SJouni Malinen 
589772299f1SJouni Malinen 
590772299f1SJouni Malinen static int dpp_get_test(const char *step, const char *frame, const char *attr)
591772299f1SJouni Malinen {
592772299f1SJouni Malinen 	int i;
593772299f1SJouni Malinen 
594772299f1SJouni Malinen 	for (i = 0; dpp_tests[i].step; i++) {
595772299f1SJouni Malinen 		if (strcasecmp(step, dpp_tests[i].step) == 0 &&
596772299f1SJouni Malinen 		    strcasecmp(frame, dpp_tests[i].frame) == 0 &&
5973a6b92a6SJouni Malinen 		    ((!attr && dpp_tests[i].attr == NULL) ||
5983a6b92a6SJouni Malinen 		     (attr && strcasecmp(attr, dpp_tests[i].attr) == 0)))
599772299f1SJouni Malinen 			return dpp_tests[i].value;
600772299f1SJouni Malinen 	}
601772299f1SJouni Malinen 
602772299f1SJouni Malinen 	return -1;
603772299f1SJouni Malinen }
604772299f1SJouni Malinen 
605772299f1SJouni Malinen 
6066792ff4dSJouni Malinen static int dpp_wait_tx(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
6076792ff4dSJouni Malinen 		       int frame_type)
6086792ff4dSJouni Malinen {
6096792ff4dSJouni Malinen 	char buf[200], tmp[20];
6106792ff4dSJouni Malinen 	int res;
6116792ff4dSJouni Malinen 
6126792ff4dSJouni Malinen 	snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
6136792ff4dSJouni Malinen 	for (;;) {
6146792ff4dSJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf));
6156792ff4dSJouni Malinen 		if (res < 0)
6166792ff4dSJouni Malinen 			return -1;
6176792ff4dSJouni Malinen 		if (strstr(buf, tmp) != NULL)
6186792ff4dSJouni Malinen 			break;
6196792ff4dSJouni Malinen 	}
6206792ff4dSJouni Malinen 
6216792ff4dSJouni Malinen 	return 0;
6226792ff4dSJouni Malinen }
6236792ff4dSJouni Malinen 
6246792ff4dSJouni Malinen 
625772299f1SJouni Malinen static int dpp_wait_tx_status(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
626772299f1SJouni Malinen 			      int frame_type)
627772299f1SJouni Malinen {
628772299f1SJouni Malinen 	char buf[200], tmp[20];
629772299f1SJouni Malinen 	int res;
630772299f1SJouni Malinen 
631772299f1SJouni Malinen 	snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
632772299f1SJouni Malinen 	for (;;) {
633772299f1SJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf));
634772299f1SJouni Malinen 		if (res < 0)
635772299f1SJouni Malinen 			return -1;
636772299f1SJouni Malinen 		if (strstr(buf, tmp) != NULL)
637772299f1SJouni Malinen 			break;
638772299f1SJouni Malinen 	}
639772299f1SJouni Malinen 
640772299f1SJouni Malinen 	res = get_wpa_cli_event(dut, ctrl, "DPP-TX-STATUS",
641772299f1SJouni Malinen 				buf, sizeof(buf));
642772299f1SJouni Malinen 	if (res < 0 || strstr(buf, "result=FAILED") != NULL)
643772299f1SJouni Malinen 		return -1;
644772299f1SJouni Malinen 
645772299f1SJouni Malinen 	return 0;
646772299f1SJouni Malinen }
647772299f1SJouni Malinen 
648772299f1SJouni Malinen 
6493a6b92a6SJouni Malinen static int dpp_wait_rx(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
6503e4344e7SJouni Malinen 		       int frame_type, unsigned int max_wait)
6513a6b92a6SJouni Malinen {
6523a6b92a6SJouni Malinen 	char buf[200], tmp[20];
6533a6b92a6SJouni Malinen 	int res;
6549a3415c2SJouni Malinen 	unsigned int old_timeout;
6559a3415c2SJouni Malinen 
6569a3415c2SJouni Malinen 	old_timeout = dut->default_timeout;
6579a3415c2SJouni Malinen 	if (max_wait > 0 && dut->default_timeout > max_wait)
6589a3415c2SJouni Malinen 		dut->default_timeout = max_wait;
6593a6b92a6SJouni Malinen 
6603a6b92a6SJouni Malinen 	snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
6613a6b92a6SJouni Malinen 	for (;;) {
6623a6b92a6SJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "DPP-RX", buf, sizeof(buf));
6639a3415c2SJouni Malinen 		if (res < 0) {
6649a3415c2SJouni Malinen 			dut->default_timeout = old_timeout;
6653a6b92a6SJouni Malinen 			return -1;
6669a3415c2SJouni Malinen 		}
6673a6b92a6SJouni Malinen 		if (strstr(buf, tmp) != NULL)
6683a6b92a6SJouni Malinen 			break;
6693a6b92a6SJouni Malinen 	}
6703a6b92a6SJouni Malinen 
6719a3415c2SJouni Malinen 	dut->default_timeout = old_timeout;
6729a3415c2SJouni Malinen 	return 0;
6739a3415c2SJouni Malinen }
6749a3415c2SJouni Malinen 
6759a3415c2SJouni Malinen 
6769a3415c2SJouni Malinen static int dpp_wait_rx_conf_req(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
6773e4344e7SJouni Malinen 				unsigned int max_wait)
6789a3415c2SJouni Malinen {
6799a3415c2SJouni Malinen 	char buf[200];
6809a3415c2SJouni Malinen 	int res;
6819a3415c2SJouni Malinen 	unsigned int old_timeout;
6829a3415c2SJouni Malinen 
6839a3415c2SJouni Malinen 	old_timeout = dut->default_timeout;
6849a3415c2SJouni Malinen 	if (max_wait > 0 && dut->default_timeout > max_wait)
6859a3415c2SJouni Malinen 		dut->default_timeout = max_wait;
6869a3415c2SJouni Malinen 
6879a3415c2SJouni Malinen 	for (;;) {
6889a3415c2SJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-REQ-RX",
6899a3415c2SJouni Malinen 					buf, sizeof(buf));
6909a3415c2SJouni Malinen 		if (res < 0) {
6919a3415c2SJouni Malinen 			dut->default_timeout = old_timeout;
6929a3415c2SJouni Malinen 			return -1;
6939a3415c2SJouni Malinen 		}
6949a3415c2SJouni Malinen 
6959a3415c2SJouni Malinen 		break;
6969a3415c2SJouni Malinen 	}
6979a3415c2SJouni Malinen 
6989a3415c2SJouni Malinen 	dut->default_timeout = old_timeout;
6993a6b92a6SJouni Malinen 	return 0;
7003a6b92a6SJouni Malinen }
7013a6b92a6SJouni Malinen 
7023a6b92a6SJouni Malinen 
703bc9e055cSSrinivas Dasari static int dpp_scan_peer_qrcode(struct sigma_dut *dut)
704d86e5828SJouni Malinen {
7051a38cc37SJouni Malinen #ifdef ANDROID
706bc9e055cSSrinivas Dasari 	char buf[100];
707bc9e055cSSrinivas Dasari 	char *buf2 = NULL;
708bc9e055cSSrinivas Dasari 	FILE *fp = NULL;
709bc9e055cSSrinivas Dasari 	uint32_t length;
710bc9e055cSSrinivas Dasari 	unsigned int count;
711bc9e055cSSrinivas Dasari 
712bc9e055cSSrinivas Dasari 	unlink(dpp_qrcode_file);
713bc9e055cSSrinivas Dasari 
714bc9e055cSSrinivas Dasari 	snprintf(buf, sizeof(buf),
71507458342SJouni Malinen 		 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeReadActivity");
716bc9e055cSSrinivas Dasari 	if (system(buf) != 0) {
71707458342SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
71807458342SJouni Malinen 				"Failed to launch QR Code scanner");
719d86e5828SJouni Malinen 		return -1;
720d86e5828SJouni Malinen 	}
721d86e5828SJouni Malinen 
722bc9e055cSSrinivas Dasari 	count = 0;
723bc9e055cSSrinivas Dasari 	while (!(fp = fopen(dpp_qrcode_file, "r"))) {
724bc9e055cSSrinivas Dasari 		if (count > dut->default_timeout) {
725bc9e055cSSrinivas Dasari 			sigma_dut_print(dut, DUT_MSG_ERROR,
726bc9e055cSSrinivas Dasari 					"Failed to open dpp_qrcode_file - QR Code scanning timed out");
727bc9e055cSSrinivas Dasari 			return -1;
728bc9e055cSSrinivas Dasari 		}
729bc9e055cSSrinivas Dasari 
730bc9e055cSSrinivas Dasari 		sleep(1);
731bc9e055cSSrinivas Dasari 		count++;
732bc9e055cSSrinivas Dasari 	}
733bc9e055cSSrinivas Dasari 
734bc9e055cSSrinivas Dasari 	if (fseek(fp, 0, SEEK_END) < 0 || (length = ftell(fp)) <= 0 ||
735bc9e055cSSrinivas Dasari 	    fseek(fp, 0, SEEK_SET) < 0) {
736bc9e055cSSrinivas Dasari 		sigma_dut_print(dut, DUT_MSG_ERROR,
737bc9e055cSSrinivas Dasari 				"Failed to get QR Code result file length");
738bc9e055cSSrinivas Dasari 		fclose(fp);
739bc9e055cSSrinivas Dasari 		return -1;
740bc9e055cSSrinivas Dasari 	}
741bc9e055cSSrinivas Dasari 
742bc9e055cSSrinivas Dasari 	buf2 = malloc(length + 1);
743bc9e055cSSrinivas Dasari 	if (!buf2) {
744bc9e055cSSrinivas Dasari 		fclose(fp);
745bc9e055cSSrinivas Dasari 		return -1;
746bc9e055cSSrinivas Dasari 	}
747bc9e055cSSrinivas Dasari 
748bc9e055cSSrinivas Dasari 	if (fread(buf2, 1, length, fp) != length) {
749bc9e055cSSrinivas Dasari 		fclose(fp);
750bc9e055cSSrinivas Dasari 		free(buf2);
751bc9e055cSSrinivas Dasari 		return -1;
752bc9e055cSSrinivas Dasari 	}
753bc9e055cSSrinivas Dasari 
754bc9e055cSSrinivas Dasari 	fclose(fp);
755bc9e055cSSrinivas Dasari 	buf2[length] = '\0';
756bc9e055cSSrinivas Dasari 
757bc9e055cSSrinivas Dasari 	free(dut->dpp_peer_uri);
758bc9e055cSSrinivas Dasari 	dut->dpp_peer_uri = strdup(buf2);
759bc9e055cSSrinivas Dasari 	free(buf2);
760bc9e055cSSrinivas Dasari 	return 0;
7611a38cc37SJouni Malinen #else /* ANDROID */
7621a38cc37SJouni Malinen 	pid_t pid;
7631a38cc37SJouni Malinen 	int pid_status;
7641a38cc37SJouni Malinen 	int pipe_out[2];
7651a38cc37SJouni Malinen 	char buf[4000], *pos;
7661a38cc37SJouni Malinen 	ssize_t len;
7671a38cc37SJouni Malinen 	int res = -1, ret;
7681a38cc37SJouni Malinen 	struct timeval tv;
7691a38cc37SJouni Malinen 	fd_set rfd;
7701a38cc37SJouni Malinen 
7711a38cc37SJouni Malinen 	if (pipe(pipe_out) != 0) {
7721a38cc37SJouni Malinen 		perror("pipe");
7731a38cc37SJouni Malinen 		return -1;
7741a38cc37SJouni Malinen 	}
7751a38cc37SJouni Malinen 
7761a38cc37SJouni Malinen 	pid = fork();
7771a38cc37SJouni Malinen 	if (pid < 0) {
7781a38cc37SJouni Malinen 		perror("fork");
7791a38cc37SJouni Malinen 		close(pipe_out[0]);
7801a38cc37SJouni Malinen 		close(pipe_out[1]);
7811a38cc37SJouni Malinen 		return -1;
7821a38cc37SJouni Malinen 	}
7831a38cc37SJouni Malinen 
7841a38cc37SJouni Malinen 	if (pid == 0) {
7851a38cc37SJouni Malinen 		char *argv[4] = { "zbarcam", "--raw", "--prescale=320x240",
7861a38cc37SJouni Malinen 				  NULL };
7871a38cc37SJouni Malinen 
7881a38cc37SJouni Malinen 		dup2(pipe_out[1], STDOUT_FILENO);
7891a38cc37SJouni Malinen 		close(pipe_out[0]);
7901a38cc37SJouni Malinen 		close(pipe_out[1]);
7911a38cc37SJouni Malinen 		execv("/usr/bin/zbarcam", argv);
7921a38cc37SJouni Malinen 		perror("execv");
7931a38cc37SJouni Malinen 		exit(0);
7941a38cc37SJouni Malinen 		return -1;
7951a38cc37SJouni Malinen 	}
7961a38cc37SJouni Malinen 
7971a38cc37SJouni Malinen 	close(pipe_out[1]);
7981a38cc37SJouni Malinen 
7991a38cc37SJouni Malinen 	FD_ZERO(&rfd);
8001a38cc37SJouni Malinen 	FD_SET(pipe_out[0], &rfd);
8011a38cc37SJouni Malinen 	tv.tv_sec = dut->default_timeout;
8021a38cc37SJouni Malinen 	tv.tv_usec = 0;
8031a38cc37SJouni Malinen 
8041a38cc37SJouni Malinen 	ret = select(pipe_out[0] + 1, &rfd, NULL, NULL, &tv);
8051a38cc37SJouni Malinen 	if (ret < 0) {
8061a38cc37SJouni Malinen 		perror("select");
8071a38cc37SJouni Malinen 		goto out;
8081a38cc37SJouni Malinen 	}
8091a38cc37SJouni Malinen 	if (ret == 0) {
8101a38cc37SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG,
8111a38cc37SJouni Malinen 				"QR Code scanning timed out");
8121a38cc37SJouni Malinen 		goto out;
8131a38cc37SJouni Malinen 	}
8141a38cc37SJouni Malinen 
8151a38cc37SJouni Malinen 	len = read(pipe_out[0], buf, sizeof(buf));
8161a38cc37SJouni Malinen 	if (len <= 0)
8171a38cc37SJouni Malinen 		goto out;
8181a38cc37SJouni Malinen 	if (len == sizeof(buf))
8191a38cc37SJouni Malinen 		len--;
8201a38cc37SJouni Malinen 	buf[len] = '\0';
8211a38cc37SJouni Malinen 	pos = strchr(buf, '\n');
8221a38cc37SJouni Malinen 	if (pos)
8231a38cc37SJouni Malinen 		*pos = '\0';
8241a38cc37SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "URI from QR scanner: %s", buf);
8251a38cc37SJouni Malinen 
8261a38cc37SJouni Malinen 	free(dut->dpp_peer_uri);
8271a38cc37SJouni Malinen 	dut->dpp_peer_uri = strdup(buf);
8281a38cc37SJouni Malinen 	res = 0;
8291a38cc37SJouni Malinen out:
8301a38cc37SJouni Malinen 	close(pipe_out[0]);
8311a38cc37SJouni Malinen 	kill(pid, SIGTERM);
8321a38cc37SJouni Malinen 	waitpid(pid, &pid_status, 0);
8331a38cc37SJouni Malinen 
8341a38cc37SJouni Malinen 	return res;
8351a38cc37SJouni Malinen #endif /* ANDROID */
836bc9e055cSSrinivas Dasari }
837bc9e055cSSrinivas Dasari 
838bc9e055cSSrinivas Dasari 
839bc9e055cSSrinivas Dasari static int dpp_display_own_qrcode(struct sigma_dut *dut)
840bc9e055cSSrinivas Dasari {
841bc9e055cSSrinivas Dasari 	char buf[200], resp[2000];
842016ae6c8SJouni Malinen 	const char *ifname = get_station_ifname(dut);
8431a38cc37SJouni Malinen #ifdef ANDROID
844bc9e055cSSrinivas Dasari 	FILE *fp;
8451a38cc37SJouni Malinen #else /* ANDROID */
8461a38cc37SJouni Malinen 	pid_t pid;
8471a38cc37SJouni Malinen 	int pid_status;
8481a38cc37SJouni Malinen #endif /* ANDROID */
849bc9e055cSSrinivas Dasari 
850bc9e055cSSrinivas Dasari 	snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d",
851bc9e055cSSrinivas Dasari 		 dut->dpp_local_bootstrap);
852bc9e055cSSrinivas Dasari 	if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 ||
853bc9e055cSSrinivas Dasari 	    strncmp(resp, "FAIL", 4) == 0)
854bc9e055cSSrinivas Dasari 		return -2;
8551a38cc37SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Own bootstrap URI: %s", resp);
856bc9e055cSSrinivas Dasari 
8571a38cc37SJouni Malinen #ifdef ANDROID
858bc9e055cSSrinivas Dasari 	unlink(dpp_qrcode_file);
859bc9e055cSSrinivas Dasari 
860bc9e055cSSrinivas Dasari 	fp = fopen(dpp_qrcode_file, "w");
861bc9e055cSSrinivas Dasari 	if (!fp) {
862bc9e055cSSrinivas Dasari 		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open file %s",
863bc9e055cSSrinivas Dasari 				dpp_qrcode_file);
864bc9e055cSSrinivas Dasari 		return -2;
865bc9e055cSSrinivas Dasari 	}
866bc9e055cSSrinivas Dasari 
867bc9e055cSSrinivas Dasari 	fwrite(resp, 1, strlen(resp), fp);
868bc9e055cSSrinivas Dasari 	fclose(fp);
869bc9e055cSSrinivas Dasari 
870bc9e055cSSrinivas Dasari 	snprintf(buf, sizeof(buf),
871bc9e055cSSrinivas Dasari 		 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeDisplayActivity");
872bc9e055cSSrinivas Dasari 	if (system(buf) != 0) {
873bc9e055cSSrinivas Dasari 		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to display QR Code");
874bc9e055cSSrinivas Dasari 		return -1;
875bc9e055cSSrinivas Dasari 	}
8761a38cc37SJouni Malinen #else /* ANDROID */
8771a38cc37SJouni Malinen 	pid = fork();
8781a38cc37SJouni Malinen 	if (pid < 0) {
8791a38cc37SJouni Malinen 		perror("fork");
8801a38cc37SJouni Malinen 		return -1;
8811a38cc37SJouni Malinen 	}
8821a38cc37SJouni Malinen 
8831a38cc37SJouni Malinen 	if (pid == 0) {
8841a38cc37SJouni Malinen 		char *argv[3] = { "qr", resp, NULL };
8851a38cc37SJouni Malinen 
8861a38cc37SJouni Malinen 		execv("/usr/bin/qr", argv);
8871a38cc37SJouni Malinen 		perror("execv");
8881a38cc37SJouni Malinen 		exit(0);
8891a38cc37SJouni Malinen 		return -1;
8901a38cc37SJouni Malinen 	}
8911a38cc37SJouni Malinen 
8921a38cc37SJouni Malinen 	waitpid(pid, &pid_status, 0);
8931a38cc37SJouni Malinen #endif /* ANDROID */
894bc9e055cSSrinivas Dasari 
895bc9e055cSSrinivas Dasari 	return 0;
896bc9e055cSSrinivas Dasari }
897bc9e055cSSrinivas Dasari 
898d86e5828SJouni Malinen 
8998d88d822SSrinivas Dasari static int dpp_process_auth_response(struct sigma_dut *dut,
9008d88d822SSrinivas Dasari 				     struct sigma_conn *conn,
9018d88d822SSrinivas Dasari 				     struct wpa_ctrl *ctrl,
9028d88d822SSrinivas Dasari 				     const char **auth_events,
9038d88d822SSrinivas Dasari 				     const char *action_type,
9048d88d822SSrinivas Dasari 				     int check_mutual, char *buf, size_t buflen)
9058d88d822SSrinivas Dasari {
9068d88d822SSrinivas Dasari 	int res;
9078d88d822SSrinivas Dasari 
9088d88d822SSrinivas Dasari 	res = get_wpa_cli_events(dut, ctrl, auth_events, buf, buflen);
9098d88d822SSrinivas Dasari 	if (res < 0) {
9108d88d822SSrinivas Dasari 		send_resp(dut, conn, SIGMA_COMPLETE,
9118d88d822SSrinivas Dasari 			  "BootstrapResult,OK,AuthResult,Timeout");
9128d88d822SSrinivas Dasari 		return res;
9138d88d822SSrinivas Dasari 	}
9148d88d822SSrinivas Dasari 	sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
9158d88d822SSrinivas Dasari 
9168d88d822SSrinivas Dasari 	if (strstr(buf, "DPP-RESPONSE-PENDING")) {
9178d88d822SSrinivas Dasari 		/* Display own QR code in manual mode */
9188d88d822SSrinivas Dasari 		if (action_type && strcasecmp(action_type, "ManualDPP") == 0 &&
9198d88d822SSrinivas Dasari 		    dpp_display_own_qrcode(dut) < 0) {
9208d88d822SSrinivas Dasari 			send_resp(dut, conn, SIGMA_ERROR,
9218d88d822SSrinivas Dasari 				  "errorCode,Failed to display own QR code");
9228d88d822SSrinivas Dasari 			return -1;
9238d88d822SSrinivas Dasari 		}
9248d88d822SSrinivas Dasari 
9258d88d822SSrinivas Dasari 		/* Wait for the actual result after the peer has scanned the
9268d88d822SSrinivas Dasari 		 * QR Code. */
9278d88d822SSrinivas Dasari 		res = get_wpa_cli_events(dut, ctrl, auth_events,
9288d88d822SSrinivas Dasari 					 buf, buflen);
9298d88d822SSrinivas Dasari 		if (res < 0) {
9308d88d822SSrinivas Dasari 			send_resp(dut, conn, SIGMA_COMPLETE,
9318d88d822SSrinivas Dasari 				  "BootstrapResult,OK,AuthResult,Timeout");
9328d88d822SSrinivas Dasari 			return res;
9338d88d822SSrinivas Dasari 		}
9348d88d822SSrinivas Dasari 
9358d88d822SSrinivas Dasari 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
936ed629d51SJouni Malinen 	} else if (strstr(buf, "DPP-AUTH-INIT-FAILED")) {
937ed629d51SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
938ed629d51SJouni Malinen 			  "errorCode,Peer did not reply to DPP Authentication Request");
939ed629d51SJouni Malinen 		return -1;
9408d88d822SSrinivas Dasari 	}
9418d88d822SSrinivas Dasari 
9428d88d822SSrinivas Dasari 	if (check_mutual) {
9438d88d822SSrinivas Dasari 		if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
9448d88d822SSrinivas Dasari 			send_resp(dut, conn, SIGMA_COMPLETE,
9458d88d822SSrinivas Dasari 				  "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
9468d88d822SSrinivas Dasari 			return -1;
9478d88d822SSrinivas Dasari 		}
9488d88d822SSrinivas Dasari 
9498d88d822SSrinivas Dasari 		if (!strstr(buf, "DPP-AUTH-DIRECTION")) {
9508d88d822SSrinivas Dasari 			send_resp(dut, conn, SIGMA_ERROR,
9518d88d822SSrinivas Dasari 				  "errorCode,No event for auth direction seen");
9528d88d822SSrinivas Dasari 			return -1;
9538d88d822SSrinivas Dasari 		}
9548d88d822SSrinivas Dasari 
9558d88d822SSrinivas Dasari 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth direction: %s",
9568d88d822SSrinivas Dasari 				buf);
9578d88d822SSrinivas Dasari 		if (strstr(buf, "mutual=1") == NULL) {
9588d88d822SSrinivas Dasari 			send_resp(dut, conn, SIGMA_ERROR,
9598d88d822SSrinivas Dasari 				  "errorCode,Peer did not use mutual authentication");
9608d88d822SSrinivas Dasari 			return -1;
9618d88d822SSrinivas Dasari 		}
9628d88d822SSrinivas Dasari 	}
9638d88d822SSrinivas Dasari 
9648d88d822SSrinivas Dasari 	return 0;
9658d88d822SSrinivas Dasari }
9668d88d822SSrinivas Dasari 
9678d88d822SSrinivas Dasari 
96889cf6d64SJouni Malinen static enum sigma_cmd_result dpp_automatic_dpp(struct sigma_dut *dut,
969d86e5828SJouni Malinen 					       struct sigma_conn *conn,
970d86e5828SJouni Malinen 					       struct sigma_cmd *cmd)
971d86e5828SJouni Malinen {
972d86e5828SJouni Malinen 	const char *bs = get_param(cmd, "DPPBS");
973ed629d51SJouni Malinen 	const char *type = get_param(cmd, "DPPActionType");
974d86e5828SJouni Malinen 	const char *auth_role = get_param(cmd, "DPPAuthRole");
975d86e5828SJouni Malinen 	const char *prov_role = get_param(cmd, "DPPProvisioningRole");
976d86e5828SJouni Malinen 	const char *pkex_code = get_param(cmd, "DPPPKEXCode");
977d86e5828SJouni Malinen 	const char *pkex_code_id = get_param(cmd, "DPPPKEXCodeIdentifier");
978d86e5828SJouni Malinen 	const char *wait_conn = get_param(cmd, "DPPWaitForConnect");
979d86e5828SJouni Malinen 	const char *self_conf = get_param(cmd, "DPPSelfConfigure");
980772299f1SJouni Malinen 	const char *step = get_param(cmd, "DPPStep");
981772299f1SJouni Malinen 	const char *frametype = get_param(cmd, "DPPFrameType");
982772299f1SJouni Malinen 	const char *attr = get_param(cmd, "DPPIEAttribute");
983bc9e055cSSrinivas Dasari 	const char *action_type = get_param(cmd, "DPPActionType");
984785afb44SJouni Malinen 	const char *tcp = get_param(cmd, "DPPOverTCP");
985f37fda0fSJouni Malinen 	const char *nfc_handover = get_param(cmd, "DPPNFCHandover");
986d86e5828SJouni Malinen 	const char *role;
987a28608abSJouni Malinen 	const char *netrole = NULL;
988d86e5828SJouni Malinen 	const char *val;
989d86e5828SJouni Malinen 	const char *conf_role;
990d86e5828SJouni Malinen 	int conf_index = -1;
9913d16ccbdSJouni Malinen 	char buf[2000], *pos, *pos2;
992dd85cff0SJouni Malinen 	char buf2[200];
993d86e5828SJouni Malinen 	char conf_ssid[100];
994d86e5828SJouni Malinen 	char conf_pass[100];
995d86e5828SJouni Malinen 	char pkex_identifier[200];
996d86e5828SJouni Malinen 	struct wpa_ctrl *ctrl;
997d86e5828SJouni Malinen 	int res;
998d86e5828SJouni Malinen 	unsigned int old_timeout;
999d86e5828SJouni Malinen 	int own_pkex_id = -1;
1000016ae6c8SJouni Malinen 	const char *ifname = get_station_ifname(dut);
1001d86e5828SJouni Malinen 	const char *auth_events[] = {
1002d86e5828SJouni Malinen 		"DPP-AUTH-SUCCESS",
1003ed629d51SJouni Malinen 		"DPP-AUTH-INIT-FAILED",
1004d86e5828SJouni Malinen 		"DPP-NOT-COMPATIBLE",
1005d86e5828SJouni Malinen 		"DPP-RESPONSE-PENDING",
1006d86e5828SJouni Malinen 		"DPP-SCAN-PEER-QR-CODE",
1007bc9e055cSSrinivas Dasari 		"DPP-AUTH-DIRECTION",
1008d86e5828SJouni Malinen 		NULL
1009d86e5828SJouni Malinen 	};
1010d86e5828SJouni Malinen 	const char *conf_events[] = {
1011d86e5828SJouni Malinen 		"DPP-CONF-RECEIVED",
1012d86e5828SJouni Malinen 		"DPP-CONF-SENT",
1013d86e5828SJouni Malinen 		"DPP-CONF-FAILED",
1014d86e5828SJouni Malinen 		NULL
1015d86e5828SJouni Malinen 	};
1016d86e5828SJouni Malinen 	const char *conn_events[] = {
1017d86e5828SJouni Malinen 		"PMKSA-CACHE-ADDED",
1018d86e5828SJouni Malinen 		"CTRL-EVENT-CONNECTED",
1019d86e5828SJouni Malinen 		NULL
1020d86e5828SJouni Malinen 	};
102111ab72c2SPurushottam Kushwaha 	const char *group_id_str = NULL;
102211ab72c2SPurushottam Kushwaha 	char group_id[100];
1023dd85cff0SJouni Malinen 	char conf2[300];
1024772299f1SJouni Malinen 	const char *result;
1025d1e22f76SJouni Malinen 	int check_mutual = 0;
1026e89cdbf5SJouni Malinen 	int enrollee_ap;
1027a28608abSJouni Malinen 	int enrollee_configurator;
1028f2fa0d00SJouni Malinen 	int force_gas_fragm = 0;
102985a5a2e5SJouni Malinen 	int not_dpp_akm = 0;
10307a7ecf73SJouni Malinen 	int akm_use_selector = 0;
10319be22eddSJouni Malinen 	int conn_status;
1032c240fe5aSJouni Malinen 	int chirp = 0;
1033ed629d51SJouni Malinen 	int manual = strcasecmp(type, "ManualDPP") == 0;
1034ee7975a7SJouni Malinen 	time_t start, now;
1035ee7975a7SJouni Malinen 
1036ee7975a7SJouni Malinen 	time(&start);
1037d86e5828SJouni Malinen 
1038d86e5828SJouni Malinen 	if (!wait_conn)
1039d86e5828SJouni Malinen 		wait_conn = "no";
1040d86e5828SJouni Malinen 	if (!self_conf)
1041d86e5828SJouni Malinen 		self_conf = "no";
1042d86e5828SJouni Malinen 
1043d86e5828SJouni Malinen 	if (!prov_role) {
1044d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
1045d86e5828SJouni Malinen 			  "errorCode,Missing DPPProvisioningRole");
104689cf6d64SJouni Malinen 		return STATUS_SENT_ERROR;
1047d86e5828SJouni Malinen 	}
1048d86e5828SJouni Malinen 
1049e89cdbf5SJouni Malinen 	val = get_param(cmd, "DPPConfEnrolleeRole");
1050a28608abSJouni Malinen 	if (val) {
1051e89cdbf5SJouni Malinen 		enrollee_ap = strcasecmp(val, "AP") == 0;
1052a28608abSJouni Malinen 		enrollee_configurator = strcasecmp(val, "Configurator") == 0;
1053a28608abSJouni Malinen 	} else {
1054e89cdbf5SJouni Malinen 		enrollee_ap = sigma_dut_is_ap(dut);
1055a28608abSJouni Malinen 		enrollee_configurator = 0;
1056a28608abSJouni Malinen 	}
1057a28608abSJouni Malinen 
1058a28608abSJouni Malinen 	val = get_param(cmd, "DPPNetworkRole");
1059a28608abSJouni Malinen 	if (val) {
1060a28608abSJouni Malinen 		if (strcasecmp(val, "AP") == 0) {
1061a28608abSJouni Malinen 			netrole = "ap";
1062a28608abSJouni Malinen 		} else if (strcasecmp(val, "STA") == 0) {
1063a28608abSJouni Malinen 			netrole = "sta";
1064a28608abSJouni Malinen 		} else if (strcasecmp(val, "Configurator") == 0) {
1065a28608abSJouni Malinen 			netrole = "configurator";
1066a28608abSJouni Malinen 		} else {
1067a28608abSJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1068a28608abSJouni Malinen 				  "errorCode,Unsupported DPPNetworkRole value");
106989cf6d64SJouni Malinen 			return STATUS_SENT_ERROR;
1070a28608abSJouni Malinen 		}
1071a28608abSJouni Malinen 	}
1072e89cdbf5SJouni Malinen 
1073c240fe5aSJouni Malinen 	val = get_param(cmd, "DPPChirp");
1074c240fe5aSJouni Malinen 	if (val)
1075c240fe5aSJouni Malinen 		chirp = get_enable_disable(val);
1076c240fe5aSJouni Malinen 
10773a6b92a6SJouni Malinen 	if ((step || frametype) && (!step || !frametype)) {
1078772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
1079772299f1SJouni Malinen 			  "errorCode,Invalid DPPStep,DPPFrameType,DPPIEAttribute combination");
108089cf6d64SJouni Malinen 		return STATUS_SENT_ERROR;
1081772299f1SJouni Malinen 	}
1082772299f1SJouni Malinen 
108390776b1fSJouni Malinen 	val = get_param(cmd, "MUDURL");
108490776b1fSJouni Malinen 	if (val) {
108590776b1fSJouni Malinen 		snprintf(buf, sizeof(buf), "SET dpp_mud_url %s", val);
108690776b1fSJouni Malinen 		if (wpa_command(ifname, buf) < 0) {
108790776b1fSJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
108890776b1fSJouni Malinen 				  "errorCode,Failed to set MUD URL");
108989cf6d64SJouni Malinen 			return STATUS_SENT_ERROR;
109090776b1fSJouni Malinen 		}
109190776b1fSJouni Malinen 	}
109290776b1fSJouni Malinen 
1093d86e5828SJouni Malinen 	if (sigma_dut_is_ap(dut)) {
1094d86e5828SJouni Malinen 		if (!dut->hostapd_ifname) {
1095d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_ERROR,
1096d86e5828SJouni Malinen 					"hostapd ifname not specified (-j)");
109789cf6d64SJouni Malinen 			return ERROR_SEND_STATUS;
1098d86e5828SJouni Malinen 		}
1099d86e5828SJouni Malinen 		ifname = dut->hostapd_ifname;
1100d86e5828SJouni Malinen 
1101d86e5828SJouni Malinen 		if (dpp_hostapd_run(dut) < 0) {
1102d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1103d86e5828SJouni Malinen 				  "errorCode,Failed to start hostapd");
110489cf6d64SJouni Malinen 			return STATUS_SENT_ERROR;
1105d86e5828SJouni Malinen 		}
1106d86e5828SJouni Malinen 	}
1107d86e5828SJouni Malinen 
110867acb0cfSJouni Malinen 	if (strcasecmp(prov_role, "Configurator") == 0 ||
110967acb0cfSJouni Malinen 	    strcasecmp(prov_role, "Both") == 0) {
1110d86e5828SJouni Malinen 		if (dut->dpp_conf_id < 0) {
1111d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
1112d86e5828SJouni Malinen 				 "DPP_CONFIGURATOR_ADD curve=%s",
1113d86e5828SJouni Malinen 				 dpp_get_curve(cmd, "DPPSigningKeyECC"));
1114d86e5828SJouni Malinen 			if (wpa_command_resp(ifname, buf,
1115d86e5828SJouni Malinen 					     buf, sizeof(buf)) < 0) {
1116d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1117d86e5828SJouni Malinen 					  "errorCode,Failed to set up configurator");
111889cf6d64SJouni Malinen 				return STATUS_SENT_ERROR;
1119d86e5828SJouni Malinen 			}
1120d86e5828SJouni Malinen 			dut->dpp_conf_id = atoi(buf);
1121d86e5828SJouni Malinen 		}
112267acb0cfSJouni Malinen 		if (strcasecmp(prov_role, "Configurator") == 0)
1123d86e5828SJouni Malinen 			role = "configurator";
112467acb0cfSJouni Malinen 		else
112567acb0cfSJouni Malinen 			role = "either";
1126d86e5828SJouni Malinen 	} else if (strcasecmp(prov_role, "Enrollee") == 0) {
1127d86e5828SJouni Malinen 		role = "enrollee";
1128d86e5828SJouni Malinen 	} else {
1129d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
1130d86e5828SJouni Malinen 			  "errorCode,Unknown DPPProvisioningRole");
113189cf6d64SJouni Malinen 		return STATUS_SENT_ERROR;
1132d86e5828SJouni Malinen 	}
1133d86e5828SJouni Malinen 
1134d86e5828SJouni Malinen 	pkex_identifier[0] = '\0';
1135d86e5828SJouni Malinen 	if (strcasecmp(bs, "PKEX") == 0) {
11364f47a272SJouni Malinen 		if (sigma_dut_is_ap(dut) && dut->ap_channel != 6) {
11374f47a272SJouni Malinen 			/* For now, have to make operating channel match DPP
11384f47a272SJouni Malinen 			 * listen channel. This should be removed once hostapd
11394f47a272SJouni Malinen 			 * has support for DPP listen on non-operating channel.
11404f47a272SJouni Malinen 			 */
11414f47a272SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
11424f47a272SJouni Malinen 					"Update hostapd operating channel to match listen needs");
11434f47a272SJouni Malinen 			dut->ap_channel = 6;
1144b4de1962Spriyadharshini gowthaman 
1145016ae6c8SJouni Malinen 			if (get_driver_type(dut) == DRIVER_OPENWRT) {
1146b4de1962Spriyadharshini gowthaman 				snprintf(buf, sizeof(buf),
1147b4de1962Spriyadharshini gowthaman 					 "iwconfig %s channel %d",
1148b4de1962Spriyadharshini gowthaman 					 dut->hostapd_ifname, dut->ap_channel);
1149b4de1962Spriyadharshini gowthaman 				run_system(dut, buf);
1150b4de1962Spriyadharshini gowthaman 			}
1151b4de1962Spriyadharshini gowthaman 
11524f47a272SJouni Malinen 			if (wpa_command(ifname, "SET channel 6") < 0 ||
11534f47a272SJouni Malinen 			    wpa_command(ifname, "DISABLE") < 0 ||
11544f47a272SJouni Malinen 			    wpa_command(ifname, "ENABLE") < 0) {
11554f47a272SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
11564f47a272SJouni Malinen 					  "errorCode,Failed to update channel");
115789cf6d64SJouni Malinen 				return STATUS_SENT_ERROR;
11584f47a272SJouni Malinen 			}
11594f47a272SJouni Malinen 		}
11604f47a272SJouni Malinen 
1161d86e5828SJouni Malinen 		if (!pkex_code) {
1162d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1163d86e5828SJouni Malinen 				  "errorCode,Missing DPPPKEXCode");
116489cf6d64SJouni Malinen 			return STATUS_SENT_ERROR;
1165d86e5828SJouni Malinen 		}
1166d86e5828SJouni Malinen 
1167d86e5828SJouni Malinen 		if (pkex_code_id)
1168d86e5828SJouni Malinen 			snprintf(pkex_identifier, sizeof(pkex_identifier),
1169d86e5828SJouni Malinen 				 "identifier=%s ", pkex_code_id);
1170d86e5828SJouni Malinen 
1171d86e5828SJouni Malinen 		snprintf(buf, sizeof(buf),
1172d86e5828SJouni Malinen 			 "DPP_BOOTSTRAP_GEN type=pkex curve=%s",
1173d86e5828SJouni Malinen 			 dpp_get_curve(cmd, "DPPCryptoIdentifier"));
1174d86e5828SJouni Malinen 		if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) {
1175d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1176d86e5828SJouni Malinen 				  "errorCode,Failed to set up PKEX");
117789cf6d64SJouni Malinen 			return STATUS_SENT_ERROR;
1178d86e5828SJouni Malinen 		}
1179d86e5828SJouni Malinen 		own_pkex_id = atoi(buf);
1180d86e5828SJouni Malinen 	}
1181d86e5828SJouni Malinen 
1182d86e5828SJouni Malinen 	ctrl = open_wpa_mon(ifname);
1183d86e5828SJouni Malinen 	if (!ctrl) {
1184d86e5828SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
1185d86e5828SJouni Malinen 				"Failed to open wpa_supplicant monitor connection");
118689cf6d64SJouni Malinen 		return ERROR_SEND_STATUS;
1187d86e5828SJouni Malinen 	}
1188d86e5828SJouni Malinen 
1189d86e5828SJouni Malinen 	old_timeout = dut->default_timeout;
1190d86e5828SJouni Malinen 	val = get_param(cmd, "DPPTimeout");
1191d86e5828SJouni Malinen 	if (val && atoi(val) > 0) {
1192d86e5828SJouni Malinen 		dut->default_timeout = atoi(val);
1193d86e5828SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u",
1194d86e5828SJouni Malinen 				dut->default_timeout);
1195d86e5828SJouni Malinen 	}
1196d86e5828SJouni Malinen 
11979be22eddSJouni Malinen 	val = get_param(cmd, "DPPStatusQuery");
11989be22eddSJouni Malinen 	conn_status = val && strcasecmp(val, "Yes") == 0;
11999be22eddSJouni Malinen 
1200d86e5828SJouni Malinen 	conf_ssid[0] = '\0';
1201d86e5828SJouni Malinen 	conf_pass[0] = '\0';
120211ab72c2SPurushottam Kushwaha 	group_id[0] = '\0';
1203dd85cff0SJouni Malinen 	conf2[0] = '\0';
120405142208SJouni Malinen 	if (!enrollee_configurator) {
1205d86e5828SJouni Malinen 		val = get_param(cmd, "DPPConfIndex");
1206d86e5828SJouni Malinen 		if (val)
1207d86e5828SJouni Malinen 			conf_index = atoi(val);
120805142208SJouni Malinen 	}
1209d86e5828SJouni Malinen 	switch (conf_index) {
1210258cc26aSJouni Malinen 	case -1:
1211a28608abSJouni Malinen 		if (enrollee_configurator)
1212a28608abSJouni Malinen 			conf_role = "configurator";
1213a28608abSJouni Malinen 		else
1214258cc26aSJouni Malinen 			conf_role = NULL;
1215258cc26aSJouni Malinen 		break;
1216d86e5828SJouni Malinen 	case 1:
1217d86e5828SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
12183aa72861SJouni Malinen 		res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
12193aa72861SJouni Malinen 		if (res < 0 || res >= sizeof(conf_ssid))
12203aa72861SJouni Malinen 			goto err;
1221e89cdbf5SJouni Malinen 		if (enrollee_ap) {
1222d86e5828SJouni Malinen 			conf_role = "ap-dpp";
12233d291f70SJouni Malinen 		} else {
1224d86e5828SJouni Malinen 			conf_role = "sta-dpp";
12253d291f70SJouni Malinen 		}
122611ab72c2SPurushottam Kushwaha 		group_id_str = "DPPGROUP_DPP_INFRA";
1227d86e5828SJouni Malinen 		break;
1228d86e5828SJouni Malinen 	case 2:
1229d86e5828SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
12303aa72861SJouni Malinen 		res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
12313aa72861SJouni Malinen 		if (res < 0 || res >= sizeof(conf_ssid))
12323aa72861SJouni Malinen 			goto err;
12338f81cdfaSJouni Malinen 		snprintf(conf_pass, sizeof(conf_pass),
12348f81cdfaSJouni Malinen 			 "psk=10506e102ad1e7f95112f6b127675bb8344dacacea60403f3fa4055aec85b0fc");
1235e89cdbf5SJouni Malinen 		if (enrollee_ap)
1236d86e5828SJouni Malinen 			conf_role = "ap-psk";
1237d86e5828SJouni Malinen 		else
1238d86e5828SJouni Malinen 			conf_role = "sta-psk";
1239d86e5828SJouni Malinen 		break;
1240d86e5828SJouni Malinen 	case 3:
1241d86e5828SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
12423aa72861SJouni Malinen 		res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
12433aa72861SJouni Malinen 		if (res < 0 || res >= sizeof(conf_ssid))
12443aa72861SJouni Malinen 			goto err;
1245d86e5828SJouni Malinen 		ascii2hexstr("ThisIsDppPassphrase", buf);
12463aa72861SJouni Malinen 		res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
12473aa72861SJouni Malinen 		if (res < 0 || res >= sizeof(conf_pass))
12483aa72861SJouni Malinen 			goto err;
1249e89cdbf5SJouni Malinen 		if (enrollee_ap)
1250d86e5828SJouni Malinen 			conf_role = "ap-psk";
1251d86e5828SJouni Malinen 		else
1252d86e5828SJouni Malinen 			conf_role = "sta-psk";
1253d86e5828SJouni Malinen 		break;
12543d291f70SJouni Malinen 	case 4:
12553d291f70SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
12563aa72861SJouni Malinen 		res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
12573aa72861SJouni Malinen 		if (res < 0 || res >= sizeof(conf_ssid))
12583aa72861SJouni Malinen 			goto err;
1259e89cdbf5SJouni Malinen 		if (enrollee_ap) {
12603d291f70SJouni Malinen 			conf_role = "ap-dpp";
12613d291f70SJouni Malinen 		} else {
12623d291f70SJouni Malinen 			conf_role = "sta-dpp";
12633d291f70SJouni Malinen 		}
126411ab72c2SPurushottam Kushwaha 		group_id_str = "DPPGROUP_DPP_INFRA2";
12653d291f70SJouni Malinen 		break;
12667d031c77SJouni Malinen 	case 5:
12677d031c77SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
12683aa72861SJouni Malinen 		res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
12693aa72861SJouni Malinen 		if (res < 0 || res >= sizeof(conf_ssid))
12703aa72861SJouni Malinen 			goto err;
12717d031c77SJouni Malinen 		ascii2hexstr("ThisIsDppPassphrase", buf);
12723aa72861SJouni Malinen 		res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
12733aa72861SJouni Malinen 		if (res < 0 || res >= sizeof(conf_pass))
12743aa72861SJouni Malinen 			goto err;
12757d031c77SJouni Malinen 		if (enrollee_ap)
12767d031c77SJouni Malinen 			conf_role = "ap-sae";
12777d031c77SJouni Malinen 		else
12787d031c77SJouni Malinen 			conf_role = "sta-sae";
12797d031c77SJouni Malinen 		break;
12807d031c77SJouni Malinen 	case 6:
12817d031c77SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
12823aa72861SJouni Malinen 		res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
12833aa72861SJouni Malinen 		if (res < 0 || res >= sizeof(conf_ssid))
12843aa72861SJouni Malinen 			goto err;
12857d031c77SJouni Malinen 		ascii2hexstr("ThisIsDppPassphrase", buf);
12863aa72861SJouni Malinen 		res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
12873aa72861SJouni Malinen 		if (res < 0 || res >= sizeof(conf_pass))
12883aa72861SJouni Malinen 			goto err;
12897d031c77SJouni Malinen 		if (enrollee_ap)
12907d031c77SJouni Malinen 			conf_role = "ap-psk-sae";
12917d031c77SJouni Malinen 		else
12927d031c77SJouni Malinen 			conf_role = "sta-psk-sae";
12937d031c77SJouni Malinen 		break;
1294f2fa0d00SJouni Malinen 	case 7:
1295f2fa0d00SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
12963aa72861SJouni Malinen 		res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
12973aa72861SJouni Malinen 		if (res < 0 || res >= sizeof(conf_ssid))
12983aa72861SJouni Malinen 			goto err;
1299f2fa0d00SJouni Malinen 		if (enrollee_ap) {
1300f2fa0d00SJouni Malinen 			conf_role = "ap-dpp";
1301f2fa0d00SJouni Malinen 		} else {
1302f2fa0d00SJouni Malinen 			conf_role = "sta-dpp";
1303f2fa0d00SJouni Malinen 		}
130411ab72c2SPurushottam Kushwaha 		group_id_str = "DPPGROUP_DPP_INFRA";
1305f2fa0d00SJouni Malinen 		force_gas_fragm = 1;
1306f2fa0d00SJouni Malinen 		break;
13070e3941c5SJouni Malinen 	case 8:
13087a7ecf73SJouni Malinen 	case 9:
13090e3941c5SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
13100e3941c5SJouni Malinen 		res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
13110e3941c5SJouni Malinen 		if (res < 0 || res >= sizeof(conf_ssid))
13120e3941c5SJouni Malinen 			goto err;
13130e3941c5SJouni Malinen 		ascii2hexstr("This_is_legacy_password", buf);
13140e3941c5SJouni Malinen 		res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
13150e3941c5SJouni Malinen 		if (res < 0 || res >= sizeof(conf_pass))
13160e3941c5SJouni Malinen 			goto err;
13170e3941c5SJouni Malinen 		if (enrollee_ap) {
13180e3941c5SJouni Malinen 			conf_role = "ap-dpp+psk+sae";
13190e3941c5SJouni Malinen 		} else {
13200e3941c5SJouni Malinen 			conf_role = "sta-dpp+psk+sae";
13210e3941c5SJouni Malinen 		}
13220e3941c5SJouni Malinen 		group_id_str = "DPPGROUP_DPP_INFRA1";
13237a7ecf73SJouni Malinen 		if (conf_index == 9)
13247a7ecf73SJouni Malinen 			akm_use_selector = 1;
13250e3941c5SJouni Malinen 		break;
1326dd85cff0SJouni Malinen 	case 10:
1327dd85cff0SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
1328dd85cff0SJouni Malinen 		res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1329dd85cff0SJouni Malinen 		if (res < 0 || res >= sizeof(conf_ssid))
1330dd85cff0SJouni Malinen 			goto err;
1331dd85cff0SJouni Malinen 		if (enrollee_ap)
1332dd85cff0SJouni Malinen 			conf_role = "ap-dpp";
1333dd85cff0SJouni Malinen 		else
1334dd85cff0SJouni Malinen 			conf_role = "sta-dpp";
1335dd85cff0SJouni Malinen 		group_id_str = "DPPGROUP_DPP_INFRA1";
1336dd85cff0SJouni Malinen 		ascii2hexstr("DPPNET02", buf);
1337dd85cff0SJouni Malinen 		ascii2hexstr("This_is_legacy_password", buf2);
1338dd85cff0SJouni Malinen 		res = snprintf(conf2, sizeof(conf2),
1339dd85cff0SJouni Malinen 			       " @CONF-OBJ-SEP@ conf=%s-dpp+psk+sae ssid=%s pass=%s group_id=DPPGROUP_DPP_INFRA2",
1340dd85cff0SJouni Malinen 			       enrollee_ap ? "ap" : "sta", buf, buf2);
13417ee04b93SJouni Malinen 		if (res < 0 || res >= sizeof(conf2))
13427ee04b93SJouni Malinen 			goto err;
1343dd85cff0SJouni Malinen 		break;
1344f7490768SJouni Malinen 	default:
1345f7490768SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
1346f7490768SJouni Malinen 			  "errorCode,Unsupported DPPConfIndex");
1347f7490768SJouni Malinen 		goto out;
1348d86e5828SJouni Malinen 	}
1349d86e5828SJouni Malinen 
135011ab72c2SPurushottam Kushwaha 	if (group_id_str)
135111ab72c2SPurushottam Kushwaha 		snprintf(group_id, sizeof(group_id), " group_id=%s",
135211ab72c2SPurushottam Kushwaha 			 group_id_str);
13533d291f70SJouni Malinen 
13542b2230fbSJouni Malinen 	if (force_gas_fragm) {
13552b2230fbSJouni Malinen 		char spaces[1500];
13562b2230fbSJouni Malinen 
13572b2230fbSJouni Malinen 		memset(spaces, ' ', sizeof(spaces));
13582b2230fbSJouni Malinen 		spaces[sizeof(spaces) - 1] = '\0';
13592b2230fbSJouni Malinen 
13602b2230fbSJouni Malinen 		snprintf(buf, sizeof(buf),
13612b2230fbSJouni Malinen 			 "SET dpp_discovery_override {\"ssid\":\"DPPNET01\"}%s",
13622b2230fbSJouni Malinen 			 spaces);
13632b2230fbSJouni Malinen 		if (wpa_command(ifname, buf) < 0) {
13642b2230fbSJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
13652b2230fbSJouni Malinen 				  "errorCode,Failed to set discovery override");
13662b2230fbSJouni Malinen 			goto out;
13672b2230fbSJouni Malinen 		}
13682b2230fbSJouni Malinen 	}
13692b2230fbSJouni Malinen 
1370772299f1SJouni Malinen 	if (step) {
1371772299f1SJouni Malinen 		int test;
1372772299f1SJouni Malinen 
1373772299f1SJouni Malinen 		test = dpp_get_test(step, frametype, attr);
1374772299f1SJouni Malinen 		if (test <= 0) {
1375772299f1SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1376772299f1SJouni Malinen 				  "errorCode,Unsupported DPPStep/DPPFrameType/DPPIEAttribute");
1377772299f1SJouni Malinen 			goto out;
1378772299f1SJouni Malinen 		}
1379772299f1SJouni Malinen 
1380772299f1SJouni Malinen 		snprintf(buf, sizeof(buf), "SET dpp_test %d", test);
1381772299f1SJouni Malinen 		if (wpa_command(ifname, buf) < 0) {
1382772299f1SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1383772299f1SJouni Malinen 				  "errorCode,Failed to set dpp_test");
1384772299f1SJouni Malinen 			goto out;
1385772299f1SJouni Malinen 		}
1386772299f1SJouni Malinen 	} else {
1387772299f1SJouni Malinen 		wpa_command(ifname, "SET dpp_test 0");
1388772299f1SJouni Malinen 	}
1389772299f1SJouni Malinen 
1390fbb268d7SJouni Malinen 	if (strcasecmp(self_conf, "Yes") == 0) {
1391fbb268d7SJouni Malinen 		if (strcasecmp(prov_role, "Configurator") != 0) {
1392fbb268d7SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1393fbb268d7SJouni Malinen 				  "errorCode,Invalid DPPSelfConfigure use - only allowed for Configurator role");
1394fbb268d7SJouni Malinen 			goto out;
1395fbb268d7SJouni Malinen 		}
1396fbb268d7SJouni Malinen 		if (!conf_role) {
1397fbb268d7SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1398fbb268d7SJouni Malinen 				  "errorCode,Missing DPPConfIndex");
1399fbb268d7SJouni Malinen 			goto out;
1400fbb268d7SJouni Malinen 		}
1401fbb268d7SJouni Malinen 
1402fbb268d7SJouni Malinen 		snprintf(buf, sizeof(buf),
1403fbb268d7SJouni Malinen 			 "DPP_CONFIGURATOR_SIGN  conf=%s %s %s configurator=%d",
1404fbb268d7SJouni Malinen 			 conf_role, conf_ssid, conf_pass, dut->dpp_conf_id);
1405fbb268d7SJouni Malinen 		if (wpa_command(ifname, buf) < 0) {
1406fbb268d7SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1407fbb268d7SJouni Malinen 				  "errorCode,Failed to initiate DPP self-configuration");
1408fbb268d7SJouni Malinen 			goto out;
1409fbb268d7SJouni Malinen 		}
1410174db64fSJouni Malinen 		if (sigma_dut_is_ap(dut))
1411174db64fSJouni Malinen 			goto update_ap;
1412fbb268d7SJouni Malinen 		goto wait_connect;
1413ed629d51SJouni Malinen 	} else if (manual && strcasecmp(bs, "NFC") == 0) {
1414ed629d51SJouni Malinen 		const char *val = get_param(cmd, "DPPNFCInit");
1415ed629d51SJouni Malinen 		int init = val && atoi(val) > 0;
1416ed629d51SJouni Malinen 		pid_t pid;
1417ed629d51SJouni Malinen 		int pid_status;
1418ed629d51SJouni Malinen 		int enrollee = 0;
1419ed629d51SJouni Malinen 
1420ed629d51SJouni Malinen 		if (strcasecmp(prov_role, "Configurator") == 0 ||
1421ed629d51SJouni Malinen 		    strcasecmp(prov_role, "Both") == 0) {
1422ed629d51SJouni Malinen 			if (!conf_role) {
1423ed629d51SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1424ed629d51SJouni Malinen 					  "errorCode,Missing DPPConfIndex");
1425ed629d51SJouni Malinen 				goto out;
1426ed629d51SJouni Malinen 			}
1427ed629d51SJouni Malinen 			snprintf(buf, sizeof(buf),
1428ed629d51SJouni Malinen 				 "SET dpp_configurator_params  conf=%s %s %s configurator=%d%s%s%s%s",
1429ed629d51SJouni Malinen 				 conf_role, conf_ssid, conf_pass,
1430ed629d51SJouni Malinen 				 dut->dpp_conf_id, group_id,
1431ed629d51SJouni Malinen 				 akm_use_selector ? " akm_use_selector=1" : "",
1432ed629d51SJouni Malinen 				 conn_status ? " conn_status=1" : "", conf2);
1433ed629d51SJouni Malinen 			if (wpa_command(ifname, buf) < 0) {
1434ed629d51SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1435ed629d51SJouni Malinen 					  "errorCode,Failed to set configurator parameters");
1436ed629d51SJouni Malinen 				goto out;
1437ed629d51SJouni Malinen 			}
1438ed629d51SJouni Malinen 			snprintf(buf, sizeof(buf),
1439ed629d51SJouni Malinen 				 "conf=%s %s %s configurator=%d%s%s%s%s",
1440ed629d51SJouni Malinen 				 conf_role, conf_ssid, conf_pass,
1441ed629d51SJouni Malinen 				 dut->dpp_conf_id, group_id,
1442ed629d51SJouni Malinen 				 akm_use_selector ? " akm_use_selector=1" : "",
1443ed629d51SJouni Malinen 				 conn_status ? " conn_status=1" : "", conf2);
1444ed629d51SJouni Malinen 		} else {
1445ed629d51SJouni Malinen 			buf[0] = '\0';
1446ed629d51SJouni Malinen 			enrollee = 1;
1447ed629d51SJouni Malinen 		}
1448ed629d51SJouni Malinen 
1449ed629d51SJouni Malinen 		run_system(dut, "killall dpp-nfc.py");
1450ed629d51SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_INFO, "Manual NFC operation");
1451ed629d51SJouni Malinen 		if (!file_exists("dpp-nfc.py")) {
1452ed629d51SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1453ed629d51SJouni Malinen 				  "errorCode,dpp-nfc.py not found");
1454ed629d51SJouni Malinen 			goto out;
1455ed629d51SJouni Malinen 		}
1456ed629d51SJouni Malinen 
1457ed629d51SJouni Malinen 		pid = fork();
1458ed629d51SJouni Malinen 		if (pid < 0) {
1459ed629d51SJouni Malinen 			perror("fork");
1460ed629d51SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1461ed629d51SJouni Malinen 				  "errorCode,fork() failed");
1462ed629d51SJouni Malinen 			goto out;
1463ed629d51SJouni Malinen 		}
1464ed629d51SJouni Malinen 
1465ed629d51SJouni Malinen 		if (pid == 0) {
1466ed629d51SJouni Malinen 			char * argv[] = { "dpp-nfc.py",
1467ed629d51SJouni Malinen 					  "--only-one", "--no-input",
1468ed629d51SJouni Malinen 					  "-i", (char *) ifname,
1469*ec5a4a44SJouni Malinen 					  "--ctrl", sigma_wpas_ctrl,
1470ed629d51SJouni Malinen 					  enrollee ? "--enrollee" :
1471ed629d51SJouni Malinen 					  "--configurator",
1472ed629d51SJouni Malinen 					  "--config-params", buf,
1473ed629d51SJouni Malinen 					  init ? "-I" : NULL,
1474ed629d51SJouni Malinen 					  NULL };
1475ed629d51SJouni Malinen 
1476ed629d51SJouni Malinen 			execv("./dpp-nfc.py", argv);
1477ed629d51SJouni Malinen 			perror("execv");
1478ed629d51SJouni Malinen 			exit(0);
1479ed629d51SJouni Malinen 			return -1;
1480ed629d51SJouni Malinen 		}
1481ed629d51SJouni Malinen 
1482ee7975a7SJouni Malinen 		usleep(300000);
1483ed629d51SJouni Malinen 		for (;;) {
1484ed629d51SJouni Malinen 			if (waitpid(pid, &pid_status, WNOHANG) > 0) {
1485ed629d51SJouni Malinen 				sigma_dut_print(dut, DUT_MSG_DEBUG,
1486ed629d51SJouni Malinen 						"dpp-nfc.py exited");
1487ed629d51SJouni Malinen 				break;
1488ed629d51SJouni Malinen 			}
1489ee7975a7SJouni Malinen 
1490ee7975a7SJouni Malinen 			time(&now);
1491ee7975a7SJouni Malinen 			if ((unsigned int) (now - start) >=
1492ee7975a7SJouni Malinen 			    dut->default_timeout) {
1493ed629d51SJouni Malinen 				sigma_dut_print(dut, DUT_MSG_DEBUG,
1494ed629d51SJouni Malinen 						"dpp-nfc.py did not exit within timeout - stop it");
1495ed629d51SJouni Malinen 				kill(pid, SIGTERM);
1496ee7975a7SJouni Malinen 				waitpid(pid, &pid_status, 0);
1497ee7975a7SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1498ee7975a7SJouni Malinen 					  "errorCode,dpp-nfc.py did not complete within timeout");
1499ee7975a7SJouni Malinen 				goto out;
1500ed629d51SJouni Malinen 			}
1501ed629d51SJouni Malinen 
1502ed629d51SJouni Malinen 			old_timeout = dut->default_timeout;
1503ee7975a7SJouni Malinen 			dut->default_timeout = 2;
1504ed629d51SJouni Malinen 			res = get_wpa_cli_event(dut, ctrl, "DPP-TX",
1505ed629d51SJouni Malinen 						buf, sizeof(buf));
1506ed629d51SJouni Malinen 			dut->default_timeout = old_timeout;
1507ed629d51SJouni Malinen 			if (res >= 0) {
1508ed629d51SJouni Malinen 				sigma_dut_print(dut, DUT_MSG_DEBUG,
1509ed629d51SJouni Malinen 						"DPP exchange started");
1510ee7975a7SJouni Malinen 				usleep(500000);
1511ed629d51SJouni Malinen 				kill(pid, SIGTERM);
1512ee7975a7SJouni Malinen 				waitpid(pid, &pid_status, 0);
1513ee7975a7SJouni Malinen 				break;
1514ed629d51SJouni Malinen 			}
1515ed629d51SJouni Malinen 		}
1516f37fda0fSJouni Malinen 	} else if ((nfc_handover &&
1517f37fda0fSJouni Malinen 		    strcasecmp(nfc_handover, "Negotiated_Requestor") == 0) ||
1518a833025dSJouni Malinen 		   ((!nfc_handover ||
1519a833025dSJouni Malinen 		     strcasecmp(nfc_handover, "Static") == 0) &&
1520ed629d51SJouni Malinen 		    auth_role && strcasecmp(auth_role, "Initiator") == 0)) {
1521d86e5828SJouni Malinen 		char own_txt[20];
1522b1dd21f8SJouni Malinen 		int dpp_peer_bootstrap = -1;
1523b5ab828bSJouni Malinen 		char neg_freq[30];
1524b5ab828bSJouni Malinen 
1525d1e22f76SJouni Malinen 		val = get_param(cmd, "DPPAuthDirection");
1526d1e22f76SJouni Malinen 		check_mutual = val && strcasecmp(val, "Mutual") == 0;
1527d1e22f76SJouni Malinen 
1528b5ab828bSJouni Malinen 		neg_freq[0] = '\0';
1529b5ab828bSJouni Malinen 		val = get_param(cmd, "DPPSubsequentChannel");
1530b5ab828bSJouni Malinen 		if (val) {
1531b5ab828bSJouni Malinen 			int opclass, channel, freq;
1532b5ab828bSJouni Malinen 
1533b5ab828bSJouni Malinen 			opclass = atoi(val);
1534b5ab828bSJouni Malinen 			val = strchr(val, '/');
1535b5ab828bSJouni Malinen 			if (opclass == 0 || !val) {
1536b5ab828bSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1537b5ab828bSJouni Malinen 					  "errorCode,Invalid DPPSubsequentChannel");
1538b5ab828bSJouni Malinen 				goto out;
1539b5ab828bSJouni Malinen 			}
1540b5ab828bSJouni Malinen 			val++;
1541b5ab828bSJouni Malinen 			channel = atoi(val);
1542b5ab828bSJouni Malinen 
1543b5ab828bSJouni Malinen 			/* Ignoring opclass for now; could use it here for more
1544b5ab828bSJouni Malinen 			 * robust frequency determination. */
1545093569ffSAlexei Avshalom Lazar 			freq = channel_to_freq(dut, channel);
1546b5ab828bSJouni Malinen 			if (!freq) {
1547b5ab828bSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1548b5ab828bSJouni Malinen 					  "errorCode,Unsupported DPPSubsequentChannel channel");
1549b5ab828bSJouni Malinen 				goto out;
1550b5ab828bSJouni Malinen 			}
1551b5ab828bSJouni Malinen 			snprintf(neg_freq, sizeof(neg_freq), " neg_freq=%d",
1552b5ab828bSJouni Malinen 				 freq);
1553b5ab828bSJouni Malinen 		}
1554b1dd21f8SJouni Malinen 
1555b1dd21f8SJouni Malinen 		if (strcasecmp(bs, "QR") == 0) {
1556b1dd21f8SJouni Malinen 			if (!dut->dpp_peer_uri) {
1557b1dd21f8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1558b1dd21f8SJouni Malinen 					  "errorCode,Missing peer bootstrapping info");
1559b1dd21f8SJouni Malinen 				goto out;
1560b1dd21f8SJouni Malinen 			}
1561b1dd21f8SJouni Malinen 
1562b1dd21f8SJouni Malinen 			snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1563b1dd21f8SJouni Malinen 				 dut->dpp_peer_uri);
1564b1dd21f8SJouni Malinen 			if (wpa_command_resp(ifname, buf, buf,
15653c27aa82SJouni Malinen 					     sizeof(buf)) < 0 ||
15663c27aa82SJouni Malinen 			    strncmp(buf, "FAIL", 4) == 0) {
1567b1dd21f8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1568b1dd21f8SJouni Malinen 					  "errorCode,Failed to parse URI");
1569b1dd21f8SJouni Malinen 				goto out;
1570b1dd21f8SJouni Malinen 			}
1571b1dd21f8SJouni Malinen 			dpp_peer_bootstrap = atoi(buf);
1572a833025dSJouni Malinen 		} else if (strcasecmp(bs, "NFC") == 0 && nfc_handover &&
1573a833025dSJouni Malinen 			   strcasecmp(nfc_handover, "Static") == 0) {
1574a833025dSJouni Malinen 			if (!dut->dpp_peer_uri) {
1575a833025dSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1576a833025dSJouni Malinen 					  "errorCode,Missing peer bootstrapping info");
1577a833025dSJouni Malinen 				goto out;
1578a833025dSJouni Malinen 			}
1579a833025dSJouni Malinen 
1580a833025dSJouni Malinen 			snprintf(buf, sizeof(buf), "DPP_NFC_URI %s",
1581a833025dSJouni Malinen 				 dut->dpp_peer_uri);
1582a833025dSJouni Malinen 			if (wpa_command_resp(ifname, buf,
1583a833025dSJouni Malinen 					     buf, sizeof(buf)) < 0 ||
1584a833025dSJouni Malinen 			    strncmp(buf, "FAIL", 4) == 0) {
1585a833025dSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1586a833025dSJouni Malinen 					  "errorCode,Failed to process URI from NFC Tag");
1587a833025dSJouni Malinen 				goto out;
1588a833025dSJouni Malinen 			}
1589a833025dSJouni Malinen 			dpp_peer_bootstrap = atoi(buf);
1590f37fda0fSJouni Malinen 		} else if (strcasecmp(bs, "NFC") == 0) {
1591f37fda0fSJouni Malinen 			if (!dut->dpp_peer_uri) {
1592f37fda0fSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1593f37fda0fSJouni Malinen 					  "errorCode,Missing peer bootstrapping info");
1594f37fda0fSJouni Malinen 				goto out;
1595f37fda0fSJouni Malinen 			}
1596f37fda0fSJouni Malinen 			if (dut->dpp_local_bootstrap < 0) {
1597f37fda0fSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1598f37fda0fSJouni Malinen 					  "errorCode,Missing own bootstrapping info");
1599f37fda0fSJouni Malinen 				goto out;
1600f37fda0fSJouni Malinen 			}
1601f37fda0fSJouni Malinen 
1602f37fda0fSJouni Malinen 			snprintf(buf, sizeof(buf),
1603f37fda0fSJouni Malinen 				 "DPP_NFC_HANDOVER_SEL own=%d uri=%s",
1604f37fda0fSJouni Malinen 				 dut->dpp_local_bootstrap, dut->dpp_peer_uri);
1605f37fda0fSJouni Malinen 			if (wpa_command_resp(ifname, buf,
1606f37fda0fSJouni Malinen 					     buf, sizeof(buf)) < 0 ||
1607f37fda0fSJouni Malinen 			    strncmp(buf, "FAIL", 4) == 0) {
1608f37fda0fSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1609f37fda0fSJouni Malinen 					  "errorCode,Failed to process NFC Handover Select");
1610f37fda0fSJouni Malinen 				goto out;
1611f37fda0fSJouni Malinen 			}
1612f37fda0fSJouni Malinen 			dpp_peer_bootstrap = atoi(buf);
1613b1dd21f8SJouni Malinen 		}
1614d86e5828SJouni Malinen 
161563d5041cSJouni Malinen 		if (dut->dpp_local_bootstrap >= 0)
1616d86e5828SJouni Malinen 			snprintf(own_txt, sizeof(own_txt), " own=%d",
1617d86e5828SJouni Malinen 				 dut->dpp_local_bootstrap);
1618d86e5828SJouni Malinen 		else
1619d86e5828SJouni Malinen 			own_txt[0] = '\0';
1620c240fe5aSJouni Malinen 		if (chirp) {
1621c240fe5aSJouni Malinen 			int freq = 2462; /* default: channel 6 */
1622c240fe5aSJouni Malinen 
1623c240fe5aSJouni Malinen 			val = get_param(cmd, "DPPChirpChannel");
1624c240fe5aSJouni Malinen 			if (val) {
1625c240fe5aSJouni Malinen 				freq = channel_to_freq(dut, atoi(val));
1626c240fe5aSJouni Malinen 				if (!freq) {
1627c240fe5aSJouni Malinen 					send_resp(dut, conn, SIGMA_ERROR,
1628c240fe5aSJouni Malinen 						  "errorCode,Unsupported DPPChirpChannel channel");
1629c240fe5aSJouni Malinen 					goto out;
1630c240fe5aSJouni Malinen 				}
1631c240fe5aSJouni Malinen 			}
1632c240fe5aSJouni Malinen 
1633c240fe5aSJouni Malinen 			if (strcasecmp(prov_role, "Configurator") == 0 ||
1634c240fe5aSJouni Malinen 			    strcasecmp(prov_role, "Both") == 0) {
1635c240fe5aSJouni Malinen 				if (!conf_role) {
1636c240fe5aSJouni Malinen 					send_resp(dut, conn, SIGMA_ERROR,
1637c240fe5aSJouni Malinen 						  "errorCode,Missing DPPConfIndex");
1638c240fe5aSJouni Malinen 					goto out;
1639c240fe5aSJouni Malinen 				}
1640c240fe5aSJouni Malinen 				snprintf(buf, sizeof(buf),
1641c240fe5aSJouni Malinen 					 "SET dpp_configurator_params  conf=%s %s %s configurator=%d%s%s%s%s",
1642c240fe5aSJouni Malinen 					 conf_role, conf_ssid, conf_pass,
1643c240fe5aSJouni Malinen 					 dut->dpp_conf_id, group_id,
1644c240fe5aSJouni Malinen 					 akm_use_selector ?
1645c240fe5aSJouni Malinen 					 " akm_use_selector=1" : "",
1646c240fe5aSJouni Malinen 					 conn_status ? " conn_status=1" : "",
1647c240fe5aSJouni Malinen 					 conf2);
1648c240fe5aSJouni Malinen 				if (wpa_command(ifname, buf) < 0) {
1649c240fe5aSJouni Malinen 					send_resp(dut, conn, SIGMA_ERROR,
1650c240fe5aSJouni Malinen 						  "errorCode,Failed to set configurator parameters");
1651c240fe5aSJouni Malinen 					goto out;
1652c240fe5aSJouni Malinen 				}
1653c240fe5aSJouni Malinen 			}
1654c240fe5aSJouni Malinen 
1655c240fe5aSJouni Malinen 			if (tcp && strcasecmp(tcp, "yes") == 0) {
1656c240fe5aSJouni Malinen 				snprintf(buf, sizeof(buf),
1657c240fe5aSJouni Malinen 					 "DPP_CONTROLLER_START");
1658c240fe5aSJouni Malinen 			} else {
1659c240fe5aSJouni Malinen 				snprintf(buf, sizeof(buf),
1660c240fe5aSJouni Malinen 					 "DPP_LISTEN %d role=%s%s%s",
1661c240fe5aSJouni Malinen 					 freq, role,
1662c240fe5aSJouni Malinen 					 netrole ? " netrole=" : "",
1663c240fe5aSJouni Malinen 					 netrole ? netrole : "");
1664c240fe5aSJouni Malinen 			}
1665c240fe5aSJouni Malinen 		} else if ((strcasecmp(bs, "QR") == 0 ||
1666c240fe5aSJouni Malinen 			    strcasecmp(bs, "NFC") == 0) &&
166767acb0cfSJouni Malinen 			   (strcasecmp(prov_role, "Configurator") == 0 ||
166867acb0cfSJouni Malinen 			    strcasecmp(prov_role, "Both") == 0)) {
1669258cc26aSJouni Malinen 			if (!conf_role) {
1670258cc26aSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1671258cc26aSJouni Malinen 					  "errorCode,Missing DPPConfIndex");
1672258cc26aSJouni Malinen 				goto out;
1673258cc26aSJouni Malinen 			}
1674d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
1675fa1d9c93SJouni Malinen 				 "DPP_AUTH_INIT peer=%d%s role=%s%s%s conf=%s %s %s configurator=%d%s%s%s%s%s%s%s",
1676b1dd21f8SJouni Malinen 				 dpp_peer_bootstrap, own_txt, role,
1677a28608abSJouni Malinen 				 netrole ? " netrole=" : "",
1678a28608abSJouni Malinen 				 netrole ? netrole : "",
1679d86e5828SJouni Malinen 				 conf_role, conf_ssid, conf_pass,
16807a7ecf73SJouni Malinen 				 dut->dpp_conf_id, neg_freq, group_id,
16817a7ecf73SJouni Malinen 				 akm_use_selector ? " akm_use_selector=1" : "",
16829be22eddSJouni Malinen 				 conn_status ? " conn_status=1" : "",
1683fa1d9c93SJouni Malinen 				 tcp ? " tcp_addr=" : "",
1684fa1d9c93SJouni Malinen 				 tcp ? tcp : "",
16857a7ecf73SJouni Malinen 				 conf2);
1686f37fda0fSJouni Malinen 		} else if (tcp && (strcasecmp(bs, "QR") == 0 ||
1687f37fda0fSJouni Malinen 				   strcasecmp(bs, "NFC") == 0)) {
16881352f1e7SJouni Malinen 			snprintf(buf, sizeof(buf),
1689a28608abSJouni Malinen 				 "DPP_AUTH_INIT peer=%d%s role=%s%s%s tcp_addr=%s%s%s",
1690a28608abSJouni Malinen 				 dpp_peer_bootstrap, own_txt, role,
1691a28608abSJouni Malinen 				 netrole ? " netrole=" : "",
1692a28608abSJouni Malinen 				 netrole ? netrole : "",
1693a28608abSJouni Malinen 				 tcp, neg_freq, group_id);
1694f37fda0fSJouni Malinen 		} else if (strcasecmp(bs, "QR") == 0 ||
1695f37fda0fSJouni Malinen 			   strcasecmp(bs, "NFC") == 0) {
1696d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
1697a28608abSJouni Malinen 				 "DPP_AUTH_INIT peer=%d%s role=%s%s%s%s%s",
169811ab72c2SPurushottam Kushwaha 				 dpp_peer_bootstrap, own_txt, role,
1699a28608abSJouni Malinen 				 netrole ? " netrole=" : "",
1700a28608abSJouni Malinen 				 netrole ? netrole : "",
170111ab72c2SPurushottam Kushwaha 				 neg_freq, group_id);
1702d86e5828SJouni Malinen 		} else if (strcasecmp(bs, "PKEX") == 0 &&
170367acb0cfSJouni Malinen 			   (strcasecmp(prov_role, "Configurator") == 0 ||
170467acb0cfSJouni Malinen 			    strcasecmp(prov_role, "Both") == 0)) {
1705258cc26aSJouni Malinen 			if (!conf_role) {
1706258cc26aSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1707258cc26aSJouni Malinen 					  "errorCode,Missing DPPConfIndex");
1708258cc26aSJouni Malinen 				goto out;
1709258cc26aSJouni Malinen 			}
1710d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
1711d86e5828SJouni Malinen 				 "DPP_PKEX_ADD own=%d init=1 role=%s conf=%s %s %s configurator=%d %scode=%s",
1712d86e5828SJouni Malinen 				 own_pkex_id, role, conf_role,
1713d86e5828SJouni Malinen 				 conf_ssid, conf_pass, dut->dpp_conf_id,
1714d86e5828SJouni Malinen 				 pkex_identifier, pkex_code);
1715d86e5828SJouni Malinen 		} else if (strcasecmp(bs, "PKEX") == 0) {
1716d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
1717d86e5828SJouni Malinen 				 "DPP_PKEX_ADD own=%d init=1 role=%s %scode=%s",
1718d86e5828SJouni Malinen 				 own_pkex_id, role, pkex_identifier, pkex_code);
1719d551c6fcSJouni Malinen 		} else {
1720d551c6fcSJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1721d551c6fcSJouni Malinen 				  "errorCode,Unsupported DPPBS");
1722d551c6fcSJouni Malinen 			goto out;
1723d86e5828SJouni Malinen 		}
1724d86e5828SJouni Malinen 		if (wpa_command(ifname, buf) < 0) {
1725d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1726d86e5828SJouni Malinen 				  "errorCode,Failed to initiate DPP authentication");
1727d86e5828SJouni Malinen 			goto out;
1728d86e5828SJouni Malinen 		}
17293d16ccbdSJouni Malinen 	} else if ((nfc_handover &&
17303d16ccbdSJouni Malinen 		    strcasecmp(nfc_handover, "Negotiated_Selector") == 0) ||
173104054cceSJouni Malinen 		   ((!nfc_handover ||
173204054cceSJouni Malinen 		     strcasecmp(nfc_handover, "Static") == 0) &&
1733ed629d51SJouni Malinen 		    auth_role && strcasecmp(auth_role, "Responder") == 0)) {
173467f096aaSJouni Malinen 		const char *delay_qr_resp;
173563d5041cSJouni Malinen 		int mutual;
1736d3afc5cbSJouni Malinen 		int freq = 2462; /* default: channel 11 */
1737d3afc5cbSJouni Malinen 
1738f8d81aa4SJouni Malinen 		if (sigma_dut_is_ap(dut) && dut->hostapd_running &&
1739f8d81aa4SJouni Malinen 		    dut->ap_oper_chn)
1740f8d81aa4SJouni Malinen 			freq = channel_to_freq(dut, dut->ap_channel);
1741f8d81aa4SJouni Malinen 
1742d2e9bb3eSJouni Malinen 		if (sigma_dut_is_ap(dut) && dpp_hostapd_beacon(dut) < 0) {
1743d2e9bb3eSJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1744d2e9bb3eSJouni Malinen 				  "errorCode,Failed to start AP mode listen");
1745d2e9bb3eSJouni Malinen 			goto out;
1746d2e9bb3eSJouni Malinen 		}
1747d2e9bb3eSJouni Malinen 
174806cfcb3eSJouni Malinen 		if (strcasecmp(bs, "PKEX") == 0) {
174906cfcb3eSJouni Malinen 			/* default: channel 6 for PKEX */
175006cfcb3eSJouni Malinen 			freq = 2437;
175106cfcb3eSJouni Malinen 		}
175206cfcb3eSJouni Malinen 
175367f096aaSJouni Malinen 		delay_qr_resp = get_param(cmd, "DPPDelayQRResponse");
175467f096aaSJouni Malinen 
175563d5041cSJouni Malinen 		val = get_param(cmd, "DPPAuthDirection");
175663d5041cSJouni Malinen 		mutual = val && strcasecmp(val, "Mutual") == 0;
175763d5041cSJouni Malinen 
1758d3afc5cbSJouni Malinen 		val = get_param(cmd, "DPPListenChannel");
1759d3afc5cbSJouni Malinen 		if (val) {
1760093569ffSAlexei Avshalom Lazar 			freq = channel_to_freq(dut, atoi(val));
1761d3afc5cbSJouni Malinen 			if (freq == 0) {
1762d3afc5cbSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1763d3afc5cbSJouni Malinen 					  "errorCode,Unsupported DPPListenChannel value");
1764d3afc5cbSJouni Malinen 				goto out;
1765d3afc5cbSJouni Malinen 			}
1766d3afc5cbSJouni Malinen 		}
1767d86e5828SJouni Malinen 
176804054cceSJouni Malinen 		if (strcasecmp(bs, "NFC") == 0 && nfc_handover &&
176904054cceSJouni Malinen 		    strcasecmp(nfc_handover, "Static") == 0) {
177004054cceSJouni Malinen 			/* No steps needed here - waiting for peer to initiate
177104054cceSJouni Malinen 			 * once it reads the URI from the NFC Tag */
177204054cceSJouni Malinen 		} else if (strcasecmp(bs, "NFC") == 0) {
17733d16ccbdSJouni Malinen 			if (!dut->dpp_peer_uri) {
17743d16ccbdSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
17753d16ccbdSJouni Malinen 					  "errorCode,Missing peer bootstrapping info");
17763d16ccbdSJouni Malinen 				goto out;
17773d16ccbdSJouni Malinen 			}
17783d16ccbdSJouni Malinen 			if (dut->dpp_local_bootstrap < 0) {
17793d16ccbdSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
17803d16ccbdSJouni Malinen 					  "errorCode,Missing own bootstrapping info");
17813d16ccbdSJouni Malinen 				goto out;
17823d16ccbdSJouni Malinen 			}
17833d16ccbdSJouni Malinen 
17843d16ccbdSJouni Malinen 			snprintf(buf, sizeof(buf),
17853d16ccbdSJouni Malinen 				 "DPP_NFC_HANDOVER_REQ own=%d uri=%s",
17863d16ccbdSJouni Malinen 				 dut->dpp_local_bootstrap, dut->dpp_peer_uri);
17873d16ccbdSJouni Malinen 			if (wpa_command(ifname, buf) < 0) {
17883d16ccbdSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
17893d16ccbdSJouni Malinen 					  "errorCode,Failed to process NFC Handover Request");
17903d16ccbdSJouni Malinen 				goto out;
17913d16ccbdSJouni Malinen 			}
17923d16ccbdSJouni Malinen 
17933d16ccbdSJouni Malinen 			snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_INFO %d",
17943d16ccbdSJouni Malinen 				 dut->dpp_local_bootstrap);
17953d16ccbdSJouni Malinen 			if (wpa_command_resp(ifname, buf,
17963d16ccbdSJouni Malinen 					     buf, sizeof(buf)) < 0 ||
17973d16ccbdSJouni Malinen 			    strncmp(buf, "FAIL", 4) == 0) {
17983d16ccbdSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
17993d16ccbdSJouni Malinen 					  "errorCode,Failed to get bootstrap information");
18003d16ccbdSJouni Malinen 				goto out;
18013d16ccbdSJouni Malinen 			}
18023d16ccbdSJouni Malinen 			pos = buf;
18033d16ccbdSJouni Malinen 			while (pos) {
18043d16ccbdSJouni Malinen 				pos2 = strchr(pos, '\n');
18053d16ccbdSJouni Malinen 				if (pos2)
18063d16ccbdSJouni Malinen 					*pos2 = '\0';
18073d16ccbdSJouni Malinen 				if (strncmp(pos, "use_freq=", 9) == 0) {
18083d16ccbdSJouni Malinen 					freq = atoi(pos + 9);
18093d16ccbdSJouni Malinen 					sigma_dut_print(dut, DUT_MSG_DEBUG,
18103d16ccbdSJouni Malinen 							"DPP negotiation frequency from NFC handover: %d MHz",
18113d16ccbdSJouni Malinen 							freq);
18123d16ccbdSJouni Malinen 					break;
18133d16ccbdSJouni Malinen 				}
18143d16ccbdSJouni Malinen 
18153d16ccbdSJouni Malinen 				if (!pos2)
18163d16ccbdSJouni Malinen 					break;
18173d16ccbdSJouni Malinen 				pos = pos2 + 1;
18183d16ccbdSJouni Malinen 			}
18193d16ccbdSJouni Malinen 		} else if (!delay_qr_resp && dut->dpp_peer_uri) {
1820b1dd21f8SJouni Malinen 			snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1821b1dd21f8SJouni Malinen 				 dut->dpp_peer_uri);
1822b1dd21f8SJouni Malinen 			if (wpa_command_resp(ifname, buf, buf,
1823b1dd21f8SJouni Malinen 					     sizeof(buf)) < 0) {
1824b1dd21f8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1825b1dd21f8SJouni Malinen 					  "errorCode,Failed to parse URI");
1826b1dd21f8SJouni Malinen 				goto out;
1827b1dd21f8SJouni Malinen 			}
1828b1dd21f8SJouni Malinen 		}
1829b1dd21f8SJouni Malinen 
1830d86e5828SJouni Malinen 		if (strcasecmp(prov_role, "Configurator") == 0) {
1831258cc26aSJouni Malinen 			if (!conf_role) {
1832258cc26aSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1833258cc26aSJouni Malinen 					  "errorCode,Missing DPPConfIndex");
1834258cc26aSJouni Malinen 				goto out;
1835258cc26aSJouni Malinen 			}
1836d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
18379be22eddSJouni Malinen 				 "SET dpp_configurator_params  conf=%s %s %s configurator=%d%s%s%s%s",
1838d86e5828SJouni Malinen 				 conf_role, conf_ssid, conf_pass,
18397a7ecf73SJouni Malinen 				 dut->dpp_conf_id, group_id,
18407a7ecf73SJouni Malinen 				 akm_use_selector ? " akm_use_selector=1" : "",
18419be22eddSJouni Malinen 				 conn_status ? " conn_status=1" : "",
18427a7ecf73SJouni Malinen 				 conf2);
1843d86e5828SJouni Malinen 			if (wpa_command(ifname, buf) < 0) {
1844d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1845d86e5828SJouni Malinen 					  "errorCode,Failed to set configurator parameters");
1846d86e5828SJouni Malinen 				goto out;
1847d86e5828SJouni Malinen 			}
1848d86e5828SJouni Malinen 		}
1849d86e5828SJouni Malinen 		if (strcasecmp(bs, "PKEX") == 0) {
1850d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
1851d86e5828SJouni Malinen 				 "DPP_PKEX_ADD own=%d role=%s %scode=%s",
1852d86e5828SJouni Malinen 				 own_pkex_id, role, pkex_identifier, pkex_code);
1853d86e5828SJouni Malinen 			if (wpa_command(ifname, buf) < 0) {
1854d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1855d86e5828SJouni Malinen 					  "errorCode,Failed to configure DPP PKEX");
1856d86e5828SJouni Malinen 				goto out;
1857d86e5828SJouni Malinen 			}
1858d86e5828SJouni Malinen 		}
1859d86e5828SJouni Malinen 
1860c240fe5aSJouni Malinen 		if (chirp) {
186116b84d5dSJouni Malinen 			snprintf(buf, sizeof(buf),
186216b84d5dSJouni Malinen 				 "DPP_CHIRP own=%d iter=10 listen=%d",
1863c240fe5aSJouni Malinen 				 dut->dpp_local_bootstrap, freq);
1864c240fe5aSJouni Malinen 		} else if (tcp && strcasecmp(tcp, "yes") == 0) {
1865785afb44SJouni Malinen 			snprintf(buf, sizeof(buf), "DPP_CONTROLLER_START");
1866785afb44SJouni Malinen 		} else {
1867a28608abSJouni Malinen 			snprintf(buf, sizeof(buf),
1868a28608abSJouni Malinen 				 "DPP_LISTEN %d role=%s%s%s%s",
1869fd7359aeSJouni Malinen 				 freq, role,
1870fd7359aeSJouni Malinen 				 (strcasecmp(bs, "QR") == 0 && mutual) ?
1871a28608abSJouni Malinen 				 " qr=mutual" : "",
1872a28608abSJouni Malinen 				 netrole ? " netrole=" : "",
1873a28608abSJouni Malinen 				 netrole ? netrole : "");
1874785afb44SJouni Malinen 		}
1875d86e5828SJouni Malinen 		if (wpa_command(ifname, buf) < 0) {
1876d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
1877c240fe5aSJouni Malinen 				  "errorCode,Failed to start DPP listen/chirp");
1878d86e5828SJouni Malinen 			goto out;
1879d86e5828SJouni Malinen 		}
1880b1dd21f8SJouni Malinen 
1881785afb44SJouni Malinen 		if (!(tcp && strcasecmp(tcp, "yes") == 0) &&
1882016ae6c8SJouni Malinen 		    get_driver_type(dut) == DRIVER_OPENWRT) {
1883b4de1962Spriyadharshini gowthaman 			snprintf(buf, sizeof(buf), "iwconfig %s channel %d",
1884b4de1962Spriyadharshini gowthaman 				 dut->hostapd_ifname, freq_to_channel(freq));
1885b4de1962Spriyadharshini gowthaman 			run_system(dut, buf);
1886b4de1962Spriyadharshini gowthaman 		}
1887b4de1962Spriyadharshini gowthaman 
1888b1dd21f8SJouni Malinen 		if (delay_qr_resp && mutual && dut->dpp_peer_uri) {
1889b1dd21f8SJouni Malinen 			int wait_time = atoi(delay_qr_resp);
1890b1dd21f8SJouni Malinen 
1891b1dd21f8SJouni Malinen 			res = get_wpa_cli_events(dut, ctrl, auth_events,
1892b1dd21f8SJouni Malinen 						 buf, sizeof(buf));
1893b1dd21f8SJouni Malinen 			if (res < 0) {
1894b1dd21f8SJouni Malinen 				send_resp(dut, conn, SIGMA_COMPLETE,
1895b1dd21f8SJouni Malinen 					  "BootstrapResult,OK,AuthResult,Timeout");
1896b1dd21f8SJouni Malinen 				goto out;
1897b1dd21f8SJouni Malinen 			}
1898b1dd21f8SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
1899b1dd21f8SJouni Malinen 					"DPP auth result: %s", buf);
1900b1dd21f8SJouni Malinen 			if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) {
1901b1dd21f8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1902b1dd21f8SJouni Malinen 					  "errorCode,No scan request for peer QR Code seen");
1903b1dd21f8SJouni Malinen 				goto out;
1904b1dd21f8SJouni Malinen 			}
1905b1dd21f8SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
1906b1dd21f8SJouni Malinen 					"Waiting %d second(s) before processing peer URI",
1907b1dd21f8SJouni Malinen 					wait_time);
1908b1dd21f8SJouni Malinen 			sleep(wait_time);
1909b1dd21f8SJouni Malinen 
1910b1dd21f8SJouni Malinen 			snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1911b1dd21f8SJouni Malinen 				 dut->dpp_peer_uri);
1912b1dd21f8SJouni Malinen 			if (wpa_command_resp(ifname, buf, buf,
1913b1dd21f8SJouni Malinen 					     sizeof(buf)) < 0) {
1914b1dd21f8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
1915b1dd21f8SJouni Malinen 					  "errorCode,Failed to parse URI");
1916b1dd21f8SJouni Malinen 				goto out;
1917b1dd21f8SJouni Malinen 			}
1918bc9e055cSSrinivas Dasari 		} else if (mutual && action_type &&
1919bc9e055cSSrinivas Dasari 			   strcasecmp(action_type, "ManualDPP") == 0) {
1920bc9e055cSSrinivas Dasari 			res = get_wpa_cli_events(dut, ctrl, auth_events,
1921bc9e055cSSrinivas Dasari 						 buf, sizeof(buf));
1922bc9e055cSSrinivas Dasari 			if (res < 0) {
1923bc9e055cSSrinivas Dasari 				send_resp(dut, conn, SIGMA_COMPLETE,
1924bc9e055cSSrinivas Dasari 					  "BootstrapResult,OK,AuthResult,Timeout");
1925bc9e055cSSrinivas Dasari 				goto out;
1926bc9e055cSSrinivas Dasari 			}
1927bc9e055cSSrinivas Dasari 			sigma_dut_print(dut, DUT_MSG_DEBUG,
1928bc9e055cSSrinivas Dasari 					"DPP auth result: %s", buf);
1929e3b13933SSrinivas Dasari 			if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
1930e3b13933SSrinivas Dasari 			    send_resp(dut, conn, SIGMA_COMPLETE,
1931e3b13933SSrinivas Dasari 				      "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
1932e3b13933SSrinivas Dasari 			    goto out;
1933e3b13933SSrinivas Dasari 			}
1934e3b13933SSrinivas Dasari 
1935bc9e055cSSrinivas Dasari 			if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) {
1936bc9e055cSSrinivas Dasari 				send_resp(dut, conn, SIGMA_ERROR,
1937bc9e055cSSrinivas Dasari 					  "errorCode,No scan request for peer QR Code seen");
1938bc9e055cSSrinivas Dasari 				goto out;
1939bc9e055cSSrinivas Dasari 			}
1940bc9e055cSSrinivas Dasari 
1941bc9e055cSSrinivas Dasari 			if (dpp_scan_peer_qrcode(dut) < 0) {
1942bc9e055cSSrinivas Dasari 				send_resp(dut, conn, SIGMA_ERROR,
1943bc9e055cSSrinivas Dasari 					  "errorCode,Failed to scan peer QR Code");
1944bc9e055cSSrinivas Dasari 				goto out;
1945bc9e055cSSrinivas Dasari 			}
1946bc9e055cSSrinivas Dasari 
1947bc9e055cSSrinivas Dasari 			snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1948bc9e055cSSrinivas Dasari 				 dut->dpp_peer_uri);
1949bc9e055cSSrinivas Dasari 			if (wpa_command_resp(ifname, buf, buf,
1950bc9e055cSSrinivas Dasari 					     sizeof(buf)) < 0) {
1951bc9e055cSSrinivas Dasari 				send_resp(dut, conn, SIGMA_ERROR,
1952bc9e055cSSrinivas Dasari 					  "errorCode,Failed to parse URI");
1953bc9e055cSSrinivas Dasari 				goto out;
1954bc9e055cSSrinivas Dasari 			}
1955b1dd21f8SJouni Malinen 		}
1956d86e5828SJouni Malinen 	} else {
1957d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
1958d86e5828SJouni Malinen 			  "errorCode,Unknown DPPAuthRole");
1959d86e5828SJouni Malinen 		goto out;
1960d86e5828SJouni Malinen 	}
1961d86e5828SJouni Malinen 
19623a6b92a6SJouni Malinen 	if (step && strcasecmp(step, "Timeout") == 0) {
19633a6b92a6SJouni Malinen 		result = "errorCode,Unexpected state";
19643a6b92a6SJouni Malinen 
19653a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "PKEXExchangeResponse") == 0) {
19669a3415c2SJouni Malinen 			if (dpp_wait_rx(dut, ctrl, 8, -1) < 0)
19673a6b92a6SJouni Malinen 				result = "BootstrapResult,Timeout";
19683a6b92a6SJouni Malinen 			else
19693a6b92a6SJouni Malinen 				result = "BootstrapResult,Errorsent";
19703a6b92a6SJouni Malinen 		}
19713a6b92a6SJouni Malinen 
19723a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "PKEXCRRequest") == 0) {
19739a3415c2SJouni Malinen 			if (dpp_wait_rx(dut, ctrl, 9, -1) < 0)
19743a6b92a6SJouni Malinen 				result = "BootstrapResult,Timeout";
19753a6b92a6SJouni Malinen 			else
19763a6b92a6SJouni Malinen 				result = "BootstrapResult,Errorsent";
19773a6b92a6SJouni Malinen 		}
19783a6b92a6SJouni Malinen 
19793a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "PKEXCRResponse") == 0) {
19809a3415c2SJouni Malinen 			if (dpp_wait_rx(dut, ctrl, 10, -1) < 0)
19813a6b92a6SJouni Malinen 				result = "BootstrapResult,Timeout";
19823a6b92a6SJouni Malinen 			else
19833a6b92a6SJouni Malinen 				result = "BootstrapResult,Errorsent";
19843a6b92a6SJouni Malinen 		}
19853a6b92a6SJouni Malinen 
19863a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "AuthenticationRequest") == 0) {
19879a3415c2SJouni Malinen 			if (dpp_wait_rx(dut, ctrl, 0, -1) < 0)
19883a6b92a6SJouni Malinen 				result = "BootstrapResult,OK,AuthResult,Timeout";
19893a6b92a6SJouni Malinen 			else
19903a6b92a6SJouni Malinen 				result = "BootstrapResult,OK,AuthResult,Errorsent";
19913a6b92a6SJouni Malinen 		}
19923a6b92a6SJouni Malinen 
19933a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "AuthenticationResponse") == 0) {
19949a3415c2SJouni Malinen 			if (dpp_wait_rx(dut, ctrl, 1, -1) < 0)
19953a6b92a6SJouni Malinen 				result = "BootstrapResult,OK,AuthResult,Timeout";
19963a6b92a6SJouni Malinen 			else
19973a6b92a6SJouni Malinen 				result = "BootstrapResult,OK,AuthResult,Errorsent";
19983a6b92a6SJouni Malinen 		}
19993a6b92a6SJouni Malinen 
20003a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "AuthenticationConfirm") == 0) {
2001ed629d51SJouni Malinen 			if (auth_role &&
2002ed629d51SJouni Malinen 			    strcasecmp(auth_role, "Initiator") == 0) {
2003a1199884SJouni Malinen 				/* This special case of DPPStep,Timeout with
2004a1199884SJouni Malinen 				 * DPPFrameType,AuthenticationConfirm on an
2005a1199884SJouni Malinen 				 * Initiator is used to cover need for stopping
2006a1199884SJouni Malinen 				 * the Initiator/Enrollee from sending out
2007a1199884SJouni Malinen 				 * Configuration Request message. */
2008a1199884SJouni Malinen 				if (strcasecmp(prov_role, "Enrollee") != 0) {
2009a1199884SJouni Malinen 					send_resp(dut, conn, SIGMA_ERROR,
2010a1199884SJouni Malinen 						  "errorCode,Unexpected use of timeout after AuthenticationConfirm TX in Configurator role");
2011a1199884SJouni Malinen 					goto out;
2012a1199884SJouni Malinen 				}
2013671c9e1aSSrinivas Dasari 				if (check_mutual &&
2014671c9e1aSSrinivas Dasari 				    dpp_process_auth_response(
2015671c9e1aSSrinivas Dasari 					    dut, conn, ctrl, auth_events,
2016671c9e1aSSrinivas Dasari 					    action_type, check_mutual,
2017671c9e1aSSrinivas Dasari 					    buf, sizeof(buf)) < 0)
2018671c9e1aSSrinivas Dasari 					goto out;
2019ecb49d8bSDeepak Dhamdhere 				if (dpp_wait_tx_status(dut, ctrl, 2) < 0)
2020ecb49d8bSDeepak Dhamdhere 					result = "BootstrapResult,OK,AuthResult,Timeout";
2021ecb49d8bSDeepak Dhamdhere 				else
2022a1199884SJouni Malinen 					result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
2023ecb49d8bSDeepak Dhamdhere 			} else {
20249a3415c2SJouni Malinen 				if (dpp_wait_rx(dut, ctrl, 2, -1) < 0)
20253a6b92a6SJouni Malinen 					result = "BootstrapResult,OK,AuthResult,Timeout";
20263a6b92a6SJouni Malinen 				else
2027ecb49d8bSDeepak Dhamdhere 					result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm";
2028ecb49d8bSDeepak Dhamdhere 			}
20293a6b92a6SJouni Malinen 		}
20303a6b92a6SJouni Malinen 
20313a6b92a6SJouni Malinen 		if (strcasecmp(frametype, "ConfigurationRequest") == 0) {
20323a6b92a6SJouni Malinen 			if (get_wpa_cli_event(dut, ctrl, "DPP-CONF-FAILED",
20333a6b92a6SJouni Malinen 					      buf, sizeof(buf)) < 0)
20343a6b92a6SJouni Malinen 				result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
20353a6b92a6SJouni Malinen 			else
20363a6b92a6SJouni Malinen 				result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
20373a6b92a6SJouni Malinen 		}
20383a6b92a6SJouni Malinen 
20393a6b92a6SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
20403a6b92a6SJouni Malinen 		goto out;
20413a6b92a6SJouni Malinen 	}
20423a6b92a6SJouni Malinen 
2043772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "PKEXExchangeRequest") == 0) {
2044772299f1SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 7) < 0)
2045772299f1SJouni Malinen 			result = "BootstrapResult,Timeout";
2046772299f1SJouni Malinen 		else
2047772299f1SJouni Malinen 			result = "BootstrapResult,Errorsent";
2048772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
2049772299f1SJouni Malinen 		goto out;
2050772299f1SJouni Malinen 	}
2051772299f1SJouni Malinen 
2052772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "PKEXExchangeResponse") == 0) {
2053772299f1SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 8) < 0)
2054772299f1SJouni Malinen 			result = "BootstrapResult,Timeout";
2055772299f1SJouni Malinen 		else
2056772299f1SJouni Malinen 			result = "BootstrapResult,Errorsent";
2057772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
2058772299f1SJouni Malinen 		goto out;
2059772299f1SJouni Malinen 	}
2060772299f1SJouni Malinen 
2061772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "PKEXCRRequest") == 0) {
2062772299f1SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 9) < 0)
2063772299f1SJouni Malinen 			result = "BootstrapResult,Timeout";
2064772299f1SJouni Malinen 		else
2065772299f1SJouni Malinen 			result = "BootstrapResult,Errorsent";
2066772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
2067772299f1SJouni Malinen 		goto out;
2068772299f1SJouni Malinen 	}
2069772299f1SJouni Malinen 
2070772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "PKEXCRResponse") == 0) {
2071772299f1SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 10) < 0)
2072772299f1SJouni Malinen 			result = "BootstrapResult,Timeout";
2073772299f1SJouni Malinen 		else
2074772299f1SJouni Malinen 			result = "BootstrapResult,Errorsent";
2075772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
2076772299f1SJouni Malinen 		goto out;
2077772299f1SJouni Malinen 	}
2078772299f1SJouni Malinen 
20796792ff4dSJouni Malinen 	if (!frametype && strcasecmp(bs, "PKEX") == 0 &&
2080ed629d51SJouni Malinen 	    auth_role && strcasecmp(auth_role, "Responder") == 0) {
20816792ff4dSJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 10) < 0) {
20826792ff4dSJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
20836792ff4dSJouni Malinen 				  "BootstrapResult,Timeout");
20846792ff4dSJouni Malinen 			goto out;
20856792ff4dSJouni Malinen 		}
20866792ff4dSJouni Malinen 	}
20876792ff4dSJouni Malinen 
20886792ff4dSJouni Malinen 	if (!frametype && strcasecmp(bs, "PKEX") == 0 &&
2089ed629d51SJouni Malinen 	    auth_role && strcasecmp(auth_role, "Initiator") == 0) {
20906792ff4dSJouni Malinen 		if (dpp_wait_tx(dut, ctrl, 0) < 0) {
20916792ff4dSJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
20926792ff4dSJouni Malinen 				  "BootstrapResult,Timeout");
20936792ff4dSJouni Malinen 			goto out;
20946792ff4dSJouni Malinen 		}
20956792ff4dSJouni Malinen 	}
20966792ff4dSJouni Malinen 
2097772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "AuthenticationRequest") == 0) {
20989a3415c2SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 0) < 0) {
20999a3415c2SJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
21009a3415c2SJouni Malinen 				  "BootstrapResult,OK,AuthResult,Timeout");
21019a3415c2SJouni Malinen 			goto out;
21029a3415c2SJouni Malinen 		}
21039a3415c2SJouni Malinen 
21049a3415c2SJouni Malinen 		if (dpp_wait_rx(dut, ctrl, 1, 5) < 0)
21059a3415c2SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,None";
2106b9f1eb9bSDeepak Dhamdhere 		else if	(get_wpa_cli_events(dut, ctrl, auth_events,
2107b9f1eb9bSDeepak Dhamdhere 					    buf, sizeof(buf)) >= 0 &&
2108b9f1eb9bSDeepak Dhamdhere 			 strstr(buf, "DPP-RESPONSE-PENDING") != NULL)
2109b9f1eb9bSDeepak Dhamdhere 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponseWithStatusPending";
2110772299f1SJouni Malinen 		else
21119a3415c2SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
2112772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
2113772299f1SJouni Malinen 		goto out;
2114772299f1SJouni Malinen 	}
2115772299f1SJouni Malinen 
2116772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "AuthenticationResponse") == 0) {
21179a3415c2SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 1) < 0) {
21189a3415c2SJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
21199a3415c2SJouni Malinen 				  "BootstrapResult,OK,AuthResult,Timeout");
21209a3415c2SJouni Malinen 			goto out;
21219a3415c2SJouni Malinen 		}
21229a3415c2SJouni Malinen 
21239a3415c2SJouni Malinen 		if (dpp_wait_rx(dut, ctrl, 2, 5) < 0)
21249a3415c2SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationRequest";
2125772299f1SJouni Malinen 		else
21269a3415c2SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm";
2127772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
2128772299f1SJouni Malinen 		goto out;
2129772299f1SJouni Malinen 	}
2130772299f1SJouni Malinen 
21318d88d822SSrinivas Dasari 	if (dpp_process_auth_response(dut, conn, ctrl, auth_events, action_type,
21328d88d822SSrinivas Dasari 				      check_mutual, buf, sizeof(buf)) < 0)
2133bc9e055cSSrinivas Dasari 		goto out;
2134d1e22f76SJouni Malinen 
2135772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "AuthenticationConfirm") == 0) {
21369a3415c2SJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 2) < 0) {
21379a3415c2SJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
21389a3415c2SJouni Malinen 				  "BootstrapResult,OK,AuthResult,Timeout");
21399a3415c2SJouni Malinen 			goto out;
21409a3415c2SJouni Malinen 		}
21419a3415c2SJouni Malinen 
21429a3415c2SJouni Malinen 		if (dpp_wait_rx_conf_req(dut, ctrl, 5) < 0)
21439a3415c2SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
2144772299f1SJouni Malinen 		else
21459a3415c2SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,ConfigurationRequest";
2146772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
2147772299f1SJouni Malinen 		goto out;
2148772299f1SJouni Malinen 	}
2149772299f1SJouni Malinen 
2150bc9e055cSSrinivas Dasari 	if (strstr(buf, "DPP-AUTH-DIRECTION")) {
21512e9c8a46SJouni Malinen 		res = get_wpa_cli_events(dut, ctrl, auth_events,
21522e9c8a46SJouni Malinen 					 buf, sizeof(buf));
21532e9c8a46SJouni Malinen 		if (res < 0) {
21542e9c8a46SJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
21552e9c8a46SJouni Malinen 				  "BootstrapResult,OK,AuthResult,Timeout");
21562e9c8a46SJouni Malinen 			goto out;
21572e9c8a46SJouni Malinen 		}
2158bc9e055cSSrinivas Dasari 
2159bc9e055cSSrinivas Dasari 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
21602e9c8a46SJouni Malinen 	}
21612e9c8a46SJouni Malinen 
2162d86e5828SJouni Malinen 	if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
2163d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
2164d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
2165d86e5828SJouni Malinen 		goto out;
2166d86e5828SJouni Malinen 	}
2167d86e5828SJouni Malinen 
2168d86e5828SJouni Malinen 	if (!strstr(buf, "DPP-AUTH-SUCCESS")) {
2169d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
2170d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,FAILED");
2171d86e5828SJouni Malinen 		goto out;
2172d86e5828SJouni Malinen 	}
2173d86e5828SJouni Malinen 
2174772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "ConfigurationRequest") == 0) {
2175772299f1SJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE",
2176772299f1SJouni Malinen 					buf, sizeof(buf));
2177772299f1SJouni Malinen 		if (res < 0)
2178772299f1SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
2179772299f1SJouni Malinen 		else
2180772299f1SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
2181772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
2182772299f1SJouni Malinen 		goto out;
2183772299f1SJouni Malinen 	}
2184772299f1SJouni Malinen 
2185772299f1SJouni Malinen 	if (frametype && strcasecmp(frametype, "ConfigurationResponse") == 0) {
2186a97b745cSJouni Malinen 		res = get_wpa_cli_events(dut, ctrl, conf_events,
2187772299f1SJouni Malinen 					 buf, sizeof(buf));
2188772299f1SJouni Malinen 		if (res < 0)
2189772299f1SJouni Malinen 			result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
2190772299f1SJouni Malinen 		else
21919b4f275cSDeepak Dhamdhere 			result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent,LastFrameReceived,ConfigurationRequest";
2192772299f1SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
2193772299f1SJouni Malinen 		goto out;
2194772299f1SJouni Malinen 	}
2195772299f1SJouni Malinen 
2196d86e5828SJouni Malinen 	res = get_wpa_cli_events(dut, ctrl, conf_events, buf, sizeof(buf));
2197d86e5828SJouni Malinen 	if (res < 0) {
2198d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
2199d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout");
2200d86e5828SJouni Malinen 		goto out;
2201d86e5828SJouni Malinen 	}
2202d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP conf result: %s", buf);
2203d86e5828SJouni Malinen 
2204d86e5828SJouni Malinen 	if (!strstr(buf, "DPP-CONF-SENT") &&
2205d86e5828SJouni Malinen 	    !strstr(buf, "DPP-CONF-RECEIVED")) {
2206d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
2207d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,OK,ConfResult,FAILED");
2208d86e5828SJouni Malinen 		goto out;
2209d86e5828SJouni Malinen 	}
2210d86e5828SJouni Malinen 
22119be22eddSJouni Malinen 	if (conn_status && strstr(buf, "DPP-CONF-SENT") &&
22129be22eddSJouni Malinen 	    strstr(buf, "wait_conn_status=1")) {
22139be22eddSJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "DPP-CONN-STATUS-RESULT",
22149be22eddSJouni Malinen 					buf, sizeof(buf));
22159be22eddSJouni Malinen 		if (res < 0) {
22169be22eddSJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
22179be22eddSJouni Malinen 				  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,StatusResult,Timeout");
22189be22eddSJouni Malinen 		} else {
22199be22eddSJouni Malinen 			pos = strstr(buf, "result=");
22209be22eddSJouni Malinen 			if (!pos) {
22219be22eddSJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
22229be22eddSJouni Malinen 					  "errorCode,Status result value not reported");
22239be22eddSJouni Malinen 			} else {
22249be22eddSJouni Malinen 				pos += 7;
22259be22eddSJouni Malinen 				snprintf(buf, sizeof(buf),
22269be22eddSJouni Malinen 					 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,StatusResult,%d",
22279be22eddSJouni Malinen 					 atoi(pos));
22289be22eddSJouni Malinen 				send_resp(dut, conn, SIGMA_COMPLETE, buf);
22299be22eddSJouni Malinen 			}
22309be22eddSJouni Malinen 		}
22319be22eddSJouni Malinen 		goto out;
22329be22eddSJouni Malinen 	}
22339be22eddSJouni Malinen 
2234a28608abSJouni Malinen 	if (strcasecmp(prov_role, "Enrollee") == 0 && netrole &&
2235a28608abSJouni Malinen 	    strcmp(netrole, "configurator") == 0) {
2236a28608abSJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "DPP-CONFIGURATOR-ID",
2237a28608abSJouni Malinen 					buf, sizeof(buf));
2238a28608abSJouni Malinen 		if (res < 0) {
2239a28608abSJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
2240a28608abSJouni Malinen 				  "errorCode,No DPP-CONFIGURATOR-ID");
2241a28608abSJouni Malinen 			goto out;
2242a28608abSJouni Malinen 		}
2243a28608abSJouni Malinen 		pos = strchr(buf, ' ');
2244a28608abSJouni Malinen 		if (!pos) {
2245a28608abSJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
2246a28608abSJouni Malinen 				  "errorCode,Invalid DPP-CONFIGURATOR-ID");
2247a28608abSJouni Malinen 			goto out;
2248a28608abSJouni Malinen 		}
2249a28608abSJouni Malinen 		pos++;
2250a28608abSJouni Malinen 		dut->dpp_conf_id = atoi(pos);
2251a28608abSJouni Malinen 	} else if (sigma_dut_is_ap(dut) &&
2252d86e5828SJouni Malinen 		   strcasecmp(prov_role, "Enrollee") == 0) {
2253174db64fSJouni Malinen 	update_ap:
2254d86e5828SJouni Malinen 		res = dpp_hostapd_conf_update(dut, conn, ifname, ctrl);
2255d86e5828SJouni Malinen 		if (res == 0)
2256d86e5828SJouni Malinen 			goto out;
2257d86e5828SJouni Malinen 		if (res < 0) {
2258d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR, NULL);
2259d86e5828SJouni Malinen 			goto out;
2260d86e5828SJouni Malinen 		}
2261d86e5828SJouni Malinen 	}
2262d86e5828SJouni Malinen 
2263d86e5828SJouni Malinen 	if (strcasecmp(wait_conn, "Yes") == 0 &&
2264d86e5828SJouni Malinen 	    !sigma_dut_is_ap(dut) &&
2265d86e5828SJouni Malinen 	    strcasecmp(prov_role, "Enrollee") == 0) {
226685a5a2e5SJouni Malinen 		int netw_id;
226785a5a2e5SJouni Malinen 		char *pos;
226885a5a2e5SJouni Malinen 
226985a5a2e5SJouni Malinen 		res = get_wpa_cli_event(dut, ctrl, "DPP-NETWORK-ID",
227085a5a2e5SJouni Malinen 					buf, sizeof(buf));
227185a5a2e5SJouni Malinen 		if (res < 0) {
227285a5a2e5SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
227385a5a2e5SJouni Malinen 				  "errorCode,No DPP-NETWORK-ID");
227485a5a2e5SJouni Malinen 			goto out;
227585a5a2e5SJouni Malinen 		}
227685a5a2e5SJouni Malinen 		pos = strchr(buf, ' ');
227785a5a2e5SJouni Malinen 		if (!pos) {
227885a5a2e5SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
227985a5a2e5SJouni Malinen 				  "errorCode,Invalid DPP-NETWORK-ID");
228085a5a2e5SJouni Malinen 			goto out;
228185a5a2e5SJouni Malinen 		}
228285a5a2e5SJouni Malinen 		pos++;
228385a5a2e5SJouni Malinen 		netw_id = atoi(pos);
228485a5a2e5SJouni Malinen 		snprintf(buf, sizeof(buf), "GET_NETWORK %d key_mgmt", netw_id);
228585a5a2e5SJouni Malinen 		if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) {
228685a5a2e5SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
228785a5a2e5SJouni Malinen 				  "errorCode,Could not fetch provisioned key_mgmt");
228885a5a2e5SJouni Malinen 			goto out;
228985a5a2e5SJouni Malinen 		}
229085a5a2e5SJouni Malinen 		if (strncmp(buf, "SAE", 3) == 0) {
229185a5a2e5SJouni Malinen 			/* SAE generates PMKSA-CACHE-ADDED event */
229285a5a2e5SJouni Malinen 			not_dpp_akm = 1;
229385a5a2e5SJouni Malinen 		}
2294fbb268d7SJouni Malinen 	wait_connect:
229553558e0fSJouni Malinen 		if (frametype && strcasecmp(frametype,
229653558e0fSJouni Malinen 					    "PeerDiscoveryRequest") == 0) {
229753558e0fSJouni Malinen 			if (dpp_wait_tx_status(dut, ctrl, 5) < 0)
229853558e0fSJouni Malinen 				result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout";
229953558e0fSJouni Malinen 			else
230053558e0fSJouni Malinen 				result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent";
230153558e0fSJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE, result);
230253558e0fSJouni Malinen 			goto out;
230353558e0fSJouni Malinen 		}
230453558e0fSJouni Malinen 
2305d86e5828SJouni Malinen 		res = get_wpa_cli_events(dut, ctrl, conn_events,
2306d86e5828SJouni Malinen 					 buf, sizeof(buf));
2307d86e5828SJouni Malinen 		if (res < 0) {
2308d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
2309d86e5828SJouni Malinen 				  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout,NetworkConnectResult,Timeout");
2310d86e5828SJouni Malinen 			goto out;
2311d86e5828SJouni Malinen 		}
2312d86e5828SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP connect result: %s",
2313d86e5828SJouni Malinen 				buf);
2314d86e5828SJouni Malinen 
2315d86e5828SJouni Malinen 		if (strstr(buf, "PMKSA-CACHE-ADDED")) {
2316d86e5828SJouni Malinen 			res = get_wpa_cli_events(dut, ctrl, conn_events,
2317d86e5828SJouni Malinen 						 buf, sizeof(buf));
2318d86e5828SJouni Malinen 			if (res < 0) {
2319d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_COMPLETE,
232085a5a2e5SJouni Malinen 					  not_dpp_akm ?
232185a5a2e5SJouni Malinen 					  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,Timeout" :
2322d86e5828SJouni Malinen 					  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
2323d86e5828SJouni Malinen 				goto out;
2324d86e5828SJouni Malinen 			}
2325d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
2326d86e5828SJouni Malinen 					"DPP connect result: %s", buf);
2327d86e5828SJouni Malinen 			if (strstr(buf, "CTRL-EVENT-CONNECTED"))
2328d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_COMPLETE,
232985a5a2e5SJouni Malinen 					  not_dpp_akm ?
233085a5a2e5SJouni Malinen 					  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK" :
2331d86e5828SJouni Malinen 					  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK");
2332d86e5828SJouni Malinen 			else
2333d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_COMPLETE,
233485a5a2e5SJouni Malinen 					  not_dpp_akm ?
233585a5a2e5SJouni Malinen 					  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,Timeout" :
2336d86e5828SJouni Malinen 					  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
2337d86e5828SJouni Malinen 			goto out;
2338d86e5828SJouni Malinen 		}
2339d86e5828SJouni Malinen 
2340d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
2341d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK");
2342d86e5828SJouni Malinen 		goto out;
2343d86e5828SJouni Malinen 	}
2344d86e5828SJouni Malinen 
234553558e0fSJouni Malinen 	if (strcasecmp(wait_conn, "Yes") == 0 &&
234653558e0fSJouni Malinen 	    frametype && strcasecmp(frametype, "PeerDiscoveryResponse") == 0) {
234753558e0fSJouni Malinen 		if (dpp_wait_tx_status(dut, ctrl, 6) < 0)
234853558e0fSJouni Malinen 			result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout";
234953558e0fSJouni Malinen 		else
235053558e0fSJouni Malinen 			result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent";
235153558e0fSJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE, result);
235253558e0fSJouni Malinen 		goto out;
235353558e0fSJouni Malinen 	}
235453558e0fSJouni Malinen 
2355d86e5828SJouni Malinen 	send_resp(dut, conn, SIGMA_COMPLETE,
2356d86e5828SJouni Malinen 		  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK");
2357d86e5828SJouni Malinen out:
2358d86e5828SJouni Malinen 	wpa_ctrl_detach(ctrl);
2359d86e5828SJouni Malinen 	wpa_ctrl_close(ctrl);
2360785afb44SJouni Malinen 	if (tcp && strcasecmp(tcp, "yes") == 0 &&
2361785afb44SJouni Malinen 	    auth_role && strcasecmp(auth_role, "Responder") == 0)
2362785afb44SJouni Malinen 		wpa_command(ifname, "DPP_CONTROLLER_STOP");
2363d86e5828SJouni Malinen 	dut->default_timeout = old_timeout;
236489cf6d64SJouni Malinen 	return STATUS_SENT;
23653aa72861SJouni Malinen err:
23663aa72861SJouni Malinen 	send_resp(dut, conn, SIGMA_ERROR, NULL);
23673aa72861SJouni Malinen 	goto out;
2368d86e5828SJouni Malinen }
2369d86e5828SJouni Malinen 
2370d86e5828SJouni Malinen 
237189cf6d64SJouni Malinen static enum sigma_cmd_result dpp_manual_dpp(struct sigma_dut *dut,
2372bc9e055cSSrinivas Dasari 					    struct sigma_conn *conn,
2373bc9e055cSSrinivas Dasari 					    struct sigma_cmd *cmd)
2374bc9e055cSSrinivas Dasari {
2375bc9e055cSSrinivas Dasari 	const char *auth_role = get_param(cmd, "DPPAuthRole");
23762fa651beSpriyadharshini gowthaman 	const char *self_conf = get_param(cmd, "DPPSelfConfigure");
237789cf6d64SJouni Malinen 	enum sigma_cmd_result res = INVALID_SEND_STATUS;
237889cf6d64SJouni Malinen 	int success;
2379bc9e055cSSrinivas Dasari 	const char *val;
2380bc9e055cSSrinivas Dasari 	unsigned int old_timeout;
2381ed629d51SJouni Malinen 	const char *bs = get_param(cmd, "DPPBS");
2382bc9e055cSSrinivas Dasari 
2383bc9e055cSSrinivas Dasari 	if (!auth_role) {
2384bc9e055cSSrinivas Dasari 		send_resp(dut, conn, SIGMA_ERROR,
2385bc9e055cSSrinivas Dasari 			  "errorCode,Missing DPPAuthRole");
238689cf6d64SJouni Malinen 		return STATUS_SENT_ERROR;
2387bc9e055cSSrinivas Dasari 	}
2388bc9e055cSSrinivas Dasari 
23892fa651beSpriyadharshini gowthaman 	if (!self_conf)
23902fa651beSpriyadharshini gowthaman 		self_conf = "no";
23912fa651beSpriyadharshini gowthaman 
2392bc9e055cSSrinivas Dasari 	old_timeout = dut->default_timeout;
2393bc9e055cSSrinivas Dasari 	val = get_param(cmd, "DPPTimeout");
2394bc9e055cSSrinivas Dasari 	if (val && atoi(val) > 0) {
2395bc9e055cSSrinivas Dasari 		dut->default_timeout = atoi(val);
2396bc9e055cSSrinivas Dasari 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u",
2397bc9e055cSSrinivas Dasari 				dut->default_timeout);
2398bc9e055cSSrinivas Dasari 	}
2399bc9e055cSSrinivas Dasari 
2400ed629d51SJouni Malinen 	if (strcasecmp(bs, "NFC") == 0) {
2401ed629d51SJouni Malinen 		res = dpp_automatic_dpp(dut, conn, cmd);
2402ed629d51SJouni Malinen 		goto out;
2403ed629d51SJouni Malinen 	}
2404ed629d51SJouni Malinen 
2405bc9e055cSSrinivas Dasari 	res = dpp_get_local_bootstrap(dut, conn, cmd, 0, &success);
240689cf6d64SJouni Malinen 	if (res != STATUS_SENT || !success)
2407bc9e055cSSrinivas Dasari 		goto out;
2408bc9e055cSSrinivas Dasari 
2409bc9e055cSSrinivas Dasari 	if (strcasecmp(auth_role, "Responder") == 0) {
241089cf6d64SJouni Malinen 		if (dpp_display_own_qrcode(dut) < 0) {
241189cf6d64SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
241289cf6d64SJouni Malinen 				  "errorCode,Failed to display own QR code");
241389cf6d64SJouni Malinen 			res = STATUS_SENT_ERROR;
2414bc9e055cSSrinivas Dasari 			goto out;
241589cf6d64SJouni Malinen 		}
2416bc9e055cSSrinivas Dasari 
2417bc9e055cSSrinivas Dasari 		res = dpp_automatic_dpp(dut, conn, cmd);
2418bc9e055cSSrinivas Dasari 		goto out;
2419bc9e055cSSrinivas Dasari 	}
2420bc9e055cSSrinivas Dasari 
2421bc9e055cSSrinivas Dasari 	if (strcasecmp(auth_role, "Initiator") == 0) {
24222fa651beSpriyadharshini gowthaman 		if (strcasecmp(self_conf, "Yes") != 0) {
242389cf6d64SJouni Malinen 			if (dpp_scan_peer_qrcode(dut) < 0) {
24241a38cc37SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
24251a38cc37SJouni Malinen 					  "errorCode,Failed to scan peer QR Code");
242689cf6d64SJouni Malinen 				res = STATUS_SENT_ERROR;
2427bc9e055cSSrinivas Dasari 				goto out;
24281a38cc37SJouni Malinen 			}
24292fa651beSpriyadharshini gowthaman 		}
2430bc9e055cSSrinivas Dasari 
2431bc9e055cSSrinivas Dasari 		res = dpp_automatic_dpp(dut, conn, cmd);
2432bc9e055cSSrinivas Dasari 		goto out;
2433bc9e055cSSrinivas Dasari 	}
2434bc9e055cSSrinivas Dasari 
2435bc9e055cSSrinivas Dasari 	send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unknown DPPAuthRole");
243689cf6d64SJouni Malinen 	res = STATUS_SENT_ERROR;
2437bc9e055cSSrinivas Dasari out:
2438bc9e055cSSrinivas Dasari 	dut->default_timeout = old_timeout;
2439bc9e055cSSrinivas Dasari 	return res;
2440bc9e055cSSrinivas Dasari }
2441bc9e055cSSrinivas Dasari 
2442bc9e055cSSrinivas Dasari 
244389cf6d64SJouni Malinen enum sigma_cmd_result dpp_dev_exec_action(struct sigma_dut *dut,
244489cf6d64SJouni Malinen 					  struct sigma_conn *conn,
2445d86e5828SJouni Malinen 					  struct sigma_cmd *cmd)
2446d86e5828SJouni Malinen {
2447d86e5828SJouni Malinen 	const char *type = get_param(cmd, "DPPActionType");
2448d86e5828SJouni Malinen 	const char *bs = get_param(cmd, "DPPBS");
2449d86e5828SJouni Malinen 
2450d86e5828SJouni Malinen 	if (!bs) {
2451d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
2452d86e5828SJouni Malinen 			  "errorCode,Missing DPPBS");
245389cf6d64SJouni Malinen 		return STATUS_SENT_ERROR;
2454d86e5828SJouni Malinen 	}
2455d86e5828SJouni Malinen 
2456d86e5828SJouni Malinen 	if (!type) {
2457d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
2458d86e5828SJouni Malinen 			  "errorCode,Missing DPPActionType");
245989cf6d64SJouni Malinen 		return STATUS_SENT_ERROR;
2460d86e5828SJouni Malinen 	}
2461d86e5828SJouni Malinen 
2462d86e5828SJouni Malinen 	if (strcasecmp(type, "GetLocalBootstrap") == 0)
2463bc9e055cSSrinivas Dasari 		return dpp_get_local_bootstrap(dut, conn, cmd, 1, NULL);
2464d86e5828SJouni Malinen 	if (strcasecmp(type, "SetPeerBootstrap") == 0)
2465d86e5828SJouni Malinen 		return dpp_set_peer_bootstrap(dut, conn, cmd);
2466d86e5828SJouni Malinen 	if (strcasecmp(type, "ManualDPP") == 0)
2467d86e5828SJouni Malinen 		return dpp_manual_dpp(dut, conn, cmd);
2468d86e5828SJouni Malinen 	if (strcasecmp(type, "AutomaticDPP") == 0)
2469d86e5828SJouni Malinen 		return dpp_automatic_dpp(dut, conn, cmd);
2470d86e5828SJouni Malinen 
2471d86e5828SJouni Malinen 	send_resp(dut, conn, SIGMA_ERROR,
2472d86e5828SJouni Malinen 		  "errorCode,Unsupported DPPActionType");
247389cf6d64SJouni Malinen 	return STATUS_SENT_ERROR;
2474d86e5828SJouni Malinen }
2475