blob: bf2e1fe6e185472212d037dc107ce6b760b632cf [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (station/AP/sniffer)
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07003 * Copyright (c) 2011-2013, 2017, Qualcomm Atheros, Inc.
Jouni Malinena0bf2442019-02-19 12:03:26 +02004 * Copyright (c) 2018-2019, The Linux Foundation
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005 * All Rights Reserved.
6 * Licensed under the Clear BSD license. See README for more details.
7 */
8
9#include "sigma_dut.h"
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -070010#include <ctype.h>
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -070011#include "miracast.h"
Anurag Das2052daa2018-08-31 14:35:25 +053012#include <sys/wait.h>
13#include "wpa_ctrl.h"
14#include "wpa_helpers.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015
16
Jouni Malinenfee3c4a2019-06-20 01:06:26 +030017extern char *sigma_cert_path;
18
19
Jouni Malinena0bf2442019-02-19 12:03:26 +020020static enum sigma_cmd_result cmd_dev_send_frame(struct sigma_dut *dut,
21 struct sigma_conn *conn,
22 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020023{
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -070024#ifdef MIRACAST
25 const char *program = get_param(cmd, "Program");
26
27 if (program && (strcasecmp(program, "WFD") == 0 ||
28 strcasecmp(program, "DisplayR2") == 0))
29 return miracast_dev_send_frame(dut, conn, cmd);
30#endif /* MIRACAST */
31
Jouni Malinencd4e3c32015-10-29 12:39:56 +020032 if (dut->mode == SIGMA_MODE_STATION ||
33 dut->mode == SIGMA_MODE_UNKNOWN) {
34 sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert "
35 "dev_send_frame to sta_send_frame");
36 return cmd_sta_send_frame(dut, conn, cmd);
37 }
38
39 if (dut->mode == SIGMA_MODE_AP) {
40 sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert "
41 "dev_send_frame to ap_send_frame");
42 return cmd_ap_send_frame(dut, conn, cmd);
43 }
44
45#ifdef CONFIG_WLANTEST
46 sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert dev_send_frame to "
47 "wlantest_send_frame");
48 return cmd_wlantest_send_frame(dut, conn, cmd);
49#else /* CONFIG_WLANTEST */
50 send_resp(dut, conn, SIGMA_ERROR,
51 "errorCode,Unsupported dev_send_frame");
Jouni Malinena0bf2442019-02-19 12:03:26 +020052 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020053#endif /* CONFIG_WLANTEST */
54}
55
56
Jouni Malinena0bf2442019-02-19 12:03:26 +020057static enum sigma_cmd_result cmd_dev_set_parameter(struct sigma_dut *dut,
58 struct sigma_conn *conn,
59 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020060{
61 const char *device = get_param(cmd, "Device");
62
63 if (device && strcasecmp(device, "STA") == 0) {
64 sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert "
65 "dev_set_parameter to sta_set_parameter");
66 return cmd_sta_set_parameter(dut, conn, cmd);
67 }
68
Jouni Malinena0bf2442019-02-19 12:03:26 +020069 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020070}
71
72
Jouni Malinen134fe3c2019-06-12 04:16:49 +030073static enum sigma_cmd_result sta_server_cert_trust(struct sigma_dut *dut,
74 struct sigma_conn *conn,
75 const char *val)
76{
Jouni Malinenfee3c4a2019-06-20 01:06:26 +030077 char buf[200];
Jouni Malinen134fe3c2019-06-12 04:16:49 +030078 struct wpa_ctrl *ctrl = NULL;
79 int e;
80 char resp[200];
81 int num_disconnected = 0;
82
83 strlcpy(resp, "ServerCertTrustResult,Accepted", sizeof(resp));
84
Jouni Malinen6a3005f2019-06-13 23:39:34 +030085 if (strcasecmp(val, "Accept") != 0 && strcasecmp(val, "Reject") != 0) {
86 sigma_dut_print(dut, DUT_MSG_INFO,
87 "Unknown ServerCertTrust value '%s'", val);
88 return INVALID_SEND_STATUS;
Jouni Malinen134fe3c2019-06-12 04:16:49 +030089 }
90
Jouni Malinenfee3c4a2019-06-20 01:06:26 +030091 snprintf(buf, sizeof(buf), "%s/uosc-disabled", sigma_cert_path);
92 if (file_exists(buf)) {
93 strlcpy(resp,
94 "ServerCertTrustResult,OverrideNotAllowed,Reason,UOSC disabled on device",
95 sizeof(resp));
96 goto done;
97 }
98
Jouni Malinen134fe3c2019-06-12 04:16:49 +030099 if (!dut->server_cert_hash[0]) {
100 strlcpy(resp,
Jouni Malinen6a3005f2019-06-13 23:39:34 +0300101 "ServerCertTrustResult,OverrideNotAllowed,Reason,No server certificate stored",
Jouni Malinen134fe3c2019-06-12 04:16:49 +0300102 sizeof(resp));
103 goto done;
104 }
105
106 if (dut->sta_tod_policy) {
107 strlcpy(resp,
Jouni Malinen6a3005f2019-06-13 23:39:34 +0300108 "ServerCertTrustResult,OverrideNotAllowed,Reason,TOD policy",
Jouni Malinen134fe3c2019-06-12 04:16:49 +0300109 sizeof(resp));
110 goto done;
111 }
112
Jouni Malinen6a3005f2019-06-13 23:39:34 +0300113 if (strcasecmp(val, "Accept") != 0) {
114 strlcpy(resp, "ServerCertTrustResult,Rejected", sizeof(resp));
115 goto done;
116 }
117
Jouni Malinen134fe3c2019-06-12 04:16:49 +0300118 snprintf(buf, sizeof(buf), "hash://server/sha256/%s",
119 dut->server_cert_hash);
120 if (set_network_quoted(get_station_ifname(), dut->infra_network_id,
121 "ca_cert", buf) < 0) {
122 strlcpy(resp,
Jouni Malinen6a3005f2019-06-13 23:39:34 +0300123 "ServerCertTrustResult,OverrideNotAllowed,Reason,Could not configure server certificate hash for the network profile",
Jouni Malinen134fe3c2019-06-12 04:16:49 +0300124 sizeof(resp));
125 goto done;
126 }
127
Jouni Malinen560e4a92019-06-20 01:42:48 +0300128 if (set_network(get_station_ifname(), dut->infra_network_id,
129 "domain_match", "NULL") < 0 ||
130 set_network(get_station_ifname(), dut->infra_network_id,
131 "domain_suffix_match", "NULL") < 0) {
132 strlcpy(resp,
133 "ServerCertTrustResult,OverrideNotAllowed,Reason,Could not clear domain matching rules",
134 sizeof(resp));
135 goto done;
136 }
137
Jouni Malinen134fe3c2019-06-12 04:16:49 +0300138 wpa_command(get_station_ifname(), "DISCONNECT");
139 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", dut->infra_network_id);
140 if (wpa_command(get_station_ifname(), buf) < 0) {
141 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
142 "network id %d on %s",
143 dut->infra_network_id,
144 get_station_ifname());
145 strlcpy(resp,
146 "ServerCertTrustResult,Accepted,Result,Could not request reconnection",
147 sizeof(resp));
148 goto done;
149 }
150
151 ctrl = open_wpa_mon(get_station_ifname());
152 if (!ctrl)
153 goto done;
154
155 for (e = 0; e < 20; e++) {
156 const char *events[] = {
157 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
158 "CTRL-EVENT-DISCONNECTED",
159 "CTRL-EVENT-CONNECTED",
160 NULL
161 };
162 char buf[1024];
163 int res;
164
165 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
166 if (res < 0) {
167 strlcpy(resp,
168 "ServerCertTrustResult,Accepted,Result,Association did not complete",
169 sizeof(resp));
170 goto done;
171 }
172 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
173 buf);
174
175 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
176 strlcpy(resp,
Jouni Malinen6a3005f2019-06-13 23:39:34 +0300177 "ServerCertTrustResult,Accepted,Result,TLS server certificate validation failed with updated profile",
Jouni Malinen134fe3c2019-06-12 04:16:49 +0300178 sizeof(resp));
179 goto done;
180 }
181
182 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
183 num_disconnected++;
184
185 if (num_disconnected > 2) {
186 strlcpy(resp,
187 "ServerCertTrustResult,Accepted,Result,Connection failed",
188 sizeof(resp));
189 goto done;
190 }
191 }
192
193 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
194 strlcpy(resp,
195 "ServerCertTrustResult,Accepted,Result,Connected",
196 sizeof(resp));
197 break;
198 }
199 }
200
201done:
202 if (ctrl) {
203 wpa_ctrl_detach(ctrl);
204 wpa_ctrl_close(ctrl);
205 }
206
207 send_resp(dut, conn, SIGMA_COMPLETE, resp);
208 return STATUS_SENT;
209}
210
211
Jouni Malinena0bf2442019-02-19 12:03:26 +0200212static enum sigma_cmd_result cmd_dev_exec_action(struct sigma_dut *dut,
213 struct sigma_conn *conn,
214 struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -0700215{
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -0700216 const char *program = get_param(cmd, "Program");
Jouni Malinen134fe3c2019-06-12 04:16:49 +0300217 const char *val;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -0700218
Jouni Malinend86e5822017-08-29 03:55:32 +0300219#ifdef MIRACAST
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -0700220 if (program && (strcasecmp(program, "WFD") == 0 ||
Jouni Malinend86e5822017-08-29 03:55:32 +0300221 strcasecmp(program, "DisplayR2") == 0)) {
222 if (get_param(cmd, "interface") == NULL)
Jouni Malinena0bf2442019-02-19 12:03:26 +0200223 return INVALID_SEND_STATUS;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -0700224 return miracast_dev_exec_action(dut, conn, cmd);
Jouni Malinend86e5822017-08-29 03:55:32 +0300225 }
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -0700226#endif /* MIRACAST */
227
Jouni Malinend86e5822017-08-29 03:55:32 +0300228 if (program && strcasecmp(program, "DPP") == 0)
229 return dpp_dev_exec_action(dut, conn, cmd);
230
Jouni Malinen134fe3c2019-06-12 04:16:49 +0300231 val = get_param(cmd, "ServerCertTrust");
232 if (val)
233 return sta_server_cert_trust(dut, conn, val);
234
Jouni Malinena0bf2442019-02-19 12:03:26 +0200235 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -0700236}
237
238
Jouni Malinena0bf2442019-02-19 12:03:26 +0200239static enum sigma_cmd_result cmd_dev_configure_ie(struct sigma_dut *dut,
240 struct sigma_conn *conn,
241 struct sigma_cmd *cmd)
Jouni Malinen3c367e82017-06-23 17:01:47 +0300242{
243 const char *ie_name = get_param(cmd, "IE_Name");
244 const char *contents = get_param(cmd, "Contents");
245
246 if (!ie_name || !contents)
Jouni Malinena0bf2442019-02-19 12:03:26 +0200247 return INVALID_SEND_STATUS;
Jouni Malinen3c367e82017-06-23 17:01:47 +0300248
249 if (strcasecmp(ie_name, "RSNE") != 0) {
250 send_resp(dut, conn, SIGMA_ERROR,
251 "errorCode,Unsupported IE_Name value");
Jouni Malinena0bf2442019-02-19 12:03:26 +0200252 return STATUS_SENT;
Jouni Malinen3c367e82017-06-23 17:01:47 +0300253 }
254
255 free(dut->rsne_override);
256 dut->rsne_override = strdup(contents);
257
Jouni Malinena0bf2442019-02-19 12:03:26 +0200258 return dut->rsne_override ? SUCCESS_SEND_STATUS : ERROR_SEND_STATUS;
Jouni Malinen3c367e82017-06-23 17:01:47 +0300259}
260
261
Jouni Malinena0bf2442019-02-19 12:03:26 +0200262static enum sigma_cmd_result cmd_dev_ble_action(struct sigma_dut *dut,
263 struct sigma_conn *conn,
264 struct sigma_cmd *cmd)
Anurag Das2052daa2018-08-31 14:35:25 +0530265{
266#ifdef ANDROID
Anurag Das2052daa2018-08-31 14:35:25 +0530267 const char *ble_op = get_param(cmd, "BLEOp");
268 const char *prog = get_param(cmd, "Prog");
269 const char *service_name = get_param(cmd, "ServiceName");
270 const char *ble_role = get_param(cmd, "BLERole");
271 const char *discovery_type = get_param(cmd, "DiscoveryType");
272 const char *msg_type = get_param(cmd, "messagetype");
273 const char *action = get_param(cmd, "action");
274 const char *M2Transmit = get_param(cmd, "M2Transmit");
275 char *argv[17];
276 pid_t pid;
277
278 if (prog && ble_role && action && msg_type) {
279 send_resp(dut, conn, SIGMA_COMPLETE,
280 "OrgID,0x00,TransDataHeader,0x00,BloomFilterElement,NULL");
Jouni Malinena0bf2442019-02-19 12:03:26 +0200281 return STATUS_SENT;
Anurag Das2052daa2018-08-31 14:35:25 +0530282 }
283 if (!ble_op || !prog || !service_name || !ble_role || !discovery_type) {
284 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid arguments");
Jouni Malinena0bf2442019-02-19 12:03:26 +0200285 return INVALID_SEND_STATUS;
Anurag Das2052daa2018-08-31 14:35:25 +0530286 }
287
288 if ((strcasecmp(prog, "NAN") != 0)) {
289 sigma_dut_print(dut, DUT_MSG_ERROR, "Program %s not supported",
290 prog);
Jouni Malinena0bf2442019-02-19 12:03:26 +0200291 return INVALID_SEND_STATUS;
Anurag Das2052daa2018-08-31 14:35:25 +0530292 }
293
294 if (strcasecmp(ble_role, "seeker") != 0 &&
295 strcasecmp(ble_role, "provider") != 0 &&
296 strcasecmp(ble_role, "browser") != 0) {
297 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid BLERole: %s",
298 ble_role);
Jouni Malinena0bf2442019-02-19 12:03:26 +0200299 return INVALID_SEND_STATUS;
Anurag Das2052daa2018-08-31 14:35:25 +0530300 }
301
302 if (strcasecmp(discovery_type, "active") != 0 &&
303 strcasecmp(discovery_type, "passive") != 0) {
304 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid DiscoveryType: %s",
305 discovery_type);
Jouni Malinena0bf2442019-02-19 12:03:26 +0200306 return INVALID_SEND_STATUS;
Anurag Das2052daa2018-08-31 14:35:25 +0530307 }
308
309 if (!M2Transmit)
310 M2Transmit = "disable";
311
312 argv[0] = "am";
313 argv[1] = "start";
314 argv[2] = "-n";
315 argv[3] = "org.codeaurora.nanservicediscovery/org.codeaurora.nanservicediscovery.MainActivity";
316 argv[4] = "--es";
317 argv[5] = "service";
318 argv[6] = (char *) service_name;
319 argv[7] = "--es";
320 argv[8] = "role";
321 argv[9] = (char *) ble_role;
322 argv[10] = "--es";
323 argv[11] = "scantype";
324 argv[12] = (char *) discovery_type;
325 argv[13] = "--es";
326 argv[14] = "M2Transmit";
327 argv[15] = (char *) M2Transmit;
328 argv[16] = NULL;
329
330 pid = fork();
331 if (pid == -1) {
332 sigma_dut_print(dut, DUT_MSG_ERROR, "fork: %s",
333 strerror(errno));
Jouni Malinena0bf2442019-02-19 12:03:26 +0200334 return ERROR_SEND_STATUS;
Anurag Das2052daa2018-08-31 14:35:25 +0530335 }
336
337 if (pid == 0) {
338 execv("/system/bin/am", argv);
339 sigma_dut_print(dut, DUT_MSG_ERROR, "execv: %s",
340 strerror(errno));
341 exit(0);
Jouni Malinena0bf2442019-02-19 12:03:26 +0200342 return ERROR_SEND_STATUS;
Anurag Das2052daa2018-08-31 14:35:25 +0530343 }
344
345 dut->nanservicediscoveryinprogress = 1;
346#endif /* ANDROID */
347
Jouni Malinena0bf2442019-02-19 12:03:26 +0200348 return SUCCESS_SEND_STATUS;
Anurag Das2052daa2018-08-31 14:35:25 +0530349}
350
351
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -0700352/* Runtime ID must contain only numbers */
353static int is_runtime_id_valid(struct sigma_dut *dut, const char *val)
354{
355 int i;
356
357 for (i = 0; val[i] != '\0'; i++) {
358 if (!isdigit(val[i])) {
359 sigma_dut_print(dut, DUT_MSG_DEBUG,
360 "Invalid Runtime_ID %s", val);
361 return 0;
362 }
363 }
364
365 return 1;
366}
367
368
369static int build_log_dir(struct sigma_dut *dut, char *dir, size_t dir_size)
370{
371 int res;
Jouni Malinence791a32019-06-20 01:19:00 +0300372 const char *vendor = dut->vendor_name;
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -0700373 int i;
374
Jouni Malinence791a32019-06-20 01:19:00 +0300375 if (!vendor)
376 return -1;
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -0700377
378 if (dut->log_file_dir) {
379 res = snprintf(dir, dir_size, "%s/%s", dut->log_file_dir,
380 vendor);
381 } else {
382#ifdef ANDROID
383 res = snprintf(dir, dir_size, "/data/vendor/wifi/%s",
384 vendor);
385#else /* ANDROID */
386 res = snprintf(dir, dir_size, "/var/log/%s", vendor);
387#endif /* ANDROID */
388 }
389
390 if (res < 0 || res >= dir_size)
391 return -1;
392
393 /* Check for valid vendor name in log dir path since the log dir
394 * (/var/log/vendor) is deleted in dev_stop routine. This check is to
395 * avoid any unintended file deletion.
396 */
397 for (i = 0; vendor[i] != '\0'; i++) {
398 if (!isalpha(vendor[i])) {
399 sigma_dut_print(dut, DUT_MSG_DEBUG,
400 "Invalid char %c in vendor name %s",
401 vendor[i], vendor);
402 return -1;
403 }
404 }
405
406 return 0;
407}
408
409
410/* User has to redirect wpa_supplicant logs to the following file. */
411#ifndef WPA_SUPPLICANT_LOG_FILE
412#define WPA_SUPPLICANT_LOG_FILE "/var/log/supplicant_log/wpa_log.txt"
413#endif /* WPA_SUPPLICANT_LOG_FILE */
Anurag Das2052daa2018-08-31 14:35:25 +0530414
Jouni Malinena0bf2442019-02-19 12:03:26 +0200415static enum sigma_cmd_result cmd_dev_start_test(struct sigma_dut *dut,
416 struct sigma_conn *conn,
417 struct sigma_cmd *cmd)
Peng Xua7ac56e2018-06-26 16:07:19 -0700418{
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -0700419 const char *val;
420 char buf[250];
421 char dir[200];
422 FILE *supp_log;
423 int res;
424
425 val = get_param(cmd, "Runtime_ID");
426 if (!(val && is_runtime_id_valid(dut, val)))
427 return INVALID_SEND_STATUS;
428
Jouni Malinence791a32019-06-20 01:19:00 +0300429 if (!dut->vendor_name) {
430 sigma_dut_print(dut, DUT_MSG_INFO,
431 "Log collection not supported without vendor name specified on the command line (-N)");
432 return SUCCESS_SEND_STATUS;
433 }
434
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -0700435 if (build_log_dir(dut, dir, sizeof(dir)) < 0)
436 return ERROR_SEND_STATUS;
437
438 supp_log = fopen(WPA_SUPPLICANT_LOG_FILE, "r");
439 if (!supp_log) {
440 sigma_dut_print(dut, DUT_MSG_ERROR,
441 "Failed to open wpa_log file %s",
442 WPA_SUPPLICANT_LOG_FILE);
443 } else {
444 /* Get the wpa_supplicant log file size */
445 if (fseek(supp_log, 0, SEEK_END))
446 sigma_dut_print(dut, DUT_MSG_ERROR,
447 "Failed to get file size for read");
448 else
449 dut->wpa_log_size = ftell(supp_log);
450
451 fclose(supp_log);
452 }
453
454 strlcpy(dut->dev_start_test_runtime_id, val,
455 sizeof(dut->dev_start_test_runtime_id));
456 sigma_dut_print(dut, DUT_MSG_DEBUG, "Runtime_ID %s",
457 dut->dev_start_test_runtime_id);
458
459 run_system_wrapper(dut, "rm -rf %s", dir);
460 run_system_wrapper(dut, "mkdir -p %s", dir);
461
462#ifdef ANDROID
463 run_system_wrapper(dut, "logcat -v time > %s/logcat_%s.txt &",
464 dir, dut->dev_start_test_runtime_id);
465#else /* ANDROID */
466 /* Open log file for sigma_dut logs. This is not needed for Android, as
467 * we are already collecting logcat. */
468 res = snprintf(buf, sizeof(buf), "%s/sigma_%s.txt", dir,
469 dut->dev_start_test_runtime_id);
470 if (res >= 0 && res < sizeof(buf)) {
471 if (dut->log_file_fd)
472 fclose(dut->log_file_fd);
473
474 dut->log_file_fd = fopen(buf, "a");
475 if (!dut->log_file_fd)
476 sigma_dut_print(dut, DUT_MSG_ERROR,
477 "Failed to create sigma_dut log %s",
478 buf);
479 }
480
481 run_system_wrapper(dut, "killall -9 cnss_diag_lite");
482 run_system_wrapper(dut,
483 "cnss_diag_lite -c -x 31 > %s/cnss_diag_id_%s.txt &",
484 dir, dut->dev_start_test_runtime_id);
485#endif /* ANDROID */
486
Jouni Malinena0bf2442019-02-19 12:03:26 +0200487 return SUCCESS_SEND_STATUS;
Peng Xua7ac56e2018-06-26 16:07:19 -0700488}
489
490
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -0700491static int is_allowed_char(char ch)
492{
493 return strchr("./-_", ch) != NULL;
494}
495
496
497static int is_destpath_valid(struct sigma_dut *dut, const char *val)
498{
499 int i;
500
501 for (i = 0; val[i] != '\0'; i++) {
502 if (!(isalnum(val[i]) || is_allowed_char(val[i]))) {
503 sigma_dut_print(dut, DUT_MSG_DEBUG,
504 "Invalid char %c in destpath %s",
505 val[i], val);
506 return 0;
507 }
508 }
509
510 return 1;
511}
512
513
514#ifndef ANDROID
515#define SUPP_LOG_BUFF_SIZE 4 * 1024
516
517static int save_supplicant_log(struct sigma_dut *dut)
518{
519 char dir[200];
520 char buf[300];
521 FILE *wpa_log = NULL;
522 FILE *supp_log;
523 char *buff_ptr = NULL;
524 unsigned int file_size;
525 unsigned int file_size_orig;
526 int status = -1, res;
527
528 if (build_log_dir(dut, dir, sizeof(dir)) < 0)
529 return -1;
530
531 res = snprintf(buf, sizeof(buf), "%s/wpa_supplicant_log_%s.txt", dir,
532 dut->dev_start_test_runtime_id);
533 if (res < 0 || res >= sizeof(buf))
534 return -1;
535
536 supp_log = fopen(WPA_SUPPLICANT_LOG_FILE, "r");
537 if (!supp_log) {
538 sigma_dut_print(dut, DUT_MSG_ERROR,
539 "Failed to open wpa_log file %s",
540 WPA_SUPPLICANT_LOG_FILE);
541 return -1;
542 }
543
544 /* Get the wpa_supplicant log file size */
545 if (fseek(supp_log, 0, SEEK_END)) {
546 sigma_dut_print(dut, DUT_MSG_ERROR,
547 "Failed to get file size for read");
548 goto exit;
549 }
550 file_size_orig = ftell(supp_log);
551
552 if (file_size_orig < dut->wpa_log_size) {
553 sigma_dut_print(dut, DUT_MSG_ERROR,
554 "file size err, new size %u, old size %u",
555 file_size_orig, dut->wpa_log_size);
556 goto exit;
557 }
558
559 /* Get the wpa_supplicant file size for current test */
560 file_size = file_size_orig - dut->wpa_log_size;
561
562 wpa_log = fopen(buf, "w");
563 if (!wpa_log) {
564 sigma_dut_print(dut, DUT_MSG_ERROR,
565 "Failed to create tmp wpa_log file %s", buf);
566 goto exit;
567 }
568
569 if (fseek(supp_log, dut->wpa_log_size, SEEK_SET)) {
570 sigma_dut_print(dut, DUT_MSG_ERROR,
571 "Failed to set wpa_log file ptr for read");
572 goto exit;
573 }
574
575 buff_ptr = malloc(SUPP_LOG_BUFF_SIZE);
576 if (!buff_ptr) {
577 sigma_dut_print(dut, DUT_MSG_ERROR,
578 "Failed to alloc buffer of size %d",
579 SUPP_LOG_BUFF_SIZE);
580 goto exit;
581 }
582
583 /* Read wpa_supplicant log file in 4K byte chunks */
584 do {
585 unsigned int num_bytes_to_read;
586 unsigned int bytes_read;
587
588 num_bytes_to_read = (file_size > SUPP_LOG_BUFF_SIZE) ?
589 SUPP_LOG_BUFF_SIZE : file_size;
590 bytes_read = fread(buff_ptr, 1, num_bytes_to_read, supp_log);
591 if (!bytes_read) {
592 sigma_dut_print(dut, DUT_MSG_ERROR,
593 "Failed to read wpa_supplicant log");
594 goto exit;
595 }
596 if (bytes_read != num_bytes_to_read) {
597 sigma_dut_print(dut, DUT_MSG_DEBUG,
598 "wpa_supplicant log read err, read %d, num_bytes_to_read %d",
599 bytes_read, num_bytes_to_read);
600 goto exit;
601 }
602 fwrite(buff_ptr, 1, bytes_read, wpa_log);
603 file_size -= bytes_read;
604 } while (file_size > 0);
605 status = 0;
606
607exit:
608 if (wpa_log)
609 fclose(wpa_log);
610 fclose(supp_log);
611 free(buff_ptr);
612
613 return status;
614}
615#endif /* !ANDROID */
616
617
Jouni Malinena0bf2442019-02-19 12:03:26 +0200618static enum sigma_cmd_result cmd_dev_stop_test(struct sigma_dut *dut,
619 struct sigma_conn *conn,
620 struct sigma_cmd *cmd)
Peng Xua7ac56e2018-06-26 16:07:19 -0700621{
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -0700622 const char *val;
623 char buf[300];
624 char out_file[100];
625 char dir[200];
626 int res;
627
Jouni Malinence791a32019-06-20 01:19:00 +0300628 if (!dut->vendor_name) {
629 sigma_dut_print(dut, DUT_MSG_INFO,
630 "Log collection not supported without vendor name specified on the command line (-N)");
631 return SUCCESS_SEND_STATUS;
632 }
633
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -0700634 val = get_param(cmd, "Runtime_ID");
635 if (!val || strcmp(val, dut->dev_start_test_runtime_id) != 0) {
636 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid runtime id");
637 return ERROR_SEND_STATUS;
638 }
639
640 if (build_log_dir(dut, dir, sizeof(dir)) < 0)
641 return ERROR_SEND_STATUS;
642
643#ifdef ANDROID
644 /* Copy all cnss_diag logs to dir */
645 run_system_wrapper(dut, "cp -a /data/vendor/wifi/wlan_logs/* %s", dir);
646#else /* ANDROID */
647 if (dut->log_file_fd) {
648 fclose(dut->log_file_fd);
649 dut->log_file_fd = NULL;
650 }
651 if (save_supplicant_log(dut))
652 sigma_dut_print(dut, DUT_MSG_ERROR,
653 "Failed to save wpa_supplicant log");
654#endif /* ANDROID */
655
656 res = snprintf(out_file, sizeof(out_file), "%s_%s_%s.tar.gz",
Jouni Malinence791a32019-06-20 01:19:00 +0300657 dut->vendor_name,
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -0700658 dut->model_name ? dut->model_name : "Unknown",
659 dut->dev_start_test_runtime_id);
660 if (res < 0 || res >= sizeof(out_file))
661 return ERROR_SEND_STATUS;
662
663 if (run_system_wrapper(dut, "tar -czvf %s/../%s %s", dir, out_file,
664 dir) < 0) {
665 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to create tar: %s",
666 buf);
667 return ERROR_SEND_STATUS;
668 }
669
670 val = get_param(cmd, "destpath");
671 if (!(val && is_destpath_valid(dut, val))) {
672 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid path for TFTP %s",
673 val);
674 return ERROR_SEND_STATUS;
675 }
676
677 res = snprintf(buf, sizeof(buf), "tftp %s -c put %s/%s %s/%s",
678 inet_ntoa(conn->addr.sin_addr), dir, out_file, val,
679 out_file);
680 if (res < 0 || res >= sizeof(buf))
681 return ERROR_SEND_STATUS;
682 if (run_system_wrapper(dut, buf) < 0) {
683 sigma_dut_print(dut, DUT_MSG_ERROR,
684 "TFTP file transfer failed: %s", buf);
685 return ERROR_SEND_STATUS;
686 }
687 sigma_dut_print(dut, DUT_MSG_DEBUG, "TFTP file transfer: %s", buf);
688 snprintf(buf, sizeof(buf), "filename,%s", out_file);
689 send_resp(dut, conn, SIGMA_COMPLETE, buf);
690 run_system_wrapper(dut, "rm -f %s/../%s", dir, out_file);
691 run_system_wrapper(dut, "rm -rf %s", dir);
692
Jouni Malinena0bf2442019-02-19 12:03:26 +0200693 return SUCCESS_SEND_STATUS;
Peng Xua7ac56e2018-06-26 16:07:19 -0700694}
695
696
Jouni Malinena0bf2442019-02-19 12:03:26 +0200697static enum sigma_cmd_result cmd_dev_get_log(struct sigma_dut *dut,
698 struct sigma_conn *conn,
699 struct sigma_cmd *cmd)
Peng Xua7ac56e2018-06-26 16:07:19 -0700700{
Jouni Malinena0bf2442019-02-19 12:03:26 +0200701 return SUCCESS_SEND_STATUS;
Peng Xua7ac56e2018-06-26 16:07:19 -0700702}
703
704
Jouni Malinen3c367e82017-06-23 17:01:47 +0300705static int req_intf(struct sigma_cmd *cmd)
706{
707 return get_param(cmd, "interface") == NULL ? -1 : 0;
708}
709
710
Anurag Das2052daa2018-08-31 14:35:25 +0530711static int req_role_svcname(struct sigma_cmd *cmd)
712{
713 if (!get_param(cmd, "BLERole"))
714 return -1;
715 if (get_param(cmd, "BLEOp") && !get_param(cmd, "ServiceName"))
716 return -1;
717 return 0;
718}
719
720
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200721static int req_intf_prog(struct sigma_cmd *cmd)
722{
723 if (get_param(cmd, "interface") == NULL)
724 return -1;
725 if (get_param(cmd, "program") == NULL)
726 return -1;
727 return 0;
728}
729
730
Jouni Malinend86e5822017-08-29 03:55:32 +0300731static int req_prog(struct sigma_cmd *cmd)
732{
733 if (get_param(cmd, "program") == NULL)
734 return -1;
735 return 0;
736}
737
738
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200739void dev_register_cmds(void)
740{
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +0300741 sigma_dut_reg_cmd("dev_send_frame", req_prog, cmd_dev_send_frame);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200742 sigma_dut_reg_cmd("dev_set_parameter", req_intf_prog,
743 cmd_dev_set_parameter);
Jouni Malinend86e5822017-08-29 03:55:32 +0300744 sigma_dut_reg_cmd("dev_exec_action", req_prog,
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -0700745 cmd_dev_exec_action);
Jouni Malinen3c367e82017-06-23 17:01:47 +0300746 sigma_dut_reg_cmd("dev_configure_ie", req_intf, cmd_dev_configure_ie);
Peng Xua7ac56e2018-06-26 16:07:19 -0700747 sigma_dut_reg_cmd("dev_start_test", NULL, cmd_dev_start_test);
748 sigma_dut_reg_cmd("dev_stop_test", NULL, cmd_dev_stop_test);
749 sigma_dut_reg_cmd("dev_get_log", NULL, cmd_dev_get_log);
Anurag Das2052daa2018-08-31 14:35:25 +0530750 sigma_dut_reg_cmd("dev_ble_action", req_role_svcname,
751 cmd_dev_ble_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200752}