1cd4e3c3eSJouni Malinen /*
2cd4e3c3eSJouni Malinen * Sigma Control API DUT (station/AP/sniffer)
39c381f59SAmarnath Hullur Subramanyam * Copyright (c) 2011-2013, 2017, Qualcomm Atheros, Inc.
4a0bf244dSJouni Malinen * Copyright (c) 2018-2019, The Linux Foundation
5cd4e3c3eSJouni Malinen * All Rights Reserved.
6cd4e3c3eSJouni Malinen * Licensed under the Clear BSD license. See README for more details.
7cd4e3c3eSJouni Malinen */
8cd4e3c3eSJouni Malinen
9cd4e3c3eSJouni Malinen #include "sigma_dut.h"
100128bf99SKiran Kumar Lokere #include <ctype.h>
119c381f59SAmarnath Hullur Subramanyam #include "miracast.h"
122052daa2SAnurag Das #include <sys/wait.h>
132052daa2SAnurag Das #include "wpa_ctrl.h"
142052daa2SAnurag Das #include "wpa_helpers.h"
15cd4e3c3eSJouni Malinen
16cd4e3c3eSJouni Malinen
17fee3c4adSJouni Malinen extern char *sigma_cert_path;
18fee3c4adSJouni Malinen
19fee3c4adSJouni Malinen
cmd_dev_send_frame(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)20a0bf244dSJouni Malinen static enum sigma_cmd_result cmd_dev_send_frame(struct sigma_dut *dut,
21a0bf244dSJouni Malinen struct sigma_conn *conn,
22cd4e3c3eSJouni Malinen struct sigma_cmd *cmd)
23cd4e3c3eSJouni Malinen {
249c381f59SAmarnath Hullur Subramanyam #ifdef MIRACAST
259c381f59SAmarnath Hullur Subramanyam const char *program = get_param(cmd, "Program");
269c381f59SAmarnath Hullur Subramanyam
279c381f59SAmarnath Hullur Subramanyam if (program && (strcasecmp(program, "WFD") == 0 ||
289c381f59SAmarnath Hullur Subramanyam strcasecmp(program, "DisplayR2") == 0))
299c381f59SAmarnath Hullur Subramanyam return miracast_dev_send_frame(dut, conn, cmd);
309c381f59SAmarnath Hullur Subramanyam #endif /* MIRACAST */
319c381f59SAmarnath Hullur Subramanyam
32cd4e3c3eSJouni Malinen if (dut->mode == SIGMA_MODE_STATION ||
33cd4e3c3eSJouni Malinen dut->mode == SIGMA_MODE_UNKNOWN) {
34cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert "
35cd4e3c3eSJouni Malinen "dev_send_frame to sta_send_frame");
36cd4e3c3eSJouni Malinen return cmd_sta_send_frame(dut, conn, cmd);
37cd4e3c3eSJouni Malinen }
38cd4e3c3eSJouni Malinen
39cd4e3c3eSJouni Malinen if (dut->mode == SIGMA_MODE_AP) {
40cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert "
41cd4e3c3eSJouni Malinen "dev_send_frame to ap_send_frame");
42cd4e3c3eSJouni Malinen return cmd_ap_send_frame(dut, conn, cmd);
43cd4e3c3eSJouni Malinen }
44cd4e3c3eSJouni Malinen
45cd4e3c3eSJouni Malinen #ifdef CONFIG_WLANTEST
46cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert dev_send_frame to "
47cd4e3c3eSJouni Malinen "wlantest_send_frame");
48cd4e3c3eSJouni Malinen return cmd_wlantest_send_frame(dut, conn, cmd);
49cd4e3c3eSJouni Malinen #else /* CONFIG_WLANTEST */
50cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_ERROR,
51cd4e3c3eSJouni Malinen "errorCode,Unsupported dev_send_frame");
52a0bf244dSJouni Malinen return STATUS_SENT;
53cd4e3c3eSJouni Malinen #endif /* CONFIG_WLANTEST */
54cd4e3c3eSJouni Malinen }
55cd4e3c3eSJouni Malinen
56cd4e3c3eSJouni Malinen
cmd_dev_set_parameter(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)57a0bf244dSJouni Malinen static enum sigma_cmd_result cmd_dev_set_parameter(struct sigma_dut *dut,
58a0bf244dSJouni Malinen struct sigma_conn *conn,
59cd4e3c3eSJouni Malinen struct sigma_cmd *cmd)
60cd4e3c3eSJouni Malinen {
61cd4e3c3eSJouni Malinen const char *device = get_param(cmd, "Device");
62cd4e3c3eSJouni Malinen
63cd4e3c3eSJouni Malinen if (device && strcasecmp(device, "STA") == 0) {
64cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert "
65cd4e3c3eSJouni Malinen "dev_set_parameter to sta_set_parameter");
66cd4e3c3eSJouni Malinen return cmd_sta_set_parameter(dut, conn, cmd);
67cd4e3c3eSJouni Malinen }
68cd4e3c3eSJouni Malinen
69a0bf244dSJouni Malinen return INVALID_SEND_STATUS;
70cd4e3c3eSJouni Malinen }
71cd4e3c3eSJouni Malinen
72cd4e3c3eSJouni Malinen
sta_server_cert_trust(struct sigma_dut * dut,struct sigma_conn * conn,const char * val)73134fe3c3SJouni Malinen static enum sigma_cmd_result sta_server_cert_trust(struct sigma_dut *dut,
74134fe3c3SJouni Malinen struct sigma_conn *conn,
75134fe3c3SJouni Malinen const char *val)
76134fe3c3SJouni Malinen {
77fee3c4adSJouni Malinen char buf[200];
78134fe3c3SJouni Malinen struct wpa_ctrl *ctrl = NULL;
79134fe3c3SJouni Malinen int e;
80134fe3c3SJouni Malinen char resp[200];
81134fe3c3SJouni Malinen int num_disconnected = 0;
821f81e2d4SJouni Malinen int tod = -1;
83134fe3c3SJouni Malinen
84134fe3c3SJouni Malinen strlcpy(resp, "ServerCertTrustResult,Accepted", sizeof(resp));
85134fe3c3SJouni Malinen
866a3005feSJouni Malinen if (strcasecmp(val, "Accept") != 0 && strcasecmp(val, "Reject") != 0) {
876a3005feSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO,
886a3005feSJouni Malinen "Unknown ServerCertTrust value '%s'", val);
896a3005feSJouni Malinen return INVALID_SEND_STATUS;
90134fe3c3SJouni Malinen }
91134fe3c3SJouni Malinen
92fee3c4adSJouni Malinen snprintf(buf, sizeof(buf), "%s/uosc-disabled", sigma_cert_path);
93fee3c4adSJouni Malinen if (file_exists(buf)) {
94fee3c4adSJouni Malinen strlcpy(resp,
95fee3c4adSJouni Malinen "ServerCertTrustResult,OverrideNotAllowed,Reason,UOSC disabled on device",
96fee3c4adSJouni Malinen sizeof(resp));
97fee3c4adSJouni Malinen goto done;
98fee3c4adSJouni Malinen }
99fee3c4adSJouni Malinen
100134fe3c3SJouni Malinen if (!dut->server_cert_hash[0]) {
101134fe3c3SJouni Malinen strlcpy(resp,
1026a3005feSJouni Malinen "ServerCertTrustResult,OverrideNotAllowed,Reason,No server certificate stored",
103134fe3c3SJouni Malinen sizeof(resp));
104134fe3c3SJouni Malinen goto done;
105134fe3c3SJouni Malinen }
106134fe3c3SJouni Malinen
107134fe3c3SJouni Malinen if (dut->sta_tod_policy) {
108134fe3c3SJouni Malinen strlcpy(resp,
1096a3005feSJouni Malinen "ServerCertTrustResult,OverrideNotAllowed,Reason,TOD policy",
110134fe3c3SJouni Malinen sizeof(resp));
111134fe3c3SJouni Malinen goto done;
112134fe3c3SJouni Malinen }
113134fe3c3SJouni Malinen
11437d5c69eSJouni Malinen if (dut->server_cert_tod == 1) {
11537d5c69eSJouni Malinen strlcpy(resp,
11637d5c69eSJouni Malinen "ServerCertTrustResult,OverrideNotAllowed,Reason,TOD-STRICT policy in received server certificate",
11737d5c69eSJouni Malinen sizeof(resp));
11837d5c69eSJouni Malinen goto done;
11937d5c69eSJouni Malinen }
12037d5c69eSJouni Malinen
1216a3005feSJouni Malinen if (strcasecmp(val, "Accept") != 0) {
1226a3005feSJouni Malinen strlcpy(resp, "ServerCertTrustResult,Rejected", sizeof(resp));
1236a3005feSJouni Malinen goto done;
1246a3005feSJouni Malinen }
1256a3005feSJouni Malinen
126134fe3c3SJouni Malinen snprintf(buf, sizeof(buf), "hash://server/sha256/%s",
127134fe3c3SJouni Malinen dut->server_cert_hash);
128016ae6c8SJouni Malinen if (set_network_quoted(get_station_ifname(dut), dut->infra_network_id,
129134fe3c3SJouni Malinen "ca_cert", buf) < 0) {
130134fe3c3SJouni Malinen strlcpy(resp,
1316a3005feSJouni Malinen "ServerCertTrustResult,OverrideNotAllowed,Reason,Could not configure server certificate hash for the network profile",
132134fe3c3SJouni Malinen sizeof(resp));
133134fe3c3SJouni Malinen goto done;
134134fe3c3SJouni Malinen }
135134fe3c3SJouni Malinen
136016ae6c8SJouni Malinen if (set_network(get_station_ifname(dut), dut->infra_network_id,
137560e4a97SJouni Malinen "domain_match", "NULL") < 0 ||
138016ae6c8SJouni Malinen set_network(get_station_ifname(dut), dut->infra_network_id,
139560e4a97SJouni Malinen "domain_suffix_match", "NULL") < 0) {
140560e4a97SJouni Malinen strlcpy(resp,
141560e4a97SJouni Malinen "ServerCertTrustResult,OverrideNotAllowed,Reason,Could not clear domain matching rules",
142560e4a97SJouni Malinen sizeof(resp));
143560e4a97SJouni Malinen goto done;
144560e4a97SJouni Malinen }
145560e4a97SJouni Malinen
146016ae6c8SJouni Malinen wpa_command(get_station_ifname(dut), "DISCONNECT");
147134fe3c3SJouni Malinen snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", dut->infra_network_id);
148016ae6c8SJouni Malinen if (wpa_command(get_station_ifname(dut), buf) < 0) {
149134fe3c3SJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
150134fe3c3SJouni Malinen "network id %d on %s",
151134fe3c3SJouni Malinen dut->infra_network_id,
152016ae6c8SJouni Malinen get_station_ifname(dut));
153134fe3c3SJouni Malinen strlcpy(resp,
154134fe3c3SJouni Malinen "ServerCertTrustResult,Accepted,Result,Could not request reconnection",
155134fe3c3SJouni Malinen sizeof(resp));
156134fe3c3SJouni Malinen goto done;
157134fe3c3SJouni Malinen }
158134fe3c3SJouni Malinen
159016ae6c8SJouni Malinen ctrl = open_wpa_mon(get_station_ifname(dut));
160134fe3c3SJouni Malinen if (!ctrl)
161134fe3c3SJouni Malinen goto done;
162134fe3c3SJouni Malinen
163134fe3c3SJouni Malinen for (e = 0; e < 20; e++) {
164134fe3c3SJouni Malinen const char *events[] = {
1651f81e2d4SJouni Malinen "CTRL-EVENT-EAP-PEER-CERT",
166134fe3c3SJouni Malinen "CTRL-EVENT-EAP-TLS-CERT-ERROR",
167134fe3c3SJouni Malinen "CTRL-EVENT-DISCONNECTED",
168134fe3c3SJouni Malinen "CTRL-EVENT-CONNECTED",
169134fe3c3SJouni Malinen NULL
170134fe3c3SJouni Malinen };
171134fe3c3SJouni Malinen char buf[1024];
172134fe3c3SJouni Malinen int res;
173134fe3c3SJouni Malinen
174134fe3c3SJouni Malinen res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
175134fe3c3SJouni Malinen if (res < 0) {
176134fe3c3SJouni Malinen strlcpy(resp,
177134fe3c3SJouni Malinen "ServerCertTrustResult,Accepted,Result,Association did not complete",
178134fe3c3SJouni Malinen sizeof(resp));
179134fe3c3SJouni Malinen goto done;
180134fe3c3SJouni Malinen }
181134fe3c3SJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
182134fe3c3SJouni Malinen buf);
183134fe3c3SJouni Malinen
1841f81e2d4SJouni Malinen
1851f81e2d4SJouni Malinen if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
1861f81e2d4SJouni Malinen strstr(buf, " depth=0")) {
1871f81e2d4SJouni Malinen char *pos = strstr(buf, " hash=");
1881f81e2d4SJouni Malinen
1891f81e2d4SJouni Malinen if (pos) {
1901f81e2d4SJouni Malinen if (strstr(buf, " tod=1"))
1911f81e2d4SJouni Malinen tod = 1;
1921f81e2d4SJouni Malinen else if (strstr(buf, " tod=2"))
1931f81e2d4SJouni Malinen tod = 2;
1941f81e2d4SJouni Malinen else
1951f81e2d4SJouni Malinen tod = 0;
1961f81e2d4SJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG,
1971f81e2d4SJouni Malinen "Server certificate TOD policy: %d",
1981f81e2d4SJouni Malinen tod);
1991f81e2d4SJouni Malinen dut->server_cert_tod = tod;
2001f81e2d4SJouni Malinen }
2011f81e2d4SJouni Malinen }
2021f81e2d4SJouni Malinen
203134fe3c3SJouni Malinen if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
204134fe3c3SJouni Malinen strlcpy(resp,
2056a3005feSJouni Malinen "ServerCertTrustResult,Accepted,Result,TLS server certificate validation failed with updated profile",
206134fe3c3SJouni Malinen sizeof(resp));
207134fe3c3SJouni Malinen goto done;
208134fe3c3SJouni Malinen }
209134fe3c3SJouni Malinen
210134fe3c3SJouni Malinen if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
211134fe3c3SJouni Malinen num_disconnected++;
212134fe3c3SJouni Malinen
213134fe3c3SJouni Malinen if (num_disconnected > 2) {
214134fe3c3SJouni Malinen strlcpy(resp,
215134fe3c3SJouni Malinen "ServerCertTrustResult,Accepted,Result,Connection failed",
216134fe3c3SJouni Malinen sizeof(resp));
217134fe3c3SJouni Malinen goto done;
218134fe3c3SJouni Malinen }
219134fe3c3SJouni Malinen }
220134fe3c3SJouni Malinen
221134fe3c3SJouni Malinen if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
2221f81e2d4SJouni Malinen if (tod >= 0) {
2231f81e2d4SJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG,
2241f81e2d4SJouni Malinen "Network profile TOD policy update: %d -> %d",
2251f81e2d4SJouni Malinen dut->sta_tod_policy, tod);
2261f81e2d4SJouni Malinen dut->sta_tod_policy = tod;
2271f81e2d4SJouni Malinen }
228134fe3c3SJouni Malinen strlcpy(resp,
229134fe3c3SJouni Malinen "ServerCertTrustResult,Accepted,Result,Connected",
230134fe3c3SJouni Malinen sizeof(resp));
231134fe3c3SJouni Malinen break;
232134fe3c3SJouni Malinen }
233134fe3c3SJouni Malinen }
234134fe3c3SJouni Malinen
235134fe3c3SJouni Malinen done:
236134fe3c3SJouni Malinen if (ctrl) {
237134fe3c3SJouni Malinen wpa_ctrl_detach(ctrl);
238134fe3c3SJouni Malinen wpa_ctrl_close(ctrl);
239134fe3c3SJouni Malinen }
240134fe3c3SJouni Malinen
241134fe3c3SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, resp);
242134fe3c3SJouni Malinen return STATUS_SENT;
243134fe3c3SJouni Malinen }
244134fe3c3SJouni Malinen
245134fe3c3SJouni Malinen
dev_exec_key_rotation(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)246*314b9c65SJouni Malinen static enum sigma_cmd_result dev_exec_key_rotation(struct sigma_dut *dut,
247*314b9c65SJouni Malinen struct sigma_conn *conn,
248*314b9c65SJouni Malinen struct sigma_cmd *cmd)
249*314b9c65SJouni Malinen {
250*314b9c65SJouni Malinen if (dut->mode == SIGMA_MODE_AP ||
251*314b9c65SJouni Malinen dut->mode == SIGMA_MODE_UNKNOWN) {
252*314b9c65SJouni Malinen const char *ifname;
253*314b9c65SJouni Malinen
254*314b9c65SJouni Malinen ifname = get_hostapd_ifname(dut);
255*314b9c65SJouni Malinen if (hapd_command(ifname, "REKEY_GTK") < 0) {
256*314b9c65SJouni Malinen send_resp(dut, conn, SIGMA_ERROR,
257*314b9c65SJouni Malinen "errorCode,Failed to request hostapd to rekey GTK");
258*314b9c65SJouni Malinen return STATUS_SENT_ERROR;
259*314b9c65SJouni Malinen }
260*314b9c65SJouni Malinen return SUCCESS_SEND_STATUS;
261*314b9c65SJouni Malinen } else if (dut->mode == SIGMA_MODE_STATION) {
262*314b9c65SJouni Malinen const char *intf = get_param(cmd, "Interface");
263*314b9c65SJouni Malinen
264*314b9c65SJouni Malinen if (!intf)
265*314b9c65SJouni Malinen intf = get_main_ifname(dut);
266*314b9c65SJouni Malinen if (wpa_command(intf, "KEY_REQUEST 0 0") != 0) {
267*314b9c65SJouni Malinen send_resp(dut, conn, SIGMA_ERROR,
268*314b9c65SJouni Malinen "errorCode,Failed to request wpa_supplicant to request AP to rekey GTK");
269*314b9c65SJouni Malinen return STATUS_SENT_ERROR;
270*314b9c65SJouni Malinen }
271*314b9c65SJouni Malinen return SUCCESS_SEND_STATUS;
272*314b9c65SJouni Malinen } else {
273*314b9c65SJouni Malinen send_resp(dut, conn, SIGMA_ERROR,
274*314b9c65SJouni Malinen "errorCode,Unsupported mode for KeyRotation,1");
275*314b9c65SJouni Malinen return STATUS_SENT_ERROR;
276*314b9c65SJouni Malinen }
277*314b9c65SJouni Malinen }
278*314b9c65SJouni Malinen
279*314b9c65SJouni Malinen
wpa3_dev_exec_action(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)28019d52a70SJouni Malinen static enum sigma_cmd_result wpa3_dev_exec_action(struct sigma_dut *dut,
28119d52a70SJouni Malinen struct sigma_conn *conn,
28219d52a70SJouni Malinen struct sigma_cmd *cmd)
28319d52a70SJouni Malinen {
28419d52a70SJouni Malinen const char *val;
28519d52a70SJouni Malinen char buf[4000], buf2[100], *pos, *end;
28619d52a70SJouni Malinen
28719d52a70SJouni Malinen val = get_param(cmd, "Rejected_DH_Groups");
28819d52a70SJouni Malinen if (val) {
28919d52a70SJouni Malinen val = get_param(cmd, "Dest_MAC");
29019d52a70SJouni Malinen if (!val)
29119d52a70SJouni Malinen return ERROR_SEND_STATUS;
29219d52a70SJouni Malinen snprintf(buf2, sizeof(buf2), "STA %s", val);
29319d52a70SJouni Malinen if (wpa_command_resp(dut->hostapd_ifname, buf2,
29419d52a70SJouni Malinen buf, sizeof(buf)) < 0)
29519d52a70SJouni Malinen return ERROR_SEND_STATUS;
29619d52a70SJouni Malinen pos = buf;
29719d52a70SJouni Malinen while (pos) {
29819d52a70SJouni Malinen if (strncmp(pos, "sae_rejected_groups=", 20) == 0)
29919d52a70SJouni Malinen break;
30019d52a70SJouni Malinen pos = strchr(pos, '\n');
30119d52a70SJouni Malinen if (pos)
30219d52a70SJouni Malinen pos++;
30319d52a70SJouni Malinen }
30419d52a70SJouni Malinen if (pos) {
30519d52a70SJouni Malinen pos += 20;
30619d52a70SJouni Malinen end = strchr(pos, '\n');
30719d52a70SJouni Malinen if (end)
30819d52a70SJouni Malinen *end = '\0';
30919d52a70SJouni Malinen }
31019d52a70SJouni Malinen snprintf(buf2, sizeof(buf2), "DHGroupVerResult,%s",
31119d52a70SJouni Malinen pos ? pos : "");
31219d52a70SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, buf2);
31319d52a70SJouni Malinen return STATUS_SENT;
31419d52a70SJouni Malinen }
31519d52a70SJouni Malinen
316*314b9c65SJouni Malinen val = get_param(cmd, "KeyRotation");
317*314b9c65SJouni Malinen if (val && atoi(val) == 1)
318*314b9c65SJouni Malinen return dev_exec_key_rotation(dut, conn, cmd);
319*314b9c65SJouni Malinen
32019d52a70SJouni Malinen return ERROR_SEND_STATUS;
32119d52a70SJouni Malinen }
32219d52a70SJouni Malinen
32319d52a70SJouni Malinen
cmd_dev_exec_action(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)324a0bf244dSJouni Malinen static enum sigma_cmd_result cmd_dev_exec_action(struct sigma_dut *dut,
325a0bf244dSJouni Malinen struct sigma_conn *conn,
3269c381f59SAmarnath Hullur Subramanyam struct sigma_cmd *cmd)
3279c381f59SAmarnath Hullur Subramanyam {
3289c381f59SAmarnath Hullur Subramanyam const char *program = get_param(cmd, "Program");
329134fe3c3SJouni Malinen const char *val;
3309c381f59SAmarnath Hullur Subramanyam
331d86e5828SJouni Malinen #ifdef MIRACAST
3329c381f59SAmarnath Hullur Subramanyam if (program && (strcasecmp(program, "WFD") == 0 ||
333d86e5828SJouni Malinen strcasecmp(program, "DisplayR2") == 0)) {
334d86e5828SJouni Malinen if (get_param(cmd, "interface") == NULL)
335a0bf244dSJouni Malinen return INVALID_SEND_STATUS;
3369c381f59SAmarnath Hullur Subramanyam return miracast_dev_exec_action(dut, conn, cmd);
337d86e5828SJouni Malinen }
3389c381f59SAmarnath Hullur Subramanyam #endif /* MIRACAST */
3399c381f59SAmarnath Hullur Subramanyam
340d86e5828SJouni Malinen if (program && strcasecmp(program, "DPP") == 0)
341d86e5828SJouni Malinen return dpp_dev_exec_action(dut, conn, cmd);
342d86e5828SJouni Malinen
343134fe3c3SJouni Malinen val = get_param(cmd, "ServerCertTrust");
344134fe3c3SJouni Malinen if (val)
345134fe3c3SJouni Malinen return sta_server_cert_trust(dut, conn, val);
346134fe3c3SJouni Malinen
34719d52a70SJouni Malinen if (program && strcasecmp(program, "WPA3") == 0)
34819d52a70SJouni Malinen return wpa3_dev_exec_action(dut, conn, cmd);
34919d52a70SJouni Malinen
350a0bf244dSJouni Malinen return ERROR_SEND_STATUS;
3519c381f59SAmarnath Hullur Subramanyam }
3529c381f59SAmarnath Hullur Subramanyam
3539c381f59SAmarnath Hullur Subramanyam
cmd_dev_configure_ie(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)354a0bf244dSJouni Malinen static enum sigma_cmd_result cmd_dev_configure_ie(struct sigma_dut *dut,
355a0bf244dSJouni Malinen struct sigma_conn *conn,
3563c367e8dSJouni Malinen struct sigma_cmd *cmd)
3573c367e8dSJouni Malinen {
3583c367e8dSJouni Malinen const char *ie_name = get_param(cmd, "IE_Name");
3593c367e8dSJouni Malinen const char *contents = get_param(cmd, "Contents");
3603c367e8dSJouni Malinen
3613c367e8dSJouni Malinen if (!ie_name || !contents)
362a0bf244dSJouni Malinen return INVALID_SEND_STATUS;
3633c367e8dSJouni Malinen
3643c367e8dSJouni Malinen if (strcasecmp(ie_name, "RSNE") != 0) {
3653c367e8dSJouni Malinen send_resp(dut, conn, SIGMA_ERROR,
3663c367e8dSJouni Malinen "errorCode,Unsupported IE_Name value");
367a0bf244dSJouni Malinen return STATUS_SENT;
3683c367e8dSJouni Malinen }
3693c367e8dSJouni Malinen
3703c367e8dSJouni Malinen free(dut->rsne_override);
3713c367e8dSJouni Malinen dut->rsne_override = strdup(contents);
3723c367e8dSJouni Malinen
373a0bf244dSJouni Malinen return dut->rsne_override ? SUCCESS_SEND_STATUS : ERROR_SEND_STATUS;
3743c367e8dSJouni Malinen }
3753c367e8dSJouni Malinen
3763c367e8dSJouni Malinen
cmd_dev_ble_action(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)377a0bf244dSJouni Malinen static enum sigma_cmd_result cmd_dev_ble_action(struct sigma_dut *dut,
378a0bf244dSJouni Malinen struct sigma_conn *conn,
3792052daa2SAnurag Das struct sigma_cmd *cmd)
3802052daa2SAnurag Das {
3812052daa2SAnurag Das #ifdef ANDROID
3822052daa2SAnurag Das const char *ble_op = get_param(cmd, "BLEOp");
3832052daa2SAnurag Das const char *prog = get_param(cmd, "Prog");
3842052daa2SAnurag Das const char *service_name = get_param(cmd, "ServiceName");
3852052daa2SAnurag Das const char *ble_role = get_param(cmd, "BLERole");
3862052daa2SAnurag Das const char *discovery_type = get_param(cmd, "DiscoveryType");
3872052daa2SAnurag Das const char *msg_type = get_param(cmd, "messagetype");
3882052daa2SAnurag Das const char *action = get_param(cmd, "action");
3892052daa2SAnurag Das const char *M2Transmit = get_param(cmd, "M2Transmit");
3902052daa2SAnurag Das char *argv[17];
3912052daa2SAnurag Das pid_t pid;
3922052daa2SAnurag Das
3932052daa2SAnurag Das if (prog && ble_role && action && msg_type) {
3942052daa2SAnurag Das send_resp(dut, conn, SIGMA_COMPLETE,
3952052daa2SAnurag Das "OrgID,0x00,TransDataHeader,0x00,BloomFilterElement,NULL");
396a0bf244dSJouni Malinen return STATUS_SENT;
3972052daa2SAnurag Das }
3982052daa2SAnurag Das if (!ble_op || !prog || !service_name || !ble_role || !discovery_type) {
3992052daa2SAnurag Das sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid arguments");
400a0bf244dSJouni Malinen return INVALID_SEND_STATUS;
4012052daa2SAnurag Das }
4022052daa2SAnurag Das
4032052daa2SAnurag Das if ((strcasecmp(prog, "NAN") != 0)) {
4042052daa2SAnurag Das sigma_dut_print(dut, DUT_MSG_ERROR, "Program %s not supported",
4052052daa2SAnurag Das prog);
406a0bf244dSJouni Malinen return INVALID_SEND_STATUS;
4072052daa2SAnurag Das }
4082052daa2SAnurag Das
4092052daa2SAnurag Das if (strcasecmp(ble_role, "seeker") != 0 &&
4102052daa2SAnurag Das strcasecmp(ble_role, "provider") != 0 &&
4112052daa2SAnurag Das strcasecmp(ble_role, "browser") != 0) {
4122052daa2SAnurag Das sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid BLERole: %s",
4132052daa2SAnurag Das ble_role);
414a0bf244dSJouni Malinen return INVALID_SEND_STATUS;
4152052daa2SAnurag Das }
4162052daa2SAnurag Das
4172052daa2SAnurag Das if (strcasecmp(discovery_type, "active") != 0 &&
4182052daa2SAnurag Das strcasecmp(discovery_type, "passive") != 0) {
4192052daa2SAnurag Das sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid DiscoveryType: %s",
4202052daa2SAnurag Das discovery_type);
421a0bf244dSJouni Malinen return INVALID_SEND_STATUS;
4222052daa2SAnurag Das }
4232052daa2SAnurag Das
4242052daa2SAnurag Das if (!M2Transmit)
4252052daa2SAnurag Das M2Transmit = "disable";
4262052daa2SAnurag Das
4272052daa2SAnurag Das argv[0] = "am";
4282052daa2SAnurag Das argv[1] = "start";
4292052daa2SAnurag Das argv[2] = "-n";
4302052daa2SAnurag Das argv[3] = "org.codeaurora.nanservicediscovery/org.codeaurora.nanservicediscovery.MainActivity";
4312052daa2SAnurag Das argv[4] = "--es";
4322052daa2SAnurag Das argv[5] = "service";
4332052daa2SAnurag Das argv[6] = (char *) service_name;
4342052daa2SAnurag Das argv[7] = "--es";
4352052daa2SAnurag Das argv[8] = "role";
4362052daa2SAnurag Das argv[9] = (char *) ble_role;
4372052daa2SAnurag Das argv[10] = "--es";
4382052daa2SAnurag Das argv[11] = "scantype";
4392052daa2SAnurag Das argv[12] = (char *) discovery_type;
4402052daa2SAnurag Das argv[13] = "--es";
4412052daa2SAnurag Das argv[14] = "M2Transmit";
4422052daa2SAnurag Das argv[15] = (char *) M2Transmit;
4432052daa2SAnurag Das argv[16] = NULL;
4442052daa2SAnurag Das
4452052daa2SAnurag Das pid = fork();
4462052daa2SAnurag Das if (pid == -1) {
4472052daa2SAnurag Das sigma_dut_print(dut, DUT_MSG_ERROR, "fork: %s",
4482052daa2SAnurag Das strerror(errno));
449a0bf244dSJouni Malinen return ERROR_SEND_STATUS;
4502052daa2SAnurag Das }
4512052daa2SAnurag Das
4522052daa2SAnurag Das if (pid == 0) {
4532052daa2SAnurag Das execv("/system/bin/am", argv);
4542052daa2SAnurag Das sigma_dut_print(dut, DUT_MSG_ERROR, "execv: %s",
4552052daa2SAnurag Das strerror(errno));
4562052daa2SAnurag Das exit(0);
457a0bf244dSJouni Malinen return ERROR_SEND_STATUS;
4582052daa2SAnurag Das }
4592052daa2SAnurag Das
4602052daa2SAnurag Das dut->nanservicediscoveryinprogress = 1;
4612052daa2SAnurag Das #endif /* ANDROID */
4622052daa2SAnurag Das
463a0bf244dSJouni Malinen return SUCCESS_SEND_STATUS;
4642052daa2SAnurag Das }
4652052daa2SAnurag Das
4662052daa2SAnurag Das
4670128bf99SKiran Kumar Lokere /* Runtime ID must contain only numbers */
is_runtime_id_valid(struct sigma_dut * dut,const char * val)4680128bf99SKiran Kumar Lokere static int is_runtime_id_valid(struct sigma_dut *dut, const char *val)
4690128bf99SKiran Kumar Lokere {
4700128bf99SKiran Kumar Lokere int i;
4710128bf99SKiran Kumar Lokere
4720128bf99SKiran Kumar Lokere for (i = 0; val[i] != '\0'; i++) {
4730128bf99SKiran Kumar Lokere if (!isdigit(val[i])) {
4740128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_DEBUG,
4750128bf99SKiran Kumar Lokere "Invalid Runtime_ID %s", val);
4760128bf99SKiran Kumar Lokere return 0;
4770128bf99SKiran Kumar Lokere }
4780128bf99SKiran Kumar Lokere }
4790128bf99SKiran Kumar Lokere
4800128bf99SKiran Kumar Lokere return 1;
4810128bf99SKiran Kumar Lokere }
4820128bf99SKiran Kumar Lokere
4830128bf99SKiran Kumar Lokere
build_log_dir(struct sigma_dut * dut,char * dir,size_t dir_size)4840128bf99SKiran Kumar Lokere static int build_log_dir(struct sigma_dut *dut, char *dir, size_t dir_size)
4850128bf99SKiran Kumar Lokere {
4860128bf99SKiran Kumar Lokere int res;
487ce791a3dSJouni Malinen const char *vendor = dut->vendor_name;
4880128bf99SKiran Kumar Lokere int i;
4890128bf99SKiran Kumar Lokere
490ce791a3dSJouni Malinen if (!vendor)
491ce791a3dSJouni Malinen return -1;
4920128bf99SKiran Kumar Lokere
4930128bf99SKiran Kumar Lokere if (dut->log_file_dir) {
4940128bf99SKiran Kumar Lokere res = snprintf(dir, dir_size, "%s/%s", dut->log_file_dir,
4950128bf99SKiran Kumar Lokere vendor);
4960128bf99SKiran Kumar Lokere } else {
4970128bf99SKiran Kumar Lokere #ifdef ANDROID
4980128bf99SKiran Kumar Lokere res = snprintf(dir, dir_size, "/data/vendor/wifi/%s",
4990128bf99SKiran Kumar Lokere vendor);
5000128bf99SKiran Kumar Lokere #else /* ANDROID */
5010128bf99SKiran Kumar Lokere res = snprintf(dir, dir_size, "/var/log/%s", vendor);
5020128bf99SKiran Kumar Lokere #endif /* ANDROID */
5030128bf99SKiran Kumar Lokere }
5040128bf99SKiran Kumar Lokere
5050128bf99SKiran Kumar Lokere if (res < 0 || res >= dir_size)
5060128bf99SKiran Kumar Lokere return -1;
5070128bf99SKiran Kumar Lokere
5080128bf99SKiran Kumar Lokere /* Check for valid vendor name in log dir path since the log dir
5090128bf99SKiran Kumar Lokere * (/var/log/vendor) is deleted in dev_stop routine. This check is to
5100128bf99SKiran Kumar Lokere * avoid any unintended file deletion.
5110128bf99SKiran Kumar Lokere */
5120128bf99SKiran Kumar Lokere for (i = 0; vendor[i] != '\0'; i++) {
5130128bf99SKiran Kumar Lokere if (!isalpha(vendor[i])) {
5140128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_DEBUG,
5150128bf99SKiran Kumar Lokere "Invalid char %c in vendor name %s",
5160128bf99SKiran Kumar Lokere vendor[i], vendor);
5170128bf99SKiran Kumar Lokere return -1;
5180128bf99SKiran Kumar Lokere }
5190128bf99SKiran Kumar Lokere }
5200128bf99SKiran Kumar Lokere
5210128bf99SKiran Kumar Lokere return 0;
5220128bf99SKiran Kumar Lokere }
5230128bf99SKiran Kumar Lokere
5240128bf99SKiran Kumar Lokere
5250128bf99SKiran Kumar Lokere /* User has to redirect wpa_supplicant logs to the following file. */
5260128bf99SKiran Kumar Lokere #ifndef WPA_SUPPLICANT_LOG_FILE
5270128bf99SKiran Kumar Lokere #define WPA_SUPPLICANT_LOG_FILE "/var/log/supplicant_log/wpa_log.txt"
5280128bf99SKiran Kumar Lokere #endif /* WPA_SUPPLICANT_LOG_FILE */
5292052daa2SAnurag Das
cmd_dev_start_test(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)530a0bf244dSJouni Malinen static enum sigma_cmd_result cmd_dev_start_test(struct sigma_dut *dut,
531a0bf244dSJouni Malinen struct sigma_conn *conn,
532a7ac56ebSPeng Xu struct sigma_cmd *cmd)
533a7ac56ebSPeng Xu {
5340128bf99SKiran Kumar Lokere const char *val;
5350128bf99SKiran Kumar Lokere char buf[250];
5360128bf99SKiran Kumar Lokere char dir[200];
5370128bf99SKiran Kumar Lokere FILE *supp_log;
5380128bf99SKiran Kumar Lokere int res;
5390128bf99SKiran Kumar Lokere
5400128bf99SKiran Kumar Lokere val = get_param(cmd, "Runtime_ID");
5410128bf99SKiran Kumar Lokere if (!(val && is_runtime_id_valid(dut, val)))
5420128bf99SKiran Kumar Lokere return INVALID_SEND_STATUS;
5430128bf99SKiran Kumar Lokere
544ce791a3dSJouni Malinen if (!dut->vendor_name) {
545ce791a3dSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO,
546ce791a3dSJouni Malinen "Log collection not supported without vendor name specified on the command line (-N)");
547ce791a3dSJouni Malinen return SUCCESS_SEND_STATUS;
548ce791a3dSJouni Malinen }
549ce791a3dSJouni Malinen
5500128bf99SKiran Kumar Lokere if (build_log_dir(dut, dir, sizeof(dir)) < 0)
5510128bf99SKiran Kumar Lokere return ERROR_SEND_STATUS;
5520128bf99SKiran Kumar Lokere
5530128bf99SKiran Kumar Lokere supp_log = fopen(WPA_SUPPLICANT_LOG_FILE, "r");
5540128bf99SKiran Kumar Lokere if (!supp_log) {
5550128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR,
5560128bf99SKiran Kumar Lokere "Failed to open wpa_log file %s",
5570128bf99SKiran Kumar Lokere WPA_SUPPLICANT_LOG_FILE);
5580128bf99SKiran Kumar Lokere } else {
5590128bf99SKiran Kumar Lokere /* Get the wpa_supplicant log file size */
5600128bf99SKiran Kumar Lokere if (fseek(supp_log, 0, SEEK_END))
5610128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR,
5620128bf99SKiran Kumar Lokere "Failed to get file size for read");
5630128bf99SKiran Kumar Lokere else
5640128bf99SKiran Kumar Lokere dut->wpa_log_size = ftell(supp_log);
5650128bf99SKiran Kumar Lokere
5660128bf99SKiran Kumar Lokere fclose(supp_log);
5670128bf99SKiran Kumar Lokere }
5680128bf99SKiran Kumar Lokere
5690128bf99SKiran Kumar Lokere strlcpy(dut->dev_start_test_runtime_id, val,
5700128bf99SKiran Kumar Lokere sizeof(dut->dev_start_test_runtime_id));
5710128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_DEBUG, "Runtime_ID %s",
5720128bf99SKiran Kumar Lokere dut->dev_start_test_runtime_id);
5730128bf99SKiran Kumar Lokere
5740128bf99SKiran Kumar Lokere run_system_wrapper(dut, "rm -rf %s", dir);
5750128bf99SKiran Kumar Lokere run_system_wrapper(dut, "mkdir -p %s", dir);
5760128bf99SKiran Kumar Lokere
5770128bf99SKiran Kumar Lokere #ifdef ANDROID
5780128bf99SKiran Kumar Lokere run_system_wrapper(dut, "logcat -v time > %s/logcat_%s.txt &",
5790128bf99SKiran Kumar Lokere dir, dut->dev_start_test_runtime_id);
5800128bf99SKiran Kumar Lokere #else /* ANDROID */
5810128bf99SKiran Kumar Lokere /* Open log file for sigma_dut logs. This is not needed for Android, as
5820128bf99SKiran Kumar Lokere * we are already collecting logcat. */
5830128bf99SKiran Kumar Lokere res = snprintf(buf, sizeof(buf), "%s/sigma_%s.txt", dir,
5840128bf99SKiran Kumar Lokere dut->dev_start_test_runtime_id);
5850128bf99SKiran Kumar Lokere if (res >= 0 && res < sizeof(buf)) {
5860128bf99SKiran Kumar Lokere if (dut->log_file_fd)
5870128bf99SKiran Kumar Lokere fclose(dut->log_file_fd);
5880128bf99SKiran Kumar Lokere
5890128bf99SKiran Kumar Lokere dut->log_file_fd = fopen(buf, "a");
5900128bf99SKiran Kumar Lokere if (!dut->log_file_fd)
5910128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR,
5920128bf99SKiran Kumar Lokere "Failed to create sigma_dut log %s",
5930128bf99SKiran Kumar Lokere buf);
5940128bf99SKiran Kumar Lokere }
5950128bf99SKiran Kumar Lokere
5960128bf99SKiran Kumar Lokere run_system_wrapper(dut, "killall -9 cnss_diag_lite");
5970128bf99SKiran Kumar Lokere run_system_wrapper(dut,
5980128bf99SKiran Kumar Lokere "cnss_diag_lite -c -x 31 > %s/cnss_diag_id_%s.txt &",
5990128bf99SKiran Kumar Lokere dir, dut->dev_start_test_runtime_id);
6000128bf99SKiran Kumar Lokere #endif /* ANDROID */
6010128bf99SKiran Kumar Lokere
602a0bf244dSJouni Malinen return SUCCESS_SEND_STATUS;
603a7ac56ebSPeng Xu }
604a7ac56ebSPeng Xu
605a7ac56ebSPeng Xu
is_allowed_char(char ch)6060128bf99SKiran Kumar Lokere static int is_allowed_char(char ch)
6070128bf99SKiran Kumar Lokere {
6080128bf99SKiran Kumar Lokere return strchr("./-_", ch) != NULL;
6090128bf99SKiran Kumar Lokere }
6100128bf99SKiran Kumar Lokere
6110128bf99SKiran Kumar Lokere
is_destpath_valid(struct sigma_dut * dut,const char * val)6120128bf99SKiran Kumar Lokere static int is_destpath_valid(struct sigma_dut *dut, const char *val)
6130128bf99SKiran Kumar Lokere {
6140128bf99SKiran Kumar Lokere int i;
6150128bf99SKiran Kumar Lokere
6160128bf99SKiran Kumar Lokere for (i = 0; val[i] != '\0'; i++) {
6170128bf99SKiran Kumar Lokere if (!(isalnum(val[i]) || is_allowed_char(val[i]))) {
6180128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_DEBUG,
6190128bf99SKiran Kumar Lokere "Invalid char %c in destpath %s",
6200128bf99SKiran Kumar Lokere val[i], val);
6210128bf99SKiran Kumar Lokere return 0;
6220128bf99SKiran Kumar Lokere }
6230128bf99SKiran Kumar Lokere }
6240128bf99SKiran Kumar Lokere
6250128bf99SKiran Kumar Lokere return 1;
6260128bf99SKiran Kumar Lokere }
6270128bf99SKiran Kumar Lokere
6280128bf99SKiran Kumar Lokere
6290128bf99SKiran Kumar Lokere #ifndef ANDROID
6300128bf99SKiran Kumar Lokere #define SUPP_LOG_BUFF_SIZE 4 * 1024
6310128bf99SKiran Kumar Lokere
save_supplicant_log(struct sigma_dut * dut)6320128bf99SKiran Kumar Lokere static int save_supplicant_log(struct sigma_dut *dut)
6330128bf99SKiran Kumar Lokere {
6340128bf99SKiran Kumar Lokere char dir[200];
6350128bf99SKiran Kumar Lokere char buf[300];
6360128bf99SKiran Kumar Lokere FILE *wpa_log = NULL;
6370128bf99SKiran Kumar Lokere FILE *supp_log;
6380128bf99SKiran Kumar Lokere char *buff_ptr = NULL;
6390128bf99SKiran Kumar Lokere unsigned int file_size;
6400128bf99SKiran Kumar Lokere unsigned int file_size_orig;
6410128bf99SKiran Kumar Lokere int status = -1, res;
6420128bf99SKiran Kumar Lokere
6430128bf99SKiran Kumar Lokere if (build_log_dir(dut, dir, sizeof(dir)) < 0)
6440128bf99SKiran Kumar Lokere return -1;
6450128bf99SKiran Kumar Lokere
6460128bf99SKiran Kumar Lokere res = snprintf(buf, sizeof(buf), "%s/wpa_supplicant_log_%s.txt", dir,
6470128bf99SKiran Kumar Lokere dut->dev_start_test_runtime_id);
6480128bf99SKiran Kumar Lokere if (res < 0 || res >= sizeof(buf))
6490128bf99SKiran Kumar Lokere return -1;
6500128bf99SKiran Kumar Lokere
6510128bf99SKiran Kumar Lokere supp_log = fopen(WPA_SUPPLICANT_LOG_FILE, "r");
6520128bf99SKiran Kumar Lokere if (!supp_log) {
6530128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR,
6540128bf99SKiran Kumar Lokere "Failed to open wpa_log file %s",
6550128bf99SKiran Kumar Lokere WPA_SUPPLICANT_LOG_FILE);
6560128bf99SKiran Kumar Lokere return -1;
6570128bf99SKiran Kumar Lokere }
6580128bf99SKiran Kumar Lokere
6590128bf99SKiran Kumar Lokere /* Get the wpa_supplicant log file size */
6600128bf99SKiran Kumar Lokere if (fseek(supp_log, 0, SEEK_END)) {
6610128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR,
6620128bf99SKiran Kumar Lokere "Failed to get file size for read");
6630128bf99SKiran Kumar Lokere goto exit;
6640128bf99SKiran Kumar Lokere }
6650128bf99SKiran Kumar Lokere file_size_orig = ftell(supp_log);
6660128bf99SKiran Kumar Lokere
6670128bf99SKiran Kumar Lokere if (file_size_orig < dut->wpa_log_size) {
6680128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR,
6690128bf99SKiran Kumar Lokere "file size err, new size %u, old size %u",
6700128bf99SKiran Kumar Lokere file_size_orig, dut->wpa_log_size);
6710128bf99SKiran Kumar Lokere goto exit;
6720128bf99SKiran Kumar Lokere }
6730128bf99SKiran Kumar Lokere
6740128bf99SKiran Kumar Lokere /* Get the wpa_supplicant file size for current test */
6750128bf99SKiran Kumar Lokere file_size = file_size_orig - dut->wpa_log_size;
6760128bf99SKiran Kumar Lokere
6770128bf99SKiran Kumar Lokere wpa_log = fopen(buf, "w");
6780128bf99SKiran Kumar Lokere if (!wpa_log) {
6790128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR,
6800128bf99SKiran Kumar Lokere "Failed to create tmp wpa_log file %s", buf);
6810128bf99SKiran Kumar Lokere goto exit;
6820128bf99SKiran Kumar Lokere }
6830128bf99SKiran Kumar Lokere
6840128bf99SKiran Kumar Lokere if (fseek(supp_log, dut->wpa_log_size, SEEK_SET)) {
6850128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR,
6860128bf99SKiran Kumar Lokere "Failed to set wpa_log file ptr for read");
6870128bf99SKiran Kumar Lokere goto exit;
6880128bf99SKiran Kumar Lokere }
6890128bf99SKiran Kumar Lokere
6900128bf99SKiran Kumar Lokere buff_ptr = malloc(SUPP_LOG_BUFF_SIZE);
6910128bf99SKiran Kumar Lokere if (!buff_ptr) {
6920128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR,
6930128bf99SKiran Kumar Lokere "Failed to alloc buffer of size %d",
6940128bf99SKiran Kumar Lokere SUPP_LOG_BUFF_SIZE);
6950128bf99SKiran Kumar Lokere goto exit;
6960128bf99SKiran Kumar Lokere }
6970128bf99SKiran Kumar Lokere
6980128bf99SKiran Kumar Lokere /* Read wpa_supplicant log file in 4K byte chunks */
6990128bf99SKiran Kumar Lokere do {
7000128bf99SKiran Kumar Lokere unsigned int num_bytes_to_read;
7010128bf99SKiran Kumar Lokere unsigned int bytes_read;
7020128bf99SKiran Kumar Lokere
7030128bf99SKiran Kumar Lokere num_bytes_to_read = (file_size > SUPP_LOG_BUFF_SIZE) ?
7040128bf99SKiran Kumar Lokere SUPP_LOG_BUFF_SIZE : file_size;
7050128bf99SKiran Kumar Lokere bytes_read = fread(buff_ptr, 1, num_bytes_to_read, supp_log);
7060128bf99SKiran Kumar Lokere if (!bytes_read) {
7070128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR,
7080128bf99SKiran Kumar Lokere "Failed to read wpa_supplicant log");
7090128bf99SKiran Kumar Lokere goto exit;
7100128bf99SKiran Kumar Lokere }
7110128bf99SKiran Kumar Lokere if (bytes_read != num_bytes_to_read) {
7120128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_DEBUG,
7130128bf99SKiran Kumar Lokere "wpa_supplicant log read err, read %d, num_bytes_to_read %d",
7140128bf99SKiran Kumar Lokere bytes_read, num_bytes_to_read);
7150128bf99SKiran Kumar Lokere goto exit;
7160128bf99SKiran Kumar Lokere }
7170128bf99SKiran Kumar Lokere fwrite(buff_ptr, 1, bytes_read, wpa_log);
7180128bf99SKiran Kumar Lokere file_size -= bytes_read;
7190128bf99SKiran Kumar Lokere } while (file_size > 0);
7200128bf99SKiran Kumar Lokere status = 0;
7210128bf99SKiran Kumar Lokere
7220128bf99SKiran Kumar Lokere exit:
7230128bf99SKiran Kumar Lokere if (wpa_log)
7240128bf99SKiran Kumar Lokere fclose(wpa_log);
7250128bf99SKiran Kumar Lokere fclose(supp_log);
7260128bf99SKiran Kumar Lokere free(buff_ptr);
7270128bf99SKiran Kumar Lokere
7280128bf99SKiran Kumar Lokere return status;
7290128bf99SKiran Kumar Lokere }
7300128bf99SKiran Kumar Lokere #endif /* !ANDROID */
7310128bf99SKiran Kumar Lokere
7320128bf99SKiran Kumar Lokere
cmd_dev_stop_test(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)733a0bf244dSJouni Malinen static enum sigma_cmd_result cmd_dev_stop_test(struct sigma_dut *dut,
734a0bf244dSJouni Malinen struct sigma_conn *conn,
735a7ac56ebSPeng Xu struct sigma_cmd *cmd)
736a7ac56ebSPeng Xu {
7370128bf99SKiran Kumar Lokere const char *val;
7380128bf99SKiran Kumar Lokere char buf[300];
7390128bf99SKiran Kumar Lokere char out_file[100];
7400128bf99SKiran Kumar Lokere char dir[200];
7410128bf99SKiran Kumar Lokere int res;
7420128bf99SKiran Kumar Lokere
743ce791a3dSJouni Malinen if (!dut->vendor_name) {
744ce791a3dSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO,
745ce791a3dSJouni Malinen "Log collection not supported without vendor name specified on the command line (-N)");
746ce791a3dSJouni Malinen return SUCCESS_SEND_STATUS;
747ce791a3dSJouni Malinen }
748ce791a3dSJouni Malinen
7490128bf99SKiran Kumar Lokere val = get_param(cmd, "Runtime_ID");
7500128bf99SKiran Kumar Lokere if (!val || strcmp(val, dut->dev_start_test_runtime_id) != 0) {
7510128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid runtime id");
7520128bf99SKiran Kumar Lokere return ERROR_SEND_STATUS;
7530128bf99SKiran Kumar Lokere }
7540128bf99SKiran Kumar Lokere
7550128bf99SKiran Kumar Lokere if (build_log_dir(dut, dir, sizeof(dir)) < 0)
7560128bf99SKiran Kumar Lokere return ERROR_SEND_STATUS;
7570128bf99SKiran Kumar Lokere
7580128bf99SKiran Kumar Lokere #ifdef ANDROID
7590128bf99SKiran Kumar Lokere /* Copy all cnss_diag logs to dir */
7600128bf99SKiran Kumar Lokere run_system_wrapper(dut, "cp -a /data/vendor/wifi/wlan_logs/* %s", dir);
7610128bf99SKiran Kumar Lokere #else /* ANDROID */
7620128bf99SKiran Kumar Lokere if (dut->log_file_fd) {
7630128bf99SKiran Kumar Lokere fclose(dut->log_file_fd);
7640128bf99SKiran Kumar Lokere dut->log_file_fd = NULL;
7650128bf99SKiran Kumar Lokere }
7660128bf99SKiran Kumar Lokere if (save_supplicant_log(dut))
7670128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR,
7680128bf99SKiran Kumar Lokere "Failed to save wpa_supplicant log");
7690128bf99SKiran Kumar Lokere #endif /* ANDROID */
7700128bf99SKiran Kumar Lokere
7710128bf99SKiran Kumar Lokere res = snprintf(out_file, sizeof(out_file), "%s_%s_%s.tar.gz",
772ce791a3dSJouni Malinen dut->vendor_name,
7730128bf99SKiran Kumar Lokere dut->model_name ? dut->model_name : "Unknown",
7740128bf99SKiran Kumar Lokere dut->dev_start_test_runtime_id);
7750128bf99SKiran Kumar Lokere if (res < 0 || res >= sizeof(out_file))
7760128bf99SKiran Kumar Lokere return ERROR_SEND_STATUS;
7770128bf99SKiran Kumar Lokere
7780128bf99SKiran Kumar Lokere if (run_system_wrapper(dut, "tar -czvf %s/../%s %s", dir, out_file,
7790128bf99SKiran Kumar Lokere dir) < 0) {
7800128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to create tar: %s",
7810128bf99SKiran Kumar Lokere buf);
7820128bf99SKiran Kumar Lokere return ERROR_SEND_STATUS;
7830128bf99SKiran Kumar Lokere }
7840128bf99SKiran Kumar Lokere
7850128bf99SKiran Kumar Lokere val = get_param(cmd, "destpath");
7860128bf99SKiran Kumar Lokere if (!(val && is_destpath_valid(dut, val))) {
7870128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid path for TFTP %s",
7880128bf99SKiran Kumar Lokere val);
7890128bf99SKiran Kumar Lokere return ERROR_SEND_STATUS;
7900128bf99SKiran Kumar Lokere }
7910128bf99SKiran Kumar Lokere
7920128bf99SKiran Kumar Lokere res = snprintf(buf, sizeof(buf), "tftp %s -c put %s/%s %s/%s",
7930128bf99SKiran Kumar Lokere inet_ntoa(conn->addr.sin_addr), dir, out_file, val,
7940128bf99SKiran Kumar Lokere out_file);
7950128bf99SKiran Kumar Lokere if (res < 0 || res >= sizeof(buf))
7960128bf99SKiran Kumar Lokere return ERROR_SEND_STATUS;
7970128bf99SKiran Kumar Lokere if (run_system_wrapper(dut, buf) < 0) {
7980128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_ERROR,
7990128bf99SKiran Kumar Lokere "TFTP file transfer failed: %s", buf);
8000128bf99SKiran Kumar Lokere return ERROR_SEND_STATUS;
8010128bf99SKiran Kumar Lokere }
8020128bf99SKiran Kumar Lokere sigma_dut_print(dut, DUT_MSG_DEBUG, "TFTP file transfer: %s", buf);
8030128bf99SKiran Kumar Lokere snprintf(buf, sizeof(buf), "filename,%s", out_file);
8040128bf99SKiran Kumar Lokere send_resp(dut, conn, SIGMA_COMPLETE, buf);
8050128bf99SKiran Kumar Lokere run_system_wrapper(dut, "rm -f %s/../%s", dir, out_file);
8060128bf99SKiran Kumar Lokere run_system_wrapper(dut, "rm -rf %s", dir);
8070128bf99SKiran Kumar Lokere
808a0bf244dSJouni Malinen return SUCCESS_SEND_STATUS;
809a7ac56ebSPeng Xu }
810a7ac56ebSPeng Xu
811a7ac56ebSPeng Xu
cmd_dev_get_log(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)812a0bf244dSJouni Malinen static enum sigma_cmd_result cmd_dev_get_log(struct sigma_dut *dut,
813a0bf244dSJouni Malinen struct sigma_conn *conn,
814a7ac56ebSPeng Xu struct sigma_cmd *cmd)
815a7ac56ebSPeng Xu {
816a0bf244dSJouni Malinen return SUCCESS_SEND_STATUS;
817a7ac56ebSPeng Xu }
818a7ac56ebSPeng Xu
819a7ac56ebSPeng Xu
req_intf(struct sigma_cmd * cmd)8203c367e8dSJouni Malinen static int req_intf(struct sigma_cmd *cmd)
8213c367e8dSJouni Malinen {
8223c367e8dSJouni Malinen return get_param(cmd, "interface") == NULL ? -1 : 0;
8233c367e8dSJouni Malinen }
8243c367e8dSJouni Malinen
8253c367e8dSJouni Malinen
req_role_svcname(struct sigma_cmd * cmd)8262052daa2SAnurag Das static int req_role_svcname(struct sigma_cmd *cmd)
8272052daa2SAnurag Das {
8282052daa2SAnurag Das if (!get_param(cmd, "BLERole"))
8292052daa2SAnurag Das return -1;
8302052daa2SAnurag Das if (get_param(cmd, "BLEOp") && !get_param(cmd, "ServiceName"))
8312052daa2SAnurag Das return -1;
8322052daa2SAnurag Das return 0;
8332052daa2SAnurag Das }
8342052daa2SAnurag Das
8352052daa2SAnurag Das
req_intf_prog(struct sigma_cmd * cmd)836cd4e3c3eSJouni Malinen static int req_intf_prog(struct sigma_cmd *cmd)
837cd4e3c3eSJouni Malinen {
838cd4e3c3eSJouni Malinen if (get_param(cmd, "interface") == NULL)
839cd4e3c3eSJouni Malinen return -1;
840cd4e3c3eSJouni Malinen if (get_param(cmd, "program") == NULL)
841cd4e3c3eSJouni Malinen return -1;
842cd4e3c3eSJouni Malinen return 0;
843cd4e3c3eSJouni Malinen }
844cd4e3c3eSJouni Malinen
845cd4e3c3eSJouni Malinen
req_prog(struct sigma_cmd * cmd)846d86e5828SJouni Malinen static int req_prog(struct sigma_cmd *cmd)
847d86e5828SJouni Malinen {
848d86e5828SJouni Malinen if (get_param(cmd, "program") == NULL)
849d86e5828SJouni Malinen return -1;
850d86e5828SJouni Malinen return 0;
851d86e5828SJouni Malinen }
852d86e5828SJouni Malinen
853d86e5828SJouni Malinen
dev_register_cmds(void)854cd4e3c3eSJouni Malinen void dev_register_cmds(void)
855cd4e3c3eSJouni Malinen {
8564a3c2f80SAlexei Avshalom Lazar sigma_dut_reg_cmd("dev_send_frame", req_prog, cmd_dev_send_frame);
857cd4e3c3eSJouni Malinen sigma_dut_reg_cmd("dev_set_parameter", req_intf_prog,
858cd4e3c3eSJouni Malinen cmd_dev_set_parameter);
859d86e5828SJouni Malinen sigma_dut_reg_cmd("dev_exec_action", req_prog,
8609c381f59SAmarnath Hullur Subramanyam cmd_dev_exec_action);
8613c367e8dSJouni Malinen sigma_dut_reg_cmd("dev_configure_ie", req_intf, cmd_dev_configure_ie);
862a7ac56ebSPeng Xu sigma_dut_reg_cmd("dev_start_test", NULL, cmd_dev_start_test);
863a7ac56ebSPeng Xu sigma_dut_reg_cmd("dev_stop_test", NULL, cmd_dev_stop_test);
864a7ac56ebSPeng Xu sigma_dut_reg_cmd("dev_get_log", NULL, cmd_dev_get_log);
8652052daa2SAnurag Das sigma_dut_reg_cmd("dev_ble_action", req_role_svcname,
8662052daa2SAnurag Das cmd_dev_ble_action);
867cd4e3c3eSJouni Malinen }
868