/*
 * Sigma Control API DUT (station/AP/sniffer)
 * Copyright (c) 2011-2013, 2017, Qualcomm Atheros, Inc.
 * Copyright (c) 2018-2019, The Linux Foundation
 * All Rights Reserved.
 * Licensed under the Clear BSD license. See README for more details.
 */

#include "sigma_dut.h"
#include <ctype.h>
#include "miracast.h"
#include <sys/wait.h>
#include "wpa_ctrl.h"
#include "wpa_helpers.h"


extern char *sigma_cert_path;


static enum sigma_cmd_result cmd_dev_send_frame(struct sigma_dut *dut,
						struct sigma_conn *conn,
						struct sigma_cmd *cmd)
{
#ifdef MIRACAST
	const char *program = get_param(cmd, "Program");

	if (program && (strcasecmp(program, "WFD") == 0 ||
			strcasecmp(program, "DisplayR2") == 0))
		return miracast_dev_send_frame(dut, conn, cmd);
#endif /* MIRACAST */

	if (dut->mode == SIGMA_MODE_STATION ||
	    dut->mode == SIGMA_MODE_UNKNOWN) {
		sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert "
				"dev_send_frame to sta_send_frame");
		return cmd_sta_send_frame(dut, conn, cmd);
	}

	if (dut->mode == SIGMA_MODE_AP) {
		sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert "
				"dev_send_frame to ap_send_frame");
		return cmd_ap_send_frame(dut, conn, cmd);
	}

#ifdef CONFIG_WLANTEST
	sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert dev_send_frame to "
			"wlantest_send_frame");
	return cmd_wlantest_send_frame(dut, conn, cmd);
#else /* CONFIG_WLANTEST */
	send_resp(dut, conn, SIGMA_ERROR,
		  "errorCode,Unsupported dev_send_frame");
	return STATUS_SENT;
#endif /* CONFIG_WLANTEST */
}


static enum sigma_cmd_result cmd_dev_set_parameter(struct sigma_dut *dut,
						   struct sigma_conn *conn,
						   struct sigma_cmd *cmd)
{
	const char *device = get_param(cmd, "Device");

	if (device && strcasecmp(device, "STA") == 0) {
		sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert "
				"dev_set_parameter to sta_set_parameter");
		return cmd_sta_set_parameter(dut, conn, cmd);
	}

	return INVALID_SEND_STATUS;
}


static enum sigma_cmd_result sta_server_cert_trust(struct sigma_dut *dut,
						   struct sigma_conn *conn,
						   const char *val)
{
	char buf[200];
	struct wpa_ctrl *ctrl = NULL;
	int e;
	char resp[200];
	int num_disconnected = 0;
	int tod = -1;

	strlcpy(resp, "ServerCertTrustResult,Accepted", sizeof(resp));

	if (strcasecmp(val, "Accept") != 0 && strcasecmp(val, "Reject") != 0) {
		sigma_dut_print(dut, DUT_MSG_INFO,
				"Unknown ServerCertTrust value '%s'", val);
		return INVALID_SEND_STATUS;
	}

	snprintf(buf, sizeof(buf), "%s/uosc-disabled", sigma_cert_path);
	if (file_exists(buf)) {
		strlcpy(resp,
			"ServerCertTrustResult,OverrideNotAllowed,Reason,UOSC disabled on device",
			sizeof(resp));
		goto done;
	}

	if (!dut->server_cert_hash[0]) {
		strlcpy(resp,
			"ServerCertTrustResult,OverrideNotAllowed,Reason,No server certificate stored",
			sizeof(resp));
		goto done;
	}

	if (dut->sta_tod_policy) {
		strlcpy(resp,
			"ServerCertTrustResult,OverrideNotAllowed,Reason,TOD policy",
			sizeof(resp));
		goto done;
	}

	if (dut->server_cert_tod == 1) {
		strlcpy(resp,
			"ServerCertTrustResult,OverrideNotAllowed,Reason,TOD-STRICT policy in received server certificate",
			sizeof(resp));
		goto done;
	}

	if (strcasecmp(val, "Accept") != 0) {
		strlcpy(resp, "ServerCertTrustResult,Rejected", sizeof(resp));
		goto done;
	}

	snprintf(buf, sizeof(buf), "hash://server/sha256/%s",
		 dut->server_cert_hash);
	if (set_network_quoted(get_station_ifname(dut), dut->infra_network_id,
			       "ca_cert", buf) < 0) {
		strlcpy(resp,
			"ServerCertTrustResult,OverrideNotAllowed,Reason,Could not configure server certificate hash for the network profile",
			sizeof(resp));
		goto done;
	}

	if (set_network(get_station_ifname(dut), dut->infra_network_id,
			"domain_match", "NULL") < 0 ||
	    set_network(get_station_ifname(dut), dut->infra_network_id,
			"domain_suffix_match", "NULL") < 0) {
		strlcpy(resp,
			"ServerCertTrustResult,OverrideNotAllowed,Reason,Could not clear domain matching rules",
			sizeof(resp));
		goto done;
	}

	wpa_command(get_station_ifname(dut), "DISCONNECT");
	snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", dut->infra_network_id);
	if (wpa_command(get_station_ifname(dut), buf) < 0) {
		sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
				"network id %d on %s",
				dut->infra_network_id,
				get_station_ifname(dut));
		strlcpy(resp,
			"ServerCertTrustResult,Accepted,Result,Could not request reconnection",
			sizeof(resp));
		goto done;
	}

	ctrl = open_wpa_mon(get_station_ifname(dut));
	if (!ctrl)
		goto done;

	for (e = 0; e < 20; e++) {
		const char *events[] = {
			"CTRL-EVENT-EAP-PEER-CERT",
			"CTRL-EVENT-EAP-TLS-CERT-ERROR",
			"CTRL-EVENT-DISCONNECTED",
			"CTRL-EVENT-CONNECTED",
			NULL
		};
		char buf[1024];
		int res;

		res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
		if (res < 0) {
			strlcpy(resp,
				"ServerCertTrustResult,Accepted,Result,Association did not complete",
				sizeof(resp));
			goto done;
		}
		sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
				buf);


		if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
		    strstr(buf, " depth=0")) {
			char *pos = strstr(buf, " hash=");

			if (pos) {
				if (strstr(buf, " tod=1"))
					tod = 1;
				else if (strstr(buf, " tod=2"))
					tod = 2;
				else
					tod = 0;
				sigma_dut_print(dut, DUT_MSG_DEBUG,
						"Server certificate TOD policy: %d",
						tod);
				dut->server_cert_tod = tod;
			}
		}

		if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
			strlcpy(resp,
				"ServerCertTrustResult,Accepted,Result,TLS server certificate validation failed with updated profile",
				sizeof(resp));
			goto done;
		}

		if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
			num_disconnected++;

			if (num_disconnected > 2) {
				strlcpy(resp,
					"ServerCertTrustResult,Accepted,Result,Connection failed",
					sizeof(resp));
				goto done;
			}
		}

		if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
			if (tod >= 0) {
				sigma_dut_print(dut, DUT_MSG_DEBUG,
						"Network profile TOD policy update: %d -> %d",
						dut->sta_tod_policy, tod);
				dut->sta_tod_policy = tod;
			}
			strlcpy(resp,
				"ServerCertTrustResult,Accepted,Result,Connected",
				sizeof(resp));
			break;
		}
	}

done:
	if (ctrl) {
		wpa_ctrl_detach(ctrl);
		wpa_ctrl_close(ctrl);
	}

	send_resp(dut, conn, SIGMA_COMPLETE, resp);
	return STATUS_SENT;
}


static enum sigma_cmd_result dev_exec_key_rotation(struct sigma_dut *dut,
						   struct sigma_conn *conn,
						   struct sigma_cmd *cmd)
{
	if (dut->mode == SIGMA_MODE_AP ||
	    dut->mode == SIGMA_MODE_UNKNOWN) {
		const char *ifname;

		ifname = get_hostapd_ifname(dut);
		if (hapd_command(ifname, "REKEY_GTK") < 0) {
			send_resp(dut, conn, SIGMA_ERROR,
				  "errorCode,Failed to request hostapd to rekey GTK");
			return STATUS_SENT_ERROR;
		}
		return SUCCESS_SEND_STATUS;
	} else if (dut->mode == SIGMA_MODE_STATION) {
		const char *intf = get_param(cmd, "Interface");

		if (!intf)
			intf = get_main_ifname(dut);
		if (wpa_command(intf, "KEY_REQUEST 0 0") != 0) {
			send_resp(dut, conn, SIGMA_ERROR,
				  "errorCode,Failed to request wpa_supplicant to request AP to rekey GTK");
			return STATUS_SENT_ERROR;
		}
		return SUCCESS_SEND_STATUS;
	} else {
		send_resp(dut, conn, SIGMA_ERROR,
			  "errorCode,Unsupported mode for KeyRotation,1");
		return STATUS_SENT_ERROR;
	}
}


static enum sigma_cmd_result wpa3_dev_exec_action(struct sigma_dut *dut,
						  struct sigma_conn *conn,
						  struct sigma_cmd *cmd)
{
	const char *val;
	char buf[4000], buf2[100], *pos, *end;

	val = get_param(cmd, "Rejected_DH_Groups");
	if (val) {
		val = get_param(cmd, "Dest_MAC");
		if (!val)
			return ERROR_SEND_STATUS;
		snprintf(buf2, sizeof(buf2), "STA %s", val);
		if (wpa_command_resp(dut->hostapd_ifname, buf2,
				     buf, sizeof(buf)) < 0)
			return ERROR_SEND_STATUS;
		pos = buf;
		while (pos) {
			if (strncmp(pos, "sae_rejected_groups=", 20) == 0)
				break;
			pos = strchr(pos, '\n');
			if (pos)
				pos++;
		}
		if (pos) {
			pos += 20;
			end = strchr(pos, '\n');
			if (end)
				*end = '\0';
		}
		snprintf(buf2, sizeof(buf2), "DHGroupVerResult,%s",
			 pos ? pos : "");
		send_resp(dut, conn, SIGMA_COMPLETE, buf2);
		return STATUS_SENT;
	}

	val = get_param(cmd, "KeyRotation");
	if (val && atoi(val) == 1)
		return dev_exec_key_rotation(dut, conn, cmd);

	return ERROR_SEND_STATUS;
}


static enum sigma_cmd_result cmd_dev_exec_action(struct sigma_dut *dut,
						 struct sigma_conn *conn,
						 struct sigma_cmd *cmd)
{
	const char *program = get_param(cmd, "Program");
	const char *val;

#ifdef MIRACAST
	if (program && (strcasecmp(program, "WFD") == 0 ||
			strcasecmp(program, "DisplayR2") == 0)) {
		if (get_param(cmd, "interface") == NULL)
			return INVALID_SEND_STATUS;
		return miracast_dev_exec_action(dut, conn, cmd);
	}
#endif /* MIRACAST */

	if (program && strcasecmp(program, "DPP") == 0)
		return dpp_dev_exec_action(dut, conn, cmd);

	val = get_param(cmd, "ServerCertTrust");
	if (val)
		return sta_server_cert_trust(dut, conn, val);

	if (program && strcasecmp(program, "WPA3") == 0)
		return wpa3_dev_exec_action(dut, conn, cmd);

	return ERROR_SEND_STATUS;
}


static enum sigma_cmd_result cmd_dev_configure_ie(struct sigma_dut *dut,
						  struct sigma_conn *conn,
						  struct sigma_cmd *cmd)
{
	const char *ie_name = get_param(cmd, "IE_Name");
	const char *contents = get_param(cmd, "Contents");

	if (!ie_name || !contents)
		return INVALID_SEND_STATUS;

	if (strcasecmp(ie_name, "RSNE") != 0) {
		send_resp(dut, conn, SIGMA_ERROR,
			  "errorCode,Unsupported IE_Name value");
		return STATUS_SENT;
	}

	free(dut->rsne_override);
	dut->rsne_override = strdup(contents);

	return dut->rsne_override ? SUCCESS_SEND_STATUS : ERROR_SEND_STATUS;
}


static enum sigma_cmd_result cmd_dev_ble_action(struct sigma_dut *dut,
						struct sigma_conn *conn,
						struct sigma_cmd *cmd)
{
#ifdef ANDROID
	const char *ble_op = get_param(cmd, "BLEOp");
	const char *prog = get_param(cmd, "Prog");
	const char *service_name = get_param(cmd, "ServiceName");
	const char *ble_role = get_param(cmd, "BLERole");
	const char *discovery_type = get_param(cmd, "DiscoveryType");
	const char *msg_type = get_param(cmd, "messagetype");
	const char *action = get_param(cmd, "action");
	const char *M2Transmit = get_param(cmd, "M2Transmit");
	char *argv[17];
	pid_t pid;

	if (prog && ble_role && action && msg_type) {
		send_resp(dut, conn, SIGMA_COMPLETE,
			  "OrgID,0x00,TransDataHeader,0x00,BloomFilterElement,NULL");
		return STATUS_SENT;
	}
	if (!ble_op || !prog || !service_name || !ble_role || !discovery_type) {
		sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid arguments");
		return INVALID_SEND_STATUS;
	}

	if ((strcasecmp(prog, "NAN") != 0)) {
		sigma_dut_print(dut, DUT_MSG_ERROR, "Program %s not supported",
				prog);
		return INVALID_SEND_STATUS;
	}

	if (strcasecmp(ble_role, "seeker") != 0 &&
	    strcasecmp(ble_role, "provider") != 0 &&
	    strcasecmp(ble_role, "browser") != 0) {
		sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid BLERole: %s",
				ble_role);
		return INVALID_SEND_STATUS;
	}

	if (strcasecmp(discovery_type, "active") != 0 &&
	    strcasecmp(discovery_type, "passive") != 0) {
		sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid DiscoveryType: %s",
				discovery_type);
		return INVALID_SEND_STATUS;
	}

	if (!M2Transmit)
		M2Transmit = "disable";

	argv[0] = "am";
	argv[1] = "start";
	argv[2] = "-n";
	argv[3] = "org.codeaurora.nanservicediscovery/org.codeaurora.nanservicediscovery.MainActivity";
	argv[4] = "--es";
	argv[5] = "service";
	argv[6] = (char *) service_name;
	argv[7] = "--es";
	argv[8] = "role";
	argv[9] = (char *) ble_role;
	argv[10] = "--es";
	argv[11] = "scantype";
	argv[12] = (char *) discovery_type;
	argv[13] = "--es";
	argv[14] = "M2Transmit";
	argv[15] = (char *) M2Transmit;
	argv[16] = NULL;

	pid = fork();
	if (pid == -1) {
		sigma_dut_print(dut, DUT_MSG_ERROR, "fork: %s",
				strerror(errno));
		return ERROR_SEND_STATUS;
	}

	if (pid == 0) {
		execv("/system/bin/am", argv);
		sigma_dut_print(dut, DUT_MSG_ERROR, "execv: %s",
				strerror(errno));
		exit(0);
		return ERROR_SEND_STATUS;
	}

	dut->nanservicediscoveryinprogress = 1;
#endif /* ANDROID */

	return SUCCESS_SEND_STATUS;
}


/* Runtime ID must contain only numbers */
static int is_runtime_id_valid(struct sigma_dut *dut, const char *val)
{
	int i;

	for (i = 0; val[i] != '\0'; i++) {
		if (!isdigit(val[i])) {
			sigma_dut_print(dut, DUT_MSG_DEBUG,
					"Invalid Runtime_ID %s", val);
			return 0;
		}
	}

	return 1;
}


static int build_log_dir(struct sigma_dut *dut, char *dir, size_t dir_size)
{
	int res;
	const char *vendor = dut->vendor_name;
	int i;

	if (!vendor)
		return -1;

	if (dut->log_file_dir) {
		res = snprintf(dir, dir_size, "%s/%s", dut->log_file_dir,
			       vendor);
	} else {
#ifdef ANDROID
		res = snprintf(dir, dir_size, "/data/vendor/wifi/%s",
			       vendor);
#else /* ANDROID */
		res = snprintf(dir, dir_size, "/var/log/%s", vendor);
#endif /* ANDROID */
	}

	if (res < 0 || res >= dir_size)
		return -1;

	/* Check for valid vendor name in log dir path since the log dir
	 * (/var/log/vendor) is deleted in dev_stop routine. This check is to
	 * avoid any unintended file deletion.
	 */
	for (i = 0; vendor[i] != '\0'; i++) {
		if (!isalpha(vendor[i])) {
			sigma_dut_print(dut, DUT_MSG_DEBUG,
					"Invalid char %c in vendor name %s",
					vendor[i], vendor);
			return -1;
		}
	}

	return 0;
}


/* User has to redirect wpa_supplicant logs to the following file. */
#ifndef WPA_SUPPLICANT_LOG_FILE
#define WPA_SUPPLICANT_LOG_FILE "/var/log/supplicant_log/wpa_log.txt"
#endif /* WPA_SUPPLICANT_LOG_FILE */

static enum sigma_cmd_result cmd_dev_start_test(struct sigma_dut *dut,
						struct sigma_conn *conn,
						struct sigma_cmd *cmd)
{
	const char *val;
	char buf[250];
	char dir[200];
	FILE *supp_log;
	int res;

	val = get_param(cmd, "Runtime_ID");
	if (!(val && is_runtime_id_valid(dut, val)))
		return INVALID_SEND_STATUS;

	if (!dut->vendor_name) {
		sigma_dut_print(dut, DUT_MSG_INFO,
				"Log collection not supported without vendor name specified on the command line (-N)");
		return SUCCESS_SEND_STATUS;
	}

	if (build_log_dir(dut, dir, sizeof(dir)) < 0)
		return ERROR_SEND_STATUS;

	supp_log = fopen(WPA_SUPPLICANT_LOG_FILE, "r");
	if (!supp_log) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Failed to open wpa_log file %s",
				WPA_SUPPLICANT_LOG_FILE);
	} else {
		/* Get the wpa_supplicant log file size */
		if (fseek(supp_log, 0, SEEK_END))
			sigma_dut_print(dut, DUT_MSG_ERROR,
					"Failed to get file size for read");
		else
			dut->wpa_log_size = ftell(supp_log);

		fclose(supp_log);
	}

	strlcpy(dut->dev_start_test_runtime_id, val,
		sizeof(dut->dev_start_test_runtime_id));
	sigma_dut_print(dut, DUT_MSG_DEBUG, "Runtime_ID %s",
			dut->dev_start_test_runtime_id);

	run_system_wrapper(dut, "rm -rf %s", dir);
	run_system_wrapper(dut, "mkdir -p %s", dir);

#ifdef ANDROID
	run_system_wrapper(dut, "logcat -v time > %s/logcat_%s.txt &",
			   dir, dut->dev_start_test_runtime_id);
#else /* ANDROID */
	/* Open log file for sigma_dut logs. This is not needed for Android, as
	 * we are already collecting logcat. */
	res = snprintf(buf, sizeof(buf), "%s/sigma_%s.txt", dir,
		       dut->dev_start_test_runtime_id);
	if (res >= 0 && res < sizeof(buf)) {
		if (dut->log_file_fd)
			fclose(dut->log_file_fd);

		dut->log_file_fd = fopen(buf, "a");
		if (!dut->log_file_fd)
			sigma_dut_print(dut, DUT_MSG_ERROR,
					"Failed to create sigma_dut log %s",
					buf);
	}

	run_system_wrapper(dut, "killall -9 cnss_diag_lite");
	run_system_wrapper(dut,
			   "cnss_diag_lite -c -x 31 > %s/cnss_diag_id_%s.txt &",
			   dir, dut->dev_start_test_runtime_id);
#endif /* ANDROID */

	return SUCCESS_SEND_STATUS;
}


static int is_allowed_char(char ch)
{
	return strchr("./-_", ch) != NULL;
}


static int is_destpath_valid(struct sigma_dut *dut, const char *val)
{
	int i;

	for (i = 0; val[i] != '\0'; i++) {
		if (!(isalnum(val[i]) || is_allowed_char(val[i]))) {
			sigma_dut_print(dut, DUT_MSG_DEBUG,
					"Invalid char %c in destpath %s",
					val[i], val);
			return 0;
		}
	}

	return 1;
}


#ifndef ANDROID
#define SUPP_LOG_BUFF_SIZE 4 * 1024

static int save_supplicant_log(struct sigma_dut *dut)
{
	char dir[200];
	char buf[300];
	FILE *wpa_log = NULL;
	FILE *supp_log;
	char *buff_ptr = NULL;
	unsigned int file_size;
	unsigned int file_size_orig;
	int status = -1, res;

	if (build_log_dir(dut, dir, sizeof(dir)) < 0)
		return -1;

	res = snprintf(buf, sizeof(buf), "%s/wpa_supplicant_log_%s.txt", dir,
		       dut->dev_start_test_runtime_id);
	if (res < 0 || res >= sizeof(buf))
		return -1;

	supp_log = fopen(WPA_SUPPLICANT_LOG_FILE, "r");
	if (!supp_log) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Failed to open wpa_log file %s",
				WPA_SUPPLICANT_LOG_FILE);
		return -1;
	}

	/* Get the wpa_supplicant log file size */
	if (fseek(supp_log, 0, SEEK_END)) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Failed to get file size for read");
		goto exit;
	}
	file_size_orig = ftell(supp_log);

	if (file_size_orig < dut->wpa_log_size) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"file size err, new size %u, old size %u",
				file_size_orig, dut->wpa_log_size);
		goto exit;
	}

	/* Get the wpa_supplicant file size for current test */
	file_size = file_size_orig - dut->wpa_log_size;

	wpa_log = fopen(buf, "w");
	if (!wpa_log) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Failed to create tmp wpa_log file %s", buf);
		goto exit;
	}

	if (fseek(supp_log, dut->wpa_log_size, SEEK_SET)) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Failed to set wpa_log file ptr for read");
		goto exit;
	}

	buff_ptr = malloc(SUPP_LOG_BUFF_SIZE);
	if (!buff_ptr) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Failed to alloc buffer of size %d",
				SUPP_LOG_BUFF_SIZE);
		goto exit;
	}

	/* Read wpa_supplicant log file in 4K byte chunks */
	do {
		unsigned int num_bytes_to_read;
		unsigned int bytes_read;

		num_bytes_to_read = (file_size > SUPP_LOG_BUFF_SIZE) ?
			SUPP_LOG_BUFF_SIZE : file_size;
		bytes_read = fread(buff_ptr, 1, num_bytes_to_read, supp_log);
		if (!bytes_read) {
			sigma_dut_print(dut, DUT_MSG_ERROR,
					"Failed to read wpa_supplicant log");
			goto exit;
		}
		if (bytes_read != num_bytes_to_read) {
			sigma_dut_print(dut, DUT_MSG_DEBUG,
					"wpa_supplicant log read err, read %d, num_bytes_to_read %d",
					bytes_read, num_bytes_to_read);
			goto exit;
		}
		fwrite(buff_ptr, 1, bytes_read, wpa_log);
		file_size -= bytes_read;
	} while (file_size > 0);
	status = 0;

exit:
	if (wpa_log)
		fclose(wpa_log);
	fclose(supp_log);
	free(buff_ptr);

	return status;
}
#endif /* !ANDROID */


static enum sigma_cmd_result cmd_dev_stop_test(struct sigma_dut *dut,
					       struct sigma_conn *conn,
					       struct sigma_cmd *cmd)
{
	const char *val;
	char buf[300];
	char out_file[100];
	char dir[200];
	int res;

	if (!dut->vendor_name) {
		sigma_dut_print(dut, DUT_MSG_INFO,
				"Log collection not supported without vendor name specified on the command line (-N)");
		return SUCCESS_SEND_STATUS;
	}

	val = get_param(cmd, "Runtime_ID");
	if (!val || strcmp(val, dut->dev_start_test_runtime_id) != 0) {
		sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid runtime id");
		return ERROR_SEND_STATUS;
	}

	if (build_log_dir(dut, dir, sizeof(dir)) < 0)
		return ERROR_SEND_STATUS;

#ifdef ANDROID
	/* Copy all cnss_diag logs to dir */
	run_system_wrapper(dut, "cp -a /data/vendor/wifi/wlan_logs/* %s", dir);
#else /* ANDROID */
	if (dut->log_file_fd) {
		fclose(dut->log_file_fd);
		dut->log_file_fd = NULL;
	}
	if (save_supplicant_log(dut))
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Failed to save wpa_supplicant log");
#endif /* ANDROID */

	res = snprintf(out_file, sizeof(out_file), "%s_%s_%s.tar.gz",
		       dut->vendor_name,
		       dut->model_name ? dut->model_name : "Unknown",
		       dut->dev_start_test_runtime_id);
	if (res < 0 || res >= sizeof(out_file))
	    return ERROR_SEND_STATUS;

	if (run_system_wrapper(dut, "tar -czvf %s/../%s %s", dir, out_file,
			       dir) < 0) {
		sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to create tar: %s",
				buf);
		return ERROR_SEND_STATUS;
	}

	val = get_param(cmd, "destpath");
	if (!(val && is_destpath_valid(dut, val))) {
		sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid path for TFTP %s",
				val);
		return ERROR_SEND_STATUS;
	}

	res = snprintf(buf, sizeof(buf), "tftp %s -c put %s/%s %s/%s",
		       inet_ntoa(conn->addr.sin_addr), dir, out_file, val,
		       out_file);
	if (res < 0 || res >= sizeof(buf))
		return ERROR_SEND_STATUS;
	if (run_system_wrapper(dut, buf) < 0) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"TFTP file transfer failed: %s", buf);
		return ERROR_SEND_STATUS;
	}
	sigma_dut_print(dut, DUT_MSG_DEBUG, "TFTP file transfer: %s", buf);
	snprintf(buf, sizeof(buf), "filename,%s", out_file);
	send_resp(dut, conn, SIGMA_COMPLETE, buf);
	run_system_wrapper(dut, "rm -f %s/../%s", dir, out_file);
	run_system_wrapper(dut, "rm -rf %s", dir);

	return SUCCESS_SEND_STATUS;
}


static enum sigma_cmd_result cmd_dev_get_log(struct sigma_dut *dut,
					     struct sigma_conn *conn,
					     struct sigma_cmd *cmd)
{
	return SUCCESS_SEND_STATUS;
}


static int req_intf(struct sigma_cmd *cmd)
{
	return get_param(cmd, "interface") == NULL ? -1 : 0;
}


static int req_role_svcname(struct sigma_cmd *cmd)
{
	if (!get_param(cmd, "BLERole"))
		 return -1;
	if (get_param(cmd, "BLEOp") && !get_param(cmd, "ServiceName"))
		return -1;
	return 0;
}


static int req_intf_prog(struct sigma_cmd *cmd)
{
	if (get_param(cmd, "interface") == NULL)
		return -1;
	if (get_param(cmd, "program") == NULL)
		return -1;
	return 0;
}


static int req_prog(struct sigma_cmd *cmd)
{
	if (get_param(cmd, "program") == NULL)
		return -1;
	return 0;
}


void dev_register_cmds(void)
{
	sigma_dut_reg_cmd("dev_send_frame", req_prog, cmd_dev_send_frame);
	sigma_dut_reg_cmd("dev_set_parameter", req_intf_prog,
			  cmd_dev_set_parameter);
	sigma_dut_reg_cmd("dev_exec_action", req_prog,
			  cmd_dev_exec_action);
	sigma_dut_reg_cmd("dev_configure_ie", req_intf, cmd_dev_configure_ie);
	sigma_dut_reg_cmd("dev_start_test", NULL, cmd_dev_start_test);
	sigma_dut_reg_cmd("dev_stop_test", NULL, cmd_dev_stop_test);
	sigma_dut_reg_cmd("dev_get_log", NULL, cmd_dev_get_log);
	sigma_dut_reg_cmd("dev_ble_action", req_role_svcname,
			  cmd_dev_ble_action);
}
