/*
 * Sigma Control API DUT - Miracast interface
 * Copyright (c) 2017, Qualcomm Atheros, Inc.
 * Copyright (c) 2018, The Linux Foundation
 * All Rights Reserved.
 * Licensed under the Clear BSD license. See README for more details.
 *
 * Implementation of MIRACAST specific functionality.
 * For example, starting wfd session.
*/

#include "sigma_dut.h"
#include <dlfcn.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include "wpa_ctrl.h"
#include "wpa_helpers.h"
#include "miracast.h"
#ifdef ANDROID
#include "properties.h"
#ifndef MIRACAST_DHCP_M
#include <netutils/ifc.h>
#endif /* MIRACAST_DHCP_M */
#endif /* ANDROID */

#define HUNDRED_SECOND_TIMEOUT   100 /* 100 seconds */
#define DHCP_LEASE_FILE_PATH "/data/misc/dhcp/dnsmasq.leases"
#define MIRACAST_CMD_LEN         512

extern char *sigma_main_ifname;
extern char *sigma_station_ifname;

static int session_management_control_port = 7236;
/* Followingng stores p2p interface name after P2P group formation */
static char wfd_ifname[32];

#ifndef MIRACAST_DHCP_M
extern void get_dhcp_info(uint32_t *ipaddr, uint32_t *gateway,
			  uint32_t *prefixLength, uint32_t *dns1,
			  uint32_t *dns2, uint32_t *server,
			  uint32_t *lease);

extern int do_dhcp(char *);

const char *ipaddr (in_addr_t addr)
{
	struct in_addr in_addr;
	in_addr.s_addr = addr;
	return inet_ntoa(in_addr);
}
#endif /* MIRACAST_DHCP_M */




static int miracast_load(struct sigma_dut *dut)
{
	static int once = 1;

	if (!once)
		return 0;

	once = 0;
	dlerror();
	dut->miracast_lib = dlopen(dut->miracast_lib_path ?
				   dut->miracast_lib_path : "libmiracast.so",
				   RTLD_LAZY);
	if (!dut->miracast_lib) {
		sigma_dut_print(dut, DUT_MSG_INFO,
				"Fail to load Miracast library %s",
				dlerror());
		return -1;
	}
	sigma_dut_print(dut, DUT_MSG_INFO,
			"Miracast Wi-Fi Display library found - starting service");
	return 0;
}


static int miracast_unload(struct sigma_dut *dut)
{
	int err;

	if (!dut->miracast_lib)
		return -1;

	dlerror();
	sigma_dut_print(dut, DUT_MSG_INFO, "Unloading Miracast library");
	err = dlclose(dut->miracast_lib);
	dut->miracast_lib = NULL;
	if (err == 0) {
		sigma_dut_print(dut, DUT_MSG_INFO,
			 "Miracast library successfully unloaded");
	} else {
		sigma_dut_print(dut, DUT_MSG_INFO,
			"Failed to unload Miracast library");
	}
	return err;
}


static int get_peer_ip_p2p_go(struct sigma_dut *dut, char *ipaddr,
			      const char *macaddr, unsigned int wait_limit)
{

	FILE *fp;

	fp = fopen(DHCP_LEASE_FILE_PATH, "r");
	if (!fp) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Could not open DHCP lease file");
		return -1;
	}

	sigma_dut_print(dut, DUT_MSG_INFO, "macaddress %s", macaddr);
	while (wait_limit > 0) {
		char line[100] = { 0 };
		char *str1 = NULL;
		char *dummy_str = NULL;
		char dummy_macaddress[32];
		int ip_found = 0;
		int len;

		fseek(fp, 0, SEEK_SET);
		while (fgets(line, sizeof(line), fp) != NULL) {
			len = strlen(line);
			if (len == 0)
				continue;

			str1 = strtok_r(line, " ", &dummy_str);
			if (str1 == NULL)
				break;

			/* Look for mac address */
			str1 = strtok_r(NULL, " ", &dummy_str);
			if (str1 == NULL)
				break;

			strlcpy(dummy_macaddress, str1,
				sizeof(dummy_macaddress));

			/* Look for ip address */
			str1 = strtok_r(NULL, " ", &dummy_str);
			if (str1 == NULL)
				break;

			strlcpy(ipaddr,str1,32);

			sigma_dut_print(dut, DUT_MSG_INFO,
					"Peer IP Address obtained and mac %s %s",
					ipaddr, dummy_macaddress);

			/*
			 * The idea is that the p2p mac address may differ by 1
			 * nibble mostly it is the first byte, hence try the
			 * middle two octets.
			 */
			if (strncasecmp(macaddr + 6, dummy_macaddress + 6,
					5) == 0) {
				ip_found = 1;
				sigma_dut_print(dut, DUT_MSG_INFO,
						"Obtained the IP address %s",
						ipaddr);
				break;
			}
		}

		if (ip_found)
			break;

		sigma_dut_print(dut, DUT_MSG_INFO,
				"Failed to find IP from DHCP lease file");
		sleep(1);
		wait_limit--;
	}
	fclose(fp);
	return 0;
}


static int miracast_start_dhcp_client(struct sigma_dut *dut, const char *ifname)
{
#ifdef MIRACAST_DHCP_M
	 start_dhcp(dut, ifname, 0);
#else /* MIRACAST_DHCP_M */
	int ret = ifc_init();

	sigma_dut_print(dut, DUT_MSG_DEBUG, "ifc init returned %d", ret);
	ret = do_dhcp((char *) ifname);
	sigma_dut_print(dut, DUT_MSG_DEBUG, "do dhcp returned %d", ret);
#endif /* MIRACAST_DHCP_M */
	return 0;
}


static void miracast_stop_dhcp_client(struct sigma_dut *dut, char *ifname)
{
#ifdef MIRACAST_DHCP_M
	stop_dhcp(dut, ifname, 0);
#else /* MIRACAST_DHCP_M */
	ifc_close();
#endif /* MIRACAST_DHCP_M */
}


#ifdef MIRACAST_DHCP_M

static int get_local_ip_address(struct sigma_dut *dut,
				char *local_ip_addr, size_t buflen,
				const char *intf, int size)
{
	struct ifreq ifr;
	int s;

	memset(&ifr, 0, sizeof(struct ifreq));
	strlcpy(ifr.ifr_name, intf, IFNAMSIZ);
	ifr.ifr_name[IFNAMSIZ-1] = 0;

	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		sigma_dut_print(dut, DUT_MSG_INFO,
				"%s: Error in creating socket", __func__);
		return -1;
	}

	if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
		sigma_dut_print(dut, DUT_MSG_INFO, "ioctl failed: %s",
				strerror(errno));
		close(s);
		return -1;
	}

	strlcpy(local_ip_addr,
		inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr),
		buflen);
	close(s);
	return 0;
}


static int get_peer_ip_p2p_client(struct sigma_dut *dut, char *ip_addr,
				  const char *intf, unsigned int wait_limit)
{
	char prop_name[128];
	char prop_name_self[128];
	char self_ip[128];

	memset(self_ip, 0, sizeof(self_ip));
	/* For P2P Client read the server property */
	snprintf(prop_name, sizeof(prop_name), "%s.%s.server", "dhcp", "p2p");
	snprintf(prop_name_self, sizeof(prop_name_self),
		 "%s.%s.ipaddress", "dhcp", "p2p");

	while (wait_limit > 0) {
#ifdef ANDROID
		property_get(prop_name, ip_addr, NULL);
#else /* ANDROID */
		ip_addr[0] = '\0';
#endif /* ANDROID */
		get_local_ip_address(dut, self_ip, sizeof(self_ip), intf, 20);
		sigma_dut_print(dut, DUT_MSG_INFO, "Peer IP, self IP: %s %s",
				ip_addr, self_ip);
		if (strlen(ip_addr) > 8 &&
		    ip_addr[0] == '1' && ip_addr[1] == '9' &&
		    self_ip[0] == '1' && self_ip[1] == '9')
			break; /* connected */

		/* What if DHCP server was started before Client was started?
		 * Request DHCP yet again */
		miracast_start_dhcp_client(dut, intf);
		sleep(5); /* Sleep always helps */
		wait_limit--;
	}

	return wait_limit > 0 ? 0 : -1;
}

#else /* MIRACAST_DHCP_M */

static int get_peer_ip_p2p_client(struct sigma_dut *dut, char *ipAddr,
				  const char *intf, unsigned int wait_limit)
{
	uint32_t ipaddress, gateway, prefixLength,
		dns1, dns2, serveraddr, lease;

	get_dhcp_info(&ipaddress, &gateway, &prefixLength, &dns1, &dns2,
		      &serveraddr, &lease);
	while (wait_limit > 0) {
		sigma_dut_print(dut, DUT_MSG_INFO, "Peer IP: %u", ipaddress);
		if (strlen(ipaddr(serveraddr)) > 8) {
			/* connected */
			strlcpy(ipAddr, ipaddr(serveraddr), 16);
			break;
		}
		sleep(1);
		wait_limit--;
	}
	return wait_limit == 0 ? -1 : 0;
}

#endif /* MIRACAST_DHCP_M */


static int get_p2p_connection_event(struct sigma_dut *dut,
				    const char *input_intf,
				    char *output_intf,
				    int size_output_intf,
				    int *is_group_owner)
{
	/*
	* Poll for the P2P Connection
	* Then poll for IP
	* Then poll for WFD session ID and exit
	* P2P connection done
	* Loop till connection is ready
	*/
	struct wpa_ctrl *ctrl;
	char *mode_string;
	char event_buf[256];
	char *ifname;
	char *pos;
	int res = 0;
	const char *events[] = {
		"P2P-GROUP-STARTED",
		"P2P-GO-NEG-FAILURE",
		"P2P-GROUP-FORMATION-FAILURE",
		NULL
	};

	/* Wait for WPA CLI EVENTS */
	/* Default timeout is 120s */
	ctrl = open_wpa_mon(input_intf);
	if (!ctrl) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Failed to open wpa_supplicant monitor connection");
		return -1;
	}

	res = get_wpa_cli_events(dut, ctrl, events, event_buf,
				 sizeof(event_buf));

	wpa_ctrl_detach(ctrl);
	wpa_ctrl_close(ctrl);

	if (res < 0) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Group formation did not complete");
		return -1;
	}

	sigma_dut_print(dut, DUT_MSG_DEBUG, "Received event %s", event_buf);

	if (strstr(event_buf, "P2P-GROUP-FORMATION-FAILURE") ||
	    strstr(event_buf, "P2P-GO-NEG-FAILURE"))
		return -1;

	sigma_dut_print(dut, DUT_MSG_INFO, "P2P connection done");
	ifname = strchr(event_buf, ' ');
	if (!ifname) {
		sigma_dut_print(dut, DUT_MSG_INFO, "No P2P interface found");
		return -1;
	}
	ifname++;
	pos = strchr(ifname, ' ');
	if (!pos) {
		sigma_dut_print(dut, DUT_MSG_ERROR, "No P2P interface found");
		return -1;
	}
	*pos++ = '\0';
	sigma_dut_print(dut, DUT_MSG_DEBUG, "Group interface %s", ifname);

	strlcpy(output_intf, ifname, size_output_intf);

	mode_string = pos;
	pos = strchr(mode_string, ' ');
	if (!pos) {
		sigma_dut_print(dut, DUT_MSG_ERROR, "No group role found");
		return -1;
	}

	*pos++ = '\0';
	sigma_dut_print(dut, DUT_MSG_DEBUG, "Group Role %s", mode_string);

	if (strcmp(mode_string, "GO") == 0)
		*is_group_owner = 1;
	sigma_dut_print(dut, DUT_MSG_DEBUG, "Value of is_group_owner %d",
			*is_group_owner);
	return 0;
}


/* Following serves as an entry point function to perform rtsp tasks */
static void * miracast_rtsp_thread_entry(void *ptr)
{
	struct sigma_dut *dut = ptr;
	char output_ifname[16];
	int is_group_owner = 0;
	const char *intf = sigma_station_ifname;
	unsigned int wait_limit;
	char peer_ip_address[32];
	char rtsp_session_id[12];
	int (*extn_start_wfd_connection)(const char *,
					 const char *, /* Peer IP */
					 int, /* RTSP port number */
					 int, /* WFD Device Type; 0-Source,
						 1-P-Sink, 2-Secondary Sink */
					 char *); /* for returning session ID */

	miracast_load(dut);

	if (sigma_main_ifname) {
		intf = sigma_main_ifname;
		sigma_dut_print(dut, DUT_MSG_DEBUG,
				"miracast_rtsp_thread_entry: sigma_main_ifname = [%s]",
				intf);
	} else {
		sigma_dut_print(dut, DUT_MSG_DEBUG,
				"miracast_rtsp_thread_entry: sigma_main_ifname is NULL");
	}

	if (get_p2p_connection_event(dut, intf, output_ifname,
				     sizeof(output_ifname),
				     &is_group_owner) < 0) {
		sigma_dut_print(dut, DUT_MSG_ERROR, "P2P connection failure");
		goto EXIT;
	}

	sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting to start dhcp");

	/* Calling WFD APIs now */
	/* If you are a source, go ahead and start the RTSP server */
	if (dut->wfd_device_type != 0)
		wait_limit = HUNDRED_SECOND_TIMEOUT;
	else
		wait_limit = 500;

	if (!is_group_owner) {
		sigma_dut_print(dut, DUT_MSG_INFO,
				"Waiting to start dhcp client");
		sleep(5); /* Wait for IP */
		miracast_start_dhcp_client(dut, output_ifname);
		sleep(5); /* Wait for IP */
		if (get_peer_ip_p2p_client(dut, peer_ip_address, output_ifname,
					   wait_limit) < 0) {
			sigma_dut_print(dut, DUT_MSG_ERROR,
					"Could not get peer IP");
			goto EXIT;
		}
	} else {
		stop_dhcp(dut, output_ifname, 1);
		/* For GO read the DHCP Lease File */
		sigma_dut_print(dut, DUT_MSG_INFO,
				"Waiting to start dhcp server");
		start_dhcp(dut, output_ifname, 1);
		sleep(5);
		if (get_peer_ip_p2p_go(dut, peer_ip_address,
				       dut->peer_mac_address, wait_limit) < 0) {
			sigma_dut_print(dut, DUT_MSG_ERROR,
					"Could not get peer IP");
			goto EXIT;
		}
	}

	extn_start_wfd_connection = dlsym(dut->miracast_lib,
					  "start_wfd_connection");
	if (extn_start_wfd_connection) {
		extn_start_wfd_connection(NULL, peer_ip_address,
					  session_management_control_port,
					  1 - dut->wfd_device_type,
					  rtsp_session_id);
	} else {
		sigma_dut_print(dut, DUT_MSG_INFO,
				"dlsym seems to have error %p %p",
				dut->miracast_lib, extn_start_wfd_connection);
	}

EXIT:
	sigma_dut_print(dut, DUT_MSG_INFO, "Reached Miracast thread exit");

	return NULL;
}


/*----------------------------------------------------------------------
  WFD Source IE: 000601101c440036
  len        WFD device info          control port              throughput
  110]    [00000 00100010 000]    [00011 10001000 100]    [00000 00000110 110]
				       = 7236

  WFD Sink IE: 000601511c440036
  len        WFD device info          control port              throughput
  110]    [00000 00101010 001]    [00011 10001000 100]    [00000 00000110 110]
				       = 7236

  WFD device info:
  BITS        NAME                DESCRIPTION
  -------------------------------------------
  1:0     WFD Device Type     0b00: WFD Source
			      0b01: Primary Sink
			      0b10: Secondary Sink
			      0b11: Dual Role, either WFD Source/Primary sink

  5:4     WFD Session         0b00: Not available for WFD Session
			Availibility	0b01: Available for WFD Session
							0b10, 0b11: Reserved

  6       WSD Support Bit     0b0: WFD Service Discovery not supported
			      0b1: WFD Service Discovery supported

  8       CP Support Bit      0b0: Content Protection via HDCP not supported
			      0b1: Content Protection via HDCP supported
---------------------------------------------------------------------------
*/

static void miracast_set_wfd_ie(struct sigma_dut *sigma_dut)
{
	char *intf = sigma_station_ifname;

	if (sigma_main_ifname != NULL)
		intf = sigma_main_ifname;

	sigma_dut_print(sigma_dut, DUT_MSG_DEBUG, "miracast_set_wfd_ie() = intf = %s",
			intf);
	wpa_command(intf, "SET wifi_display 1");

	if (sigma_dut->wfd_device_type == 0) {
		wpa_command(intf, "WFD_SUBELEM_SET 0 000601101c440036");
		wpa_command(intf, "WFD_SUBELEM_SET 11 00020000");
	} else {
		wpa_command(intf, "WFD_SUBELEM_SET 0 000601511c440036");
		wpa_command(intf, "WFD_SUBELEM_SET 11 00020001");
	}
}


void miracast_init(struct sigma_dut *dut)
{
	sigma_dut_print(dut, DUT_MSG_DEBUG, "Create thread pool for VDS");
	miracast_set_wfd_ie(dut);
	sigma_dut_print(dut, DUT_MSG_DEBUG, "Clear groupID @ start");
}


void miracast_deinit(struct sigma_dut *dut)
{
	(void) miracast_unload(dut);
}


static void miracast_generate_string_cmd(struct sigma_cmd *cmd, char *strcmd,
					 size_t size)
{
	int i = 0;
	char *pos, *end;
	int ret;

	if (!strcmd)
		return;
	strcmd[0] = '\0';
	pos = strcmd;
	end = strcmd + size;
	for (i = 0; i < cmd->count; i++) {
		ret = snprintf(pos, end - pos, "%s,%s,", cmd->params[i],
			       cmd->values[i]);
		if (ret < 0 || ret >= end - pos)
			break;
		pos += ret;
	}

	pos = strrchr(strcmd, ',');
	if (pos)
		*pos = '\0';
	printf("Miracast: generated command: %s\n", strcmd);
}


static void * auto_go_thread_entry(void *ptr)
{
	struct sigma_dut *dut = ptr;
	struct wpa_ctrl *ctrl;
	char event_buf[64];
	char *peer = NULL;
	int res = 0;
	char macaddress[32];
	char peer_ip_address[32];
	char rtsp_session_id[12];
	int (*extn_start_wfd_connection)(const char *,
					 const char *, /* Peer IP */
					 int, /* RTSP port number */
					 int, /* WFD Device Type; 0-Source,
						1-P-Sink, 2-Secondary Sink */
					 char *); /* for returning session ID */

	stop_dhcp(dut, wfd_ifname, 1);
	/* For auto-GO, start the DHCP server and wait for 5 seconds */
	start_dhcp(dut, wfd_ifname, 1);
	sleep(5); /* Wait for IP */

	sigma_dut_print(dut, DUT_MSG_INFO, "Wait for AP-STA-CONNECTED");
	ctrl = open_wpa_mon(wfd_ifname); /* Refer to wfd_ifname */
	if (!ctrl) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Failed to open wpa_supplicant monitor connection");
		goto THR_EXIT;
	}
	res = get_wpa_cli_event(dut, ctrl, "AP-STA-CONNECTED",
				event_buf, sizeof(event_buf));
	wpa_ctrl_detach(ctrl);
	wpa_ctrl_close(ctrl);

	if (res < 0) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Could not get event before timeout");
		goto THR_EXIT;
	}

	sigma_dut_print(dut, DUT_MSG_DEBUG, "STA Connected Event: '%s'",
			event_buf);
	peer = strchr(event_buf, ' ');
	if (!peer) {
		sigma_dut_print(dut, DUT_MSG_ERROR, "Could not find STA MAC");
		goto THR_EXIT;
	}

	peer++;
	strlcpy(macaddress, peer, sizeof(macaddress));
	if (get_peer_ip_p2p_go(dut, peer_ip_address, macaddress, 30) < 0) {
		sigma_dut_print(dut, DUT_MSG_ERROR, "Could not get peer IP");
		goto THR_EXIT;
	}

	sigma_dut_print(dut, DUT_MSG_INFO, "dlsym %p", dut->miracast_lib);
	extn_start_wfd_connection = dlsym(dut->miracast_lib,
					  "start_wfd_connection");
	if (!extn_start_wfd_connection)
		sigma_dut_print(dut, DUT_MSG_INFO, "dlsym function NULL");
	else
		extn_start_wfd_connection(NULL, peer_ip_address,
					  session_management_control_port,
					  1 - dut->wfd_device_type,
					  rtsp_session_id);

THR_EXIT:
	sigma_dut_print(dut, DUT_MSG_INFO, "Reached auto GO thread exit");
	return NULL;
}


void miracast_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
				struct sigma_cmd *cmd)
{
	char *intf = sigma_station_ifname;
	int (*extn_sta_reset_default)(char *);
	char string_cmd[MIRACAST_CMD_LEN] = { 0 };

	if (sigma_main_ifname != NULL)
		intf = sigma_main_ifname;
	sigma_dut_print(dut, DUT_MSG_DEBUG,
			"miracast_sta_reset_default() = intf = %s", intf);
	stop_dhcp(dut, intf, 1); /* IFNAME argument is ignored */
	miracast_stop_dhcp_client(dut, intf);

	/* This is where vendor Miracast library is loaded and function pointers
	 * to Miracast functions (defined by CAPI) are loaded. */

	if (miracast_load(dut) != 0) {
		sigma_dut_print(dut, DUT_MSG_INFO,
				"Fail to load Miracast library");
		return;
	}

	if (!dut->miracast_lib) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Miracast library is absent");
		return;
	}

	dlerror();

	miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd));
	extn_sta_reset_default = dlsym(dut->miracast_lib, "sta_reset_default");
	if (extn_sta_reset_default)
		extn_sta_reset_default(string_cmd);

	/* delete threads if any */
	/* TODO: if dut->rtsp_thread_handle running, call
	 * miracast_release_rtsp_thread_resources(dut); */
}


void miracast_start_autonomous_go(struct sigma_dut *dut,
				  struct sigma_conn *conn,
				  struct sigma_cmd *cmd, char *ifname)
{
	strlcpy(wfd_ifname, ifname, sizeof(wfd_ifname));
	(void) pthread_create(&dut->rtsp_thread_handle, NULL,
			      auto_go_thread_entry, dut);
}


static void miracast_rtsp_thread_create(struct sigma_dut *dut,
					struct sigma_conn *conn,
					struct sigma_cmd *cmd)
{
	(void) pthread_create(&dut->rtsp_thread_handle, NULL,
			      miracast_rtsp_thread_entry, dut);
}


int miracast_dev_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
			    struct sigma_cmd *cmd)
{
	const char *frame_name = get_param(cmd, "FrameName");
	/* const char *source = get_param(cmd, "Source"); */
	/* const char *destination = get_param(cmd, "Destination"); */
	/* const char *dev_type = get_param(cmd, "DevType"); */
	const char *rtsp_msg_type = get_param(cmd, "RtspMsgType");
	/* const char *wfd_session_id = get_param(cmd, "WfdSessionID"); */
	int (*dev_send_frame)(const char *);
	char string_cmd[MIRACAST_CMD_LEN] = { 0 };

	dev_send_frame = dlsym(dut->miracast_lib, "dev_send_frame");
	if (!dev_send_frame)
		return -1;
	sigma_dut_print(dut, DUT_MSG_DEBUG, "miracast_dev_send_frame 1");
	miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd));
	if (!frame_name)
		return 0;
	if (strcasecmp(frame_name, "RTSP") != 0)
		return 0;

	if (!rtsp_msg_type)
		return 0;

	if (strcasecmp(rtsp_msg_type, "PAUSE") == 0 ||
	    strcasecmp(rtsp_msg_type, "TRIGGER-PAUSE") == 0) {
		/* Call RTSP Pause */
		dev_send_frame(string_cmd);
		return 1;
	}

	if (strcasecmp(rtsp_msg_type, "PLAY") == 0 ||
	    strcasecmp(rtsp_msg_type, "TRIGGER-PLAY") == 0) {
		/* Call RTSP Play */;
		dev_send_frame(string_cmd); /* Not for secure playback */
		return 1;
	}

	if (strcasecmp(rtsp_msg_type, "TEARDOWN") == 0 ||
	    strcasecmp(rtsp_msg_type, "TRIGGER-TEARDOWN") == 0) {
		dev_send_frame(string_cmd); /* RTSP Teardown */
		return 1;
	}

	if (strcasecmp(rtsp_msg_type,"SET_PARAMETER") == 0) {
		const char *set_parameter = get_param(cmd, "SetParameter");
		const char *transportType = get_param(cmd, "TransportType");

		if (set_parameter == NULL && transportType == NULL) {
			send_resp(dut, conn, SIGMA_ERROR,
				  "errorCode,Invalid Set Parameter value");
			return 0;
		}

		if (1) /* (strcasecmp(set_parameter, "Standby") == 0) */ {
			dev_send_frame(string_cmd);
			return 1;
		}
		/* TODO More needs to be implemented when the spec is clearer */
		return 1;
	}

	if (strcasecmp(rtsp_msg_type, "SETUP") == 0) {
		dev_send_frame(string_cmd);
		/* TODO More needs to be implemented when the spec is clearer */
		return 1;
	}

	if (strcasecmp(frame_name, "WFD_ProbeReq") == 0) {
		send_resp(dut, conn, SIGMA_ERROR,
			  "errorCode,Unsupported WFD Probe Request");
		return 0;
	}

	if (strcasecmp(frame_name, "WFD_ServiceDiscReq") == 0) {
		send_resp(dut, conn, SIGMA_ERROR,
			  "errorCode,Unsupported WFD Service Discovery");
		return 0;
	}

	send_resp(dut, conn, SIGMA_ERROR,
		  "errorCode,Unsupported dev_send_frame");
	return 0;
}


int miracast_dev_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
			     struct sigma_cmd *cmd)
{
	const char *service_type = get_param(cmd,"ServiceType");
	int (*dev_exec_action)(const char *);
	char string_cmd[MIRACAST_CMD_LEN] = { 0 };

	sigma_dut_print(dut, DUT_MSG_DEBUG, "miracast_dev_exec_frame");

	if (service_type) {
		char resp_buf[128];

		sigma_dut_print(dut, DUT_MSG_DEBUG, "MDNS Instance Name = %s",
				dut->mdns_instance_name);
		strlcpy(resp_buf, "InstanceName,", sizeof(resp_buf));
		strlcat(resp_buf + strlen(resp_buf), dut->mdns_instance_name,
			sizeof(resp_buf) - strlen(resp_buf));
		send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
		return 0;
	}

	miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd));
	dev_exec_action = dlsym(dut->miracast_lib, "dev_exec_action");
	if (!dev_exec_action)
		return -2;
	return dev_exec_action(string_cmd);
}


int miracast_preset_testparameters(struct sigma_dut *dut,
				   struct sigma_conn *conn,
				   struct sigma_cmd *cmd)
{
	const char *mdns_disc = get_param(cmd, "mdns_disc");
	const char *mdns_role = get_param(cmd, "mdns_role");
	char string_cmd[MIRACAST_CMD_LEN];
	int ret = 0;
	char string_resp[64] = { 0 };
	int (*extn_sta_preset_test_parameter)(const char *, char *, int);

	miracast_load(dut);
	miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd));
	extn_sta_preset_test_parameter =
		dlsym(dut->miracast_lib, "sta_preset_testparameters");
	if (!extn_sta_preset_test_parameter)
		return -1;
	ret = extn_sta_preset_test_parameter(string_cmd, string_resp,
					     sizeof(string_resp));
	if (ret == SIGMA_ERROR) {
		send_resp(dut, conn, SIGMA_ERROR,
			  "Miracast extension reported error in the command sta_preset_testparameters");
		return 0;
	}

	if (mdns_disc && mdns_role) {
		if (strlen(string_resp))
			strlcpy(dut->mdns_instance_name, string_resp,
				sizeof(dut->mdns_instance_name));
		else
			dut->mdns_instance_name[0] = '\0';
	}

	return 1;
}


static int get_p2p_peers(char *respbuf, size_t bufsize)
{
	char addr[1024], cmd[64];
	char *intf = get_main_ifname();
	int ret;
	char *pos, *end;

	pos = respbuf;
	end = respbuf + bufsize;

	if (wpa_command_resp(intf, "P2P_PEER FIRST", addr, 128) >= 0) {
		addr[17] = '\0';
		strlcpy(respbuf, addr, bufsize);
		pos += strlen(respbuf);
		snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
		memset(addr, 0, sizeof(addr));
		while (wpa_command_resp(intf, cmd, addr, sizeof(addr)) >= 0) {
			if (memcmp(addr, "FAIL", 4) == 0)
				break;
			addr[17] = '\0';
			ret = snprintf(pos, end - pos, " %s", addr);
			if (ret < 0 || ret >= end - pos)
				break;
			pos += ret;
			snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
			memset(addr, 0, sizeof(addr));
		}
	}

	return 0;
}


int miracast_cmd_sta_get_parameter(struct sigma_dut *dut,
				   struct sigma_conn *conn,
				   struct sigma_cmd *cmd)
{
	/* const char *intf = get_param(cmd, "Interface"); */
	/* const char *program = get_param(cmd, "Program"); */
	const char *parameter = get_param(cmd, "Parameter");
	char resp_buf[1024]; /* may need to change depending on number of peer
				devices found */

	if (!parameter) {
		send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
		return 0;
	}

	if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
		int len = strlen("DeviceList,");

		snprintf(resp_buf, sizeof(resp_buf), "DeviceList,");
		get_p2p_peers(resp_buf + len, 1024 - len);
	} else {
		send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
		return 0;
	}

	send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
	return 0;
}


int miracast_mdns_start_wfd_connection(struct sigma_dut *dut,
				       struct sigma_conn *conn,
				       struct sigma_cmd *cmd)
{
	const char *init_wfd = get_param(cmd, "init_wfd");
	int int_init_wfd = -1;
	char rtsp_session_id[12];
	char cmd_response[128];
	int (*extn_start_wfd_connection)(const char *,
					 const char *, /* Peer IP */
					 int, /* RTSP port number */
					 int, /* WFD Device Type; 0-Source,
						1-P-Sink, 2-Secondary Sink */
					 char *); /* for returning session ID */
	int count = 0;
	char *sig_resp = NULL;

	if (init_wfd)
		int_init_wfd = atoi(init_wfd);

	extn_start_wfd_connection = dlsym(dut->miracast_lib,
					  "start_wfd_connection");
	if (!extn_start_wfd_connection)
		return -1;
	rtsp_session_id[0] = '\0';
	if (int_init_wfd != 0) {
		extn_start_wfd_connection(NULL, NULL, -100,
					  1 - dut->wfd_device_type,
					  rtsp_session_id);
		while (strlen(rtsp_session_id) == 0 && count < 60) {
			count++;
			sleep(1);
		}
		snprintf(cmd_response, sizeof(cmd_response),
			 "result,NULL,GroupID,NULL,WFDSessionID,%s",
			 count == 60 ? "NULL" : rtsp_session_id);
		sig_resp = cmd_response;
	} else {
		extn_start_wfd_connection(NULL, NULL, -100,
					  1 - dut->wfd_device_type, NULL);
		sig_resp = "result,NULL,GroupID,NULL,WFDSessionID,NULL";
	}

	send_resp(dut, conn, SIGMA_COMPLETE, sig_resp);
	return 0;
}


static int cmd_start_wfd_connection(struct sigma_dut *dut,
				    struct sigma_conn *conn,
				    struct sigma_cmd *cmd)
{
	const char *intf = get_param(cmd, "Interface");
	const char *peer_address = get_param(cmd, "PeerAddress");
	const char *init_wfd = get_param(cmd, "init_wfd");
	const char *intent_val = get_param(cmd, "intent_val");
	const char *oper_chan = get_param(cmd, "oper_chn");
	const char *coupled_session = get_param(cmd, "coupledSession");
	const char *tdls = get_param(cmd, "TDLS");
	const char *r2_connection = get_param(cmd, "R2ConnectionType");
	char ssid[128];
	char p2p_dev_address[18];
	char output_intf[16];
	char sig_resp_buf[1024];
	char cmd_buf[256]; /* Command buffer */
	char resp_buf[256]; /* Response buffer to UCC */
	int go_intent = 0;
	int freq;
	int res = 0;
	char buf_peer[4096];
	char *availability = NULL;
	char command[64];
	int avail_bit;
	char ctemp[2];
	char rtspport[5] = { '7', '2', '3', '6', '\0' };
	int is_group_owner = 0;
	char peer_ip_address[32];
	int sm_control_port = 7236;
	char rtsp_session_id[12] = { '\0' };
	int (*extn_start_wfd_connection)(const char *,
					 const char *, /* Peer IP */
					 int, /* RTSP port number */
					 int, /* WFD Device Type; 0-Source,
						 1-P-Sink, 2-Secondary Sink */
					 char *); /* for returning session ID */
	int count = 0;

	if (r2_connection) {
		if (strcasecmp(r2_connection, "Infrastructure") == 0)
			return miracast_mdns_start_wfd_connection(dut, conn,
								  cmd);
	}

	if (coupled_session && atoi(coupled_session) == 1) {
		send_resp(dut, conn, SIGMA_ERROR,
			  "errorCode,Coupled Session is unsupported");
		return 0;
	}

	if (tdls && atoi(tdls) == 1) {
		send_resp(dut, conn, SIGMA_ERROR,
			  "errorCode,TDLS is unsupported");
		return 0;
	}

	if (intent_val) {
		go_intent = atoi(intent_val);
		if (go_intent > 15)
			go_intent = 1;
	}

	if (p2p_discover_peer(dut, intf, peer_address, 1) < 0) {
		send_resp(dut, conn, SIGMA_ERROR,
			  "errorCode,Could not find peer");
		return 0;
	}

	snprintf(cmd_buf, sizeof(cmd_buf), "P2P_CONNECT %s", peer_address);

	switch (dut->wps_method) {
	case WFA_CS_WPS_PIN_DISPLAY:
		snprintf(cmd_buf + strlen(cmd_buf),
			 sizeof(cmd_buf) - strlen(cmd_buf), " pin display");
		break;
	case WFA_CS_WPS_PIN_LABEL:
		snprintf(cmd_buf + strlen(cmd_buf),
			 sizeof(cmd_buf) - strlen(cmd_buf), " pin label");
		break;
	case WFA_CS_WPS_PIN_KEYPAD:
		snprintf(cmd_buf + strlen(cmd_buf),
			 sizeof(cmd_buf) - strlen(cmd_buf), " %s keypad",
			 dut->wps_pin);
		break;
	case WFA_CS_WPS_PBC:
	default: /* Configuring default to PBC */
		snprintf(cmd_buf + strlen(cmd_buf),
			 sizeof(cmd_buf) - strlen(cmd_buf), " pbc");
		break;
	}

	if (dut->persistent) {
		snprintf(cmd_buf + strlen(cmd_buf),
			 sizeof(cmd_buf) - strlen(cmd_buf), " persistent");
	}
	snprintf(cmd_buf + strlen(cmd_buf), sizeof(cmd_buf) - strlen(cmd_buf),
		 " go_intent=%d", go_intent);

	if (init_wfd && atoi(init_wfd) == 0) {
		snprintf(cmd_buf + strlen(cmd_buf),
			 sizeof(cmd_buf) - strlen(cmd_buf), " auth");
	}

	if (oper_chan) {
		int chan;

		chan = atoi(oper_chan);
		if (chan >= 1 && chan <= 13)
			freq = 2407 + chan * 5;
		else if (chan == 14)
			freq = 2484;
		else
			freq = 5000 + chan * 5;

		snprintf(cmd_buf + strlen(cmd_buf),
			 sizeof(cmd_buf) - strlen(cmd_buf), " freq=%d", freq);
	}

	/* WFD SESSION AVAILABILITY CHECK */

	memset(buf_peer, 0, sizeof(buf_peer));
	snprintf(command, sizeof(command), "P2P_PEER %s", peer_address);
	strlcpy(dut->peer_mac_address, peer_address,
		sizeof(dut->peer_mac_address));
	if (wpa_command_resp(intf, command, buf_peer, sizeof(buf_peer)) >= 0 &&
	    strlen(buf_peer) != 0)
		availability = strstr(buf_peer, "wfd_subelems=");

	if (!availability || strlen(availability) < 21) {
		sigma_dut_print(dut, DUT_MSG_INFO, "Did not get WFD SUBELEMS");
		send_resp(dut, conn, SIGMA_COMPLETE,
			  "result,NULL,GroupID,NULL,WFDSessionID,NULL");
		return 0;
	}

	/* Extracting Availability Bit */
	ctemp[0] = availability[21];
	ctemp[1] = '\0';
	avail_bit = (int) strtol(ctemp, NULL, 16);

	if ((avail_bit & 0x3) == 0) {
		send_resp(dut, conn, SIGMA_COMPLETE,
			  "result,NULL,GroupID,NULL,WFDSessionID,NULL");
		return 0;
	}

	/* Extract RTSP Port for Sink */

	if (dut->wfd_device_type != 0) {
		if (strlen(availability) >= 23) {
			availability += 23;
			if (availability[0])
				snprintf(rtspport, 5, "%s", availability);
		}
		sigma_dut_print(dut, DUT_MSG_INFO,
				"rtsp_port = %s, availability = %s ",
				rtspport, availability);
		session_management_control_port = (int) strtol(rtspport, NULL,
							       16);
		sigma_dut_print(dut, DUT_MSG_INFO,
				"SessionManagementControlPort = %d",
				session_management_control_port);
	}

	memset(resp_buf, 0, sizeof(resp_buf));
	res = wpa_command_resp(intf, cmd_buf, resp_buf, sizeof(resp_buf));
	if (res < 0) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"wpa_command_resp failed");
		return 1;
	}
	if (strncmp(resp_buf, "FAIL", 4) == 0) {
		sigma_dut_print(dut, DUT_MSG_INFO,
				"wpa_command: Command failed (FAIL received)");
		return 1;
	}

	if (init_wfd && atoi(init_wfd) == 0) {
		/* Start thread to wait for P2P connection */
		miracast_rtsp_thread_create(dut, conn, cmd);
		send_resp(dut, conn, SIGMA_COMPLETE,
			  "result,NULL,GroupID,NULL,WFDSessionID,NULL");
		return 0;
	}

	res = get_p2p_connection_event(dut, intf, output_intf,
				       sizeof(output_intf), &is_group_owner);
	sigma_dut_print(dut, DUT_MSG_DEBUG, "p2p connection done %d",
			is_group_owner);
	if (res < 0) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Group Formation did not complete");
		return 1;
	}

	snprintf(sig_resp_buf, sizeof(sig_resp_buf), "result");

	if (is_group_owner) {
		stop_dhcp(dut, output_intf,1);
		snprintf(sig_resp_buf + strlen(sig_resp_buf),
			 sizeof(sig_resp_buf) - strlen(sig_resp_buf), ",GO");
		start_dhcp(dut, output_intf,1);
		sleep(5);
	} else {
		snprintf(sig_resp_buf + strlen(sig_resp_buf),
			 sizeof(sig_resp_buf) - strlen(sig_resp_buf),
			 ",CLIENT");
		miracast_start_dhcp_client(dut, output_intf);
		sleep(5);
	}

	snprintf(sig_resp_buf + strlen(sig_resp_buf),
		 sizeof(sig_resp_buf) - strlen(sig_resp_buf), ",GroupID,");

	res = get_wpa_status(output_intf, "p2p_device_address",
			     p2p_dev_address, sizeof(p2p_dev_address));
	if (res < 0)
		return -1;
	sigma_dut_print(dut, DUT_MSG_INFO, "p2p_dev_address %s",
			p2p_dev_address);
	strlcpy(sig_resp_buf + strlen(sig_resp_buf), p2p_dev_address,
		sizeof(sig_resp_buf) - strlen(sig_resp_buf));

	res = get_wpa_status(output_intf, "ssid", ssid, sizeof(ssid));
	if (res < 0) {
		sigma_dut_print(dut, DUT_MSG_DEBUG,
				"get_wpa_status failed to get ssid");
		return -1;
	}

	snprintf(sig_resp_buf + strlen(sig_resp_buf),
		 sizeof(sig_resp_buf) - strlen(sig_resp_buf),
		 " %s,WFDSessionId,", ssid);

	if (!is_group_owner) {
		if (get_peer_ip_p2p_client(dut, peer_ip_address, output_intf,
					   60) < 0) {
			send_resp(dut, conn, SIGMA_ERROR,
				  "Could not get remote IP");
			return 0;
		}
	} else {
		if (get_peer_ip_p2p_go(dut, peer_ip_address, peer_address,
				       30) < 0) {
			send_resp(dut, conn, SIGMA_ERROR,
				  "Could not get remote IP");
			return 0;
		}
	}

	if (dut->wfd_device_type != 0)
		sm_control_port = (int) strtol(rtspport, NULL, 16);
	else
		sm_control_port = 7236;

	extn_start_wfd_connection = dlsym(dut->miracast_lib,
					  "start_wfd_connection");
	if (!extn_start_wfd_connection)
		return -1;
	extn_start_wfd_connection(NULL, peer_ip_address, sm_control_port,
				  1 - dut->wfd_device_type, rtsp_session_id);

	while (strlen(rtsp_session_id) == 0 && count < 60) {
		count++;
		sleep(1);
	}

	if (count == 60)
		strlcpy(rtsp_session_id, "00000000", sizeof(rtsp_session_id));

	strlcat(sig_resp_buf, rtsp_session_id,
		sizeof(sig_resp_buf) - strlen(sig_resp_buf));
	send_resp(dut, conn, SIGMA_COMPLETE, sig_resp_buf);
	return 0;
}


static int cmd_connect_go_start_wfd(struct sigma_dut *dut,
				    struct sigma_conn *conn,
				    struct sigma_cmd *cmd)
{
	const char *intf = get_param(cmd, "Interface");
	const char *p2p_dev_id = get_param(cmd, "P2PdevID");
	/* const char *p2p_group_id = get_param(cmd, "GroupID"); */
	char sig_resp_buf[1024];
	char method[12];
	char cmd_buf[256];
	char buf[256];
	char resp_buf[256];
	int go = 0;
	int res = 0;
	char output_ifname[32];
	char peer_ip_address[32];
	char rtsp_session_id[12];
	int (*extn_connect_go_start_wfd)(const char *,
					 const char * /* Peer IP */,
					 int /* RTSP port number */,
					 int /* WFD Device Type; 0-Source,
						1-P-Sink, 2-Secondary Sink */,
					 char *); /* for returning session ID */

	snprintf(cmd_buf, sizeof(cmd_buf), "P2P_CONNECT %s", p2p_dev_id);

	switch (dut->wps_method) {
	case WFA_CS_WPS_PBC:
		snprintf(cmd_buf + strlen(cmd_buf),
			 sizeof(cmd_buf) - strlen(cmd_buf), " pbc");
		strlcpy(method, "pbc", sizeof(method));
		break;
	case WFA_CS_WPS_PIN_DISPLAY:
		snprintf(cmd_buf + strlen(cmd_buf),
			 sizeof(cmd_buf) - strlen(cmd_buf), " pin display");
		strlcpy(method, "display", sizeof(method));
		break;
	case WFA_CS_WPS_PIN_LABEL:
		snprintf(cmd_buf + strlen(cmd_buf),
			 sizeof(cmd_buf) - strlen(cmd_buf), " pin label");
		strlcpy(method, "label", sizeof(method));
		break;
	case WFA_CS_WPS_PIN_KEYPAD:
		snprintf(cmd_buf + strlen(cmd_buf),
			 sizeof(cmd_buf) - strlen(cmd_buf), " %s keypad",
			 dut->wps_pin);
		strlcpy(method, "keypad", sizeof(method));
		break;
	default: /* Configuring to PBC */
		snprintf(cmd_buf + strlen(cmd_buf),
			 sizeof(cmd_buf) - strlen(cmd_buf), " pbc");
		strlcpy(method, "pbc", sizeof(method));
		break;
	}
	snprintf(cmd_buf + strlen(cmd_buf),
		 sizeof(cmd_buf) - strlen(cmd_buf), " join");

	/* run provisional discovery */
	if (p2p_discover_peer(dut, intf, p2p_dev_id, 0) < 0) {
		send_resp(dut, conn, SIGMA_ERROR,
			  "ErrorCode,Could not discover the requested peer");
		return 0;
	}

	snprintf(buf, sizeof(buf), "P2P_PROV_DISC %s %s", p2p_dev_id, method);
	if (wpa_command(intf, buf) < 0) {
		sigma_dut_print(dut, DUT_MSG_INFO,
				"Failed to send provision discovery request");
		return -2;
	}

	res = wpa_command_resp(intf, cmd_buf, resp_buf, sizeof(resp_buf));
	if (res < 0) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"wpa_command_resp failed");
		return 1;
	}
	if (strncmp(resp_buf, "FAIL", 4) == 0) {
		send_resp(dut, conn, SIGMA_ERROR,
			  "errorCode,failed P2P connection");
		return 0;
	}

	res = get_p2p_connection_event(dut, intf, output_ifname,
				       sizeof(output_ifname), &go);
	if (res < 0) {
		send_resp(dut, conn, SIGMA_ERROR,
			  "errorCode,failed P2P connection");
		return 0;
	}

	miracast_start_dhcp_client(dut, output_ifname);

	if (get_peer_ip_p2p_client(dut, peer_ip_address, output_ifname,
				   30) < 0) {
		send_resp(dut, conn, SIGMA_ERROR, "Could not get remote IP");
		return 0;
	}

	if (dut->wfd_device_type != 0) {
		char rtsp_buff[1000], cmd_buff[32];
		char *sub_elem = NULL;
		char rtspport[5] = { '7', '2', '3', '6', '\0' };

		sigma_dut_print(dut, DUT_MSG_DEBUG,
				"Log --- p2p address = %s", p2p_dev_id);
		snprintf(cmd_buff, sizeof(cmd_buff), "P2P_PEER %s", p2p_dev_id);
		if (wpa_command_resp(output_ifname, cmd_buff, rtsp_buff,
				     sizeof(rtsp_buff)) >= 0 &&
		    strlen(rtsp_buff) != 0)
			sub_elem = strstr(rtsp_buff, "wfd_subelems=");

		/* Extract RTSP Port for Sink */
		if (sub_elem && strlen(sub_elem) >= 23) {
			sub_elem += 23;
			snprintf(rtspport, 5, "%s", sub_elem);
			sigma_dut_print(dut, DUT_MSG_DEBUG,
				"rtsp_port = %s, subElem = %s",
				rtspport, sub_elem);
		}
		session_management_control_port = (int) strtol(rtspport, NULL,
							       16);
		sigma_dut_print(dut, DUT_MSG_DEBUG,
				"SessionManagementControlPort = %d",
				session_management_control_port);

	} else {
		session_management_control_port = 7236;
	}

	extn_connect_go_start_wfd = dlsym(dut->miracast_lib,
					  "connect_go_start_wfd");
	if (!extn_connect_go_start_wfd)
		return -1;
	rtsp_session_id[0] = '\0';
	extn_connect_go_start_wfd(NULL, peer_ip_address,
				  session_management_control_port,
				  1 - dut->wfd_device_type, rtsp_session_id);
	/* Null terminating regardless of what was returned */
	rtsp_session_id[sizeof(rtsp_session_id) - 1] = '\0';
	snprintf(sig_resp_buf, sizeof(sig_resp_buf), "WFDSessionId,%s",
		 rtsp_session_id);

	send_resp(dut, conn, SIGMA_COMPLETE, sig_resp_buf);
	return 0;
}


static int cmd_sta_generate_event(struct sigma_dut *dut,
				  struct sigma_conn *conn,
				  struct sigma_cmd *cmd)
{

	/* const char *intf = get_param(cmd, "Interface"); */
	/* const char *program = get_param(cmd, "Program"); */
	const char *type = get_param(cmd, "Type");
	char string_cmd[MIRACAST_CMD_LEN];
	int (*extn_sta_generate_event)(const char *);

	if (!type) {
		send_resp(dut, conn, SIGMA_INVALID,
			  "errorCode, Invalid Type for Generate Event");
		return 0;
	}
	miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd));
	extn_sta_generate_event = dlsym(dut->miracast_lib,
					"sta_generate_event");
	if (!extn_sta_generate_event)
		return -1;
	if (strcasecmp(type, "UIBC_Gen") == 0 ||
	    strcasecmp(type, "UIBC_HID") == 0) {
		extn_sta_generate_event(string_cmd);
	} else if (strcasecmp(type, "FrameSkip") == 0) {
		return 1;
	} else if (strcasecmp(type, "InputContent") == 0) {
		send_resp(dut, conn, SIGMA_COMPLETE, NULL);
		return 0;
	} else if (strcasecmp(type, "I2cRead") == 0) {
		send_resp(dut, conn, SIGMA_ERROR,
			  "errorCode,Unsupported Type for Generate Event");
		return 0;
	} else if (strcasecmp(type, "I2cWrite") == 0) {
		send_resp(dut, conn, SIGMA_ERROR,
			  "errorCode, Unsupported Type for Generate Event");
		return 0;
	} else if (strcasecmp(type, "IdrReq") == 0) {
		if (dut->wfd_device_type == 0) { /* Source */
			send_resp(dut, conn, SIGMA_ERROR,
				  "errorCode, Unsupported Type for Generate Event");
		} else {
			send_resp(dut, conn, SIGMA_COMPLETE, NULL);
			extn_sta_generate_event(string_cmd);
		}
		return 0;
	}
	return 1;
}


static int cmd_reinvoke_wfd_session(struct sigma_dut *dut,
				    struct sigma_conn *conn,
				    struct sigma_cmd *cmd)
{
	const char *intf = get_param(cmd, "Interface");
	const char *grp_id = get_param(cmd, "GroupID");
	const char *peer_address = get_param(cmd, "peeraddress");
	const char *invitation_action = get_param(cmd, "InvitationAction");
	char buf[256];
	struct wpa_ctrl *ctrl;
	int res, id;
	char *ssid, *pos;
	unsigned int wait_limit;
	char peer_ip_address[32];
	char rtsp_session_id[12];
	int (*extn_start_wfd_connection)(const char *,
					 const char *, /* Peer IP */
					 int, /* RTSP port number */
					 int, /* WFD Device Type; 0-Source,
						 1-P-Sink, 2-Secondary Sink */
					 char *); /* for returning session ID */

	/* All are compulsory parameters */
	if (!intf || !grp_id || !invitation_action || !peer_address) {
		send_resp(dut, conn, SIGMA_INVALID,
			  "errorCode,Invalid parameters for Reinvoke WFD Session");
		return 0;
	}

	if (strcmp(invitation_action, "accept") == 0) {
		/*
		 * In a client-joining-a-running-group case, we need to
		 * separately authorize the invitation.
		 */
		miracast_stop_dhcp_client(dut, NULL);
		sigma_dut_print(dut, DUT_MSG_DEBUG, "Trying to discover GO %s",
				peer_address);
		if (p2p_discover_peer(dut, intf, peer_address, 1) < 0) {
			send_resp(dut, conn, SIGMA_ERROR,
				  "ErrorCode,Could not discover the requested peer");
			return 0;
		}

		snprintf(buf, sizeof(buf), "P2P_CONNECT %s %s join auth",
			 peer_address, dut->wps_method == WFA_CS_WPS_PBC ?
			 "pbc" : dut->wps_pin);
		if (wpa_command(intf, buf) < 0)
			return -2;

		miracast_rtsp_thread_create(dut, conn, cmd);
		return 1;
	}

	ssid = strchr(grp_id, ' ');
	if (!ssid) {
		sigma_dut_print(dut, DUT_MSG_INFO, "Invalid grpid");
		return -1;
	}
	ssid++;
	sigma_dut_print(dut, DUT_MSG_DEBUG,
			"Search for persistent group credentials based on SSID: '%s'",
			ssid);
	if (wpa_command_resp(intf, "LIST_NETWORKS", buf, sizeof(buf)) < 0)
		return -2;
	pos = strstr(buf, ssid);
	if (!pos || pos == buf || pos[-1] != '\t' ||
	    pos[strlen(ssid)] != '\t') {
		send_resp(dut, conn, SIGMA_ERROR,
			  "ErrorCode,Persistent group credentials not found");
		return 0;
	}
	while (pos > buf && pos[-1] != '\n')
		pos--;
	id = atoi(pos);
	snprintf(buf, sizeof(buf), "P2P_INVITE persistent=%d peer=%s",
		 id, peer_address);

	sigma_dut_print(dut, DUT_MSG_DEBUG,
			"Trying to discover peer %s for invitation",
			peer_address);
	if (p2p_discover_peer(dut, intf, peer_address, 0) < 0) {
		send_resp(dut, conn, SIGMA_ERROR,
			  "ErrorCode,Could not discover the requested peer");
		return 0;
	}

	ctrl = open_wpa_mon(intf);
	if (!ctrl) {
		sigma_dut_print(dut, DUT_MSG_ERROR,
				"Failed to open wpa_supplicant monitor connection");
		return -2;
	}

	if (wpa_command(intf, buf) < 0) {
		sigma_dut_print(dut, DUT_MSG_INFO,
				"Failed to send invitation request");
		wpa_ctrl_detach(ctrl);
		wpa_ctrl_close(ctrl);
		return -2;
	}

	res = get_wpa_cli_event(dut, ctrl, "P2P-INVITATION-RESULT",
				buf, sizeof(buf));
	wpa_ctrl_detach(ctrl);
	wpa_ctrl_close(ctrl);
	if (res < 0)
		return -2;

	miracast_load(dut);

	sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting to start DHCP");

	/* Calling Miracast multimedia APIs */
	if (dut->wfd_device_type != 0)
		wait_limit = HUNDRED_SECOND_TIMEOUT;
	else
		wait_limit = 500;

	stop_dhcp(dut, intf, 1);
	/* For GO read the DHCP lease file */
	sigma_dut_print(dut, DUT_MSG_INFO, "Waiting to start DHCP server");
	start_dhcp(dut, intf, 1);
	sleep(5);
	if (get_peer_ip_p2p_go(dut, peer_ip_address, dut->peer_mac_address,
			       wait_limit) < 0) {
		sigma_dut_print(dut, DUT_MSG_ERROR, "Could not get peer IP");
		return -2;
	}

	extn_start_wfd_connection = dlsym(dut->miracast_lib,
					  "start_wfd_connection");
	if (extn_start_wfd_connection) {
		extn_start_wfd_connection(NULL, peer_ip_address,
					  session_management_control_port,
					  1 - dut->wfd_device_type,
					  rtsp_session_id);
	} else {
		sigma_dut_print(dut, DUT_MSG_INFO,
				"dlsym seems to have error %p %p",
				dut->miracast_lib,
				extn_start_wfd_connection);
	}

	return 1;
}


static int req_intf_peer(struct sigma_cmd *cmd)
{
	if (!get_param(cmd, "interface") ||
	    !get_param(cmd, "PeerAddress"))
		return -1;
	return 0;
}


static int req_intf_p2pdev_grpid(struct sigma_cmd *cmd)
{
	if (!get_param(cmd, "interface") ||
	    !get_param(cmd, "P2pdevID") ||
	    !get_param(cmd, "GroupID"))
		return -1;
	return 0;
}


static int req_intf_prog_type(struct sigma_cmd *cmd)
{
	const char *prog = get_param(cmd, "Program");

	if (!get_param(cmd, "interface") ||
	    !get_param(cmd, "Type") ||
	    !prog || strcmp(prog, "WFD") != 0)
		return -1;
	return 0;
}


static int req_intf_peeradd_inv(struct sigma_cmd *cmd)
{
	if (!get_param(cmd, "interface") ||
	    !get_param(cmd, "peerAddress") ||
	    !get_param(cmd, "InvitationAction"))
		return -1;
	return 0;
}


void miracast_register_cmds(void)
{
	sigma_dut_reg_cmd("start_wfd_connection", req_intf_peer,
			  cmd_start_wfd_connection);
	sigma_dut_reg_cmd("connect_go_start_wfd", req_intf_p2pdev_grpid,
			  cmd_connect_go_start_wfd);
	sigma_dut_reg_cmd("sta_generate_event", req_intf_prog_type,
			  cmd_sta_generate_event);
	sigma_dut_reg_cmd("reinvoke_wfd_session", req_intf_peeradd_inv,
			  cmd_reinvoke_wfd_session);
}
