xref: /wlan-dirver/utils/sigma-dut/miracast.c (revision 30088a7ce63e03bb6e7df748bd09b93dcdf5c907)
19c381f59SAmarnath Hullur Subramanyam /*
29c381f59SAmarnath Hullur Subramanyam  * Sigma Control API DUT - Miracast interface
39c381f59SAmarnath Hullur Subramanyam  * Copyright (c) 2017, Qualcomm Atheros, Inc.
4bf9bcdf6SSunil Dutt  * Copyright (c) 2018-2019, The Linux Foundation
59c381f59SAmarnath Hullur Subramanyam  * All Rights Reserved.
69c381f59SAmarnath Hullur Subramanyam  * Licensed under the Clear BSD license. See README for more details.
79c381f59SAmarnath Hullur Subramanyam  *
89c381f59SAmarnath Hullur Subramanyam  * Implementation of MIRACAST specific functionality.
99c381f59SAmarnath Hullur Subramanyam  * For example, starting wfd session.
109c381f59SAmarnath Hullur Subramanyam */
119c381f59SAmarnath Hullur Subramanyam 
129c381f59SAmarnath Hullur Subramanyam #include "sigma_dut.h"
139c381f59SAmarnath Hullur Subramanyam #include <dlfcn.h>
149c381f59SAmarnath Hullur Subramanyam #include <sys/ioctl.h>
159c381f59SAmarnath Hullur Subramanyam #include <sys/select.h>
169c381f59SAmarnath Hullur Subramanyam #include "wpa_ctrl.h"
179c381f59SAmarnath Hullur Subramanyam #include "wpa_helpers.h"
189c381f59SAmarnath Hullur Subramanyam #include "miracast.h"
199c381f59SAmarnath Hullur Subramanyam #ifdef ANDROID
209c381f59SAmarnath Hullur Subramanyam #include "properties.h"
219c381f59SAmarnath Hullur Subramanyam #include <netutils/ifc.h>
229c381f59SAmarnath Hullur Subramanyam #endif /* ANDROID */
239c381f59SAmarnath Hullur Subramanyam 
249c381f59SAmarnath Hullur Subramanyam #define HUNDRED_SECOND_TIMEOUT   100 /* 100 seconds */
259c381f59SAmarnath Hullur Subramanyam #define DHCP_LEASE_FILE_PATH "/data/misc/dhcp/dnsmasq.leases"
269c381f59SAmarnath Hullur Subramanyam #define MIRACAST_CMD_LEN         512
279c381f59SAmarnath Hullur Subramanyam 
289c381f59SAmarnath Hullur Subramanyam static int session_management_control_port = 7236;
299c381f59SAmarnath Hullur Subramanyam /* Followingng stores p2p interface name after P2P group formation */
309c381f59SAmarnath Hullur Subramanyam static char wfd_ifname[32];
319c381f59SAmarnath Hullur Subramanyam 
32bc6ce9ffSPurushottam Kushwaha extern void get_dhcp_info(uint32_t *ipaddr, uint32_t *gateway,
33bc6ce9ffSPurushottam Kushwaha 			  uint32_t *prefixLength, uint32_t *dns1,
34bc6ce9ffSPurushottam Kushwaha 			  uint32_t *dns2, uint32_t *server,
35bc6ce9ffSPurushottam Kushwaha 			  uint32_t *lease);
36bc6ce9ffSPurushottam Kushwaha 
37bc6ce9ffSPurushottam Kushwaha extern int do_dhcp(char *);
38bc6ce9ffSPurushottam Kushwaha 
ipaddr(in_addr_t addr)39bc6ce9ffSPurushottam Kushwaha const char *ipaddr (in_addr_t addr)
40bc6ce9ffSPurushottam Kushwaha {
41bc6ce9ffSPurushottam Kushwaha 	struct in_addr in_addr;
42bc6ce9ffSPurushottam Kushwaha 	in_addr.s_addr = addr;
43bc6ce9ffSPurushottam Kushwaha 	return inet_ntoa(in_addr);
44bc6ce9ffSPurushottam Kushwaha }
45bc6ce9ffSPurushottam Kushwaha 
469c381f59SAmarnath Hullur Subramanyam 
479c381f59SAmarnath Hullur Subramanyam 
489c381f59SAmarnath Hullur Subramanyam 
miracast_load(struct sigma_dut * dut)499c381f59SAmarnath Hullur Subramanyam static int miracast_load(struct sigma_dut *dut)
509c381f59SAmarnath Hullur Subramanyam {
519c381f59SAmarnath Hullur Subramanyam 	static int once = 1;
529c381f59SAmarnath Hullur Subramanyam 
539c381f59SAmarnath Hullur Subramanyam 	if (!once)
549c381f59SAmarnath Hullur Subramanyam 		return 0;
559c381f59SAmarnath Hullur Subramanyam 
569c381f59SAmarnath Hullur Subramanyam 	once = 0;
579c381f59SAmarnath Hullur Subramanyam 	dlerror();
589c381f59SAmarnath Hullur Subramanyam 	dut->miracast_lib = dlopen(dut->miracast_lib_path ?
599c381f59SAmarnath Hullur Subramanyam 				   dut->miracast_lib_path : "libmiracast.so",
609c381f59SAmarnath Hullur Subramanyam 				   RTLD_LAZY);
619c381f59SAmarnath Hullur Subramanyam 	if (!dut->miracast_lib) {
629c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
639c381f59SAmarnath Hullur Subramanyam 				"Fail to load Miracast library %s",
649c381f59SAmarnath Hullur Subramanyam 				dlerror());
659c381f59SAmarnath Hullur Subramanyam 		return -1;
669c381f59SAmarnath Hullur Subramanyam 	}
679c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_INFO,
689c381f59SAmarnath Hullur Subramanyam 			"Miracast Wi-Fi Display library found - starting service");
699c381f59SAmarnath Hullur Subramanyam 	return 0;
709c381f59SAmarnath Hullur Subramanyam }
719c381f59SAmarnath Hullur Subramanyam 
729c381f59SAmarnath Hullur Subramanyam 
miracast_unload(struct sigma_dut * dut)739c381f59SAmarnath Hullur Subramanyam static int miracast_unload(struct sigma_dut *dut)
749c381f59SAmarnath Hullur Subramanyam {
759c381f59SAmarnath Hullur Subramanyam 	int err;
769c381f59SAmarnath Hullur Subramanyam 
779c381f59SAmarnath Hullur Subramanyam 	if (!dut->miracast_lib)
789c381f59SAmarnath Hullur Subramanyam 		return -1;
799c381f59SAmarnath Hullur Subramanyam 
809c381f59SAmarnath Hullur Subramanyam 	dlerror();
819c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_INFO, "Unloading Miracast library");
829c381f59SAmarnath Hullur Subramanyam 	err = dlclose(dut->miracast_lib);
839c381f59SAmarnath Hullur Subramanyam 	dut->miracast_lib = NULL;
849c381f59SAmarnath Hullur Subramanyam 	if (err == 0) {
859c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
869c381f59SAmarnath Hullur Subramanyam 			 "Miracast library successfully unloaded");
879c381f59SAmarnath Hullur Subramanyam 	} else {
889c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
899c381f59SAmarnath Hullur Subramanyam 			"Failed to unload Miracast library");
909c381f59SAmarnath Hullur Subramanyam 	}
919c381f59SAmarnath Hullur Subramanyam 	return err;
929c381f59SAmarnath Hullur Subramanyam }
939c381f59SAmarnath Hullur Subramanyam 
949c381f59SAmarnath Hullur Subramanyam 
get_modified_peer_mac_address(struct sigma_dut * dut)95bf9bcdf6SSunil Dutt static void get_modified_peer_mac_address(struct sigma_dut *dut)
96bf9bcdf6SSunil Dutt {
97bf9bcdf6SSunil Dutt 	struct wpa_ctrl *ctrl;
98bf9bcdf6SSunil Dutt 	char event_buf[64];
99bf9bcdf6SSunil Dutt 	char *peer;
100bf9bcdf6SSunil Dutt 	int res;
101bf9bcdf6SSunil Dutt 
102bf9bcdf6SSunil Dutt 	dut->modified_peer_mac_address[0] = '\0';
103bf9bcdf6SSunil Dutt 	ctrl = open_wpa_mon(wfd_ifname); /* Refer to wfd_ifname */
104bf9bcdf6SSunil Dutt 	if (!ctrl) {
105bf9bcdf6SSunil Dutt 		sigma_dut_print(dut, DUT_MSG_ERROR,
106bf9bcdf6SSunil Dutt 				"Failed to open wpa_supplicant monitor connection");
107bf9bcdf6SSunil Dutt 		return;
108bf9bcdf6SSunil Dutt 	}
109bf9bcdf6SSunil Dutt 	res = get_wpa_cli_event(dut, ctrl, "AP-STA-CONNECTED",
110bf9bcdf6SSunil Dutt 				event_buf, sizeof(event_buf));
111bf9bcdf6SSunil Dutt 	wpa_ctrl_detach(ctrl);
112bf9bcdf6SSunil Dutt 	wpa_ctrl_close(ctrl);
113bf9bcdf6SSunil Dutt 
114bf9bcdf6SSunil Dutt 	if (res < 0) {
115bf9bcdf6SSunil Dutt 		sigma_dut_print(dut, DUT_MSG_ERROR,
116bf9bcdf6SSunil Dutt 				"Could not get event before timeout");
117bf9bcdf6SSunil Dutt 		return;
118bf9bcdf6SSunil Dutt 	}
119bf9bcdf6SSunil Dutt 
120bf9bcdf6SSunil Dutt 	sigma_dut_print(dut, DUT_MSG_DEBUG, "STA connected event: '%s'",
121bf9bcdf6SSunil Dutt 			event_buf);
122bf9bcdf6SSunil Dutt 	peer = strchr(event_buf, ' ');
123bf9bcdf6SSunil Dutt 	if (!peer) {
124bf9bcdf6SSunil Dutt 		sigma_dut_print(dut, DUT_MSG_ERROR,
125bf9bcdf6SSunil Dutt 				"Could not find STA MAC address");
126bf9bcdf6SSunil Dutt 		return;
127bf9bcdf6SSunil Dutt 	}
128bf9bcdf6SSunil Dutt 
129bf9bcdf6SSunil Dutt 	peer++;
130bf9bcdf6SSunil Dutt 	strlcpy(dut->modified_peer_mac_address, peer,
131bf9bcdf6SSunil Dutt 		sizeof(dut->modified_peer_mac_address));
132bf9bcdf6SSunil Dutt }
133bf9bcdf6SSunil Dutt 
134bf9bcdf6SSunil Dutt 
get_peer_ip_p2p_go(struct sigma_dut * dut,char * ipaddr,unsigned int wait_limit)1359c381f59SAmarnath Hullur Subramanyam static int get_peer_ip_p2p_go(struct sigma_dut *dut, char *ipaddr,
136bf9bcdf6SSunil Dutt 			      unsigned int wait_limit)
1379c381f59SAmarnath Hullur Subramanyam {
1389c381f59SAmarnath Hullur Subramanyam 
1399c381f59SAmarnath Hullur Subramanyam 	FILE *fp;
140bf9bcdf6SSunil Dutt 	char *macaddr;
141bf9bcdf6SSunil Dutt 
142bf9bcdf6SSunil Dutt 	if (dut->modified_peer_mac_address[0])
143bf9bcdf6SSunil Dutt 		macaddr = dut->modified_peer_mac_address;
144bf9bcdf6SSunil Dutt 	else
145bf9bcdf6SSunil Dutt 		macaddr = dut->peer_mac_address;
1469c381f59SAmarnath Hullur Subramanyam 
1479c381f59SAmarnath Hullur Subramanyam 	fp = fopen(DHCP_LEASE_FILE_PATH, "r");
1489c381f59SAmarnath Hullur Subramanyam 	if (!fp) {
1499c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR,
1509c381f59SAmarnath Hullur Subramanyam 				"Could not open DHCP lease file");
1519c381f59SAmarnath Hullur Subramanyam 		return -1;
1529c381f59SAmarnath Hullur Subramanyam 	}
1539c381f59SAmarnath Hullur Subramanyam 
1549c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_INFO, "macaddress %s", macaddr);
1559c381f59SAmarnath Hullur Subramanyam 	while (wait_limit > 0) {
1569c381f59SAmarnath Hullur Subramanyam 		char line[100] = { 0 };
1579c381f59SAmarnath Hullur Subramanyam 		char *str1 = NULL;
1589c381f59SAmarnath Hullur Subramanyam 		char *dummy_str = NULL;
1599c381f59SAmarnath Hullur Subramanyam 		char dummy_macaddress[32];
1609c381f59SAmarnath Hullur Subramanyam 		int ip_found = 0;
1619c381f59SAmarnath Hullur Subramanyam 		int len;
1629c381f59SAmarnath Hullur Subramanyam 
1639c381f59SAmarnath Hullur Subramanyam 		fseek(fp, 0, SEEK_SET);
1649c381f59SAmarnath Hullur Subramanyam 		while (fgets(line, sizeof(line), fp) != NULL) {
1659c381f59SAmarnath Hullur Subramanyam 			len = strlen(line);
1669c381f59SAmarnath Hullur Subramanyam 			if (len == 0)
1679c381f59SAmarnath Hullur Subramanyam 				continue;
1689c381f59SAmarnath Hullur Subramanyam 
1699c381f59SAmarnath Hullur Subramanyam 			str1 = strtok_r(line, " ", &dummy_str);
1709c381f59SAmarnath Hullur Subramanyam 			if (str1 == NULL)
1719c381f59SAmarnath Hullur Subramanyam 				break;
1729c381f59SAmarnath Hullur Subramanyam 
1739c381f59SAmarnath Hullur Subramanyam 			/* Look for mac address */
1749c381f59SAmarnath Hullur Subramanyam 			str1 = strtok_r(NULL, " ", &dummy_str);
1759c381f59SAmarnath Hullur Subramanyam 			if (str1 == NULL)
1769c381f59SAmarnath Hullur Subramanyam 				break;
1779c381f59SAmarnath Hullur Subramanyam 
1789c381f59SAmarnath Hullur Subramanyam 			strlcpy(dummy_macaddress, str1,
1799c381f59SAmarnath Hullur Subramanyam 				sizeof(dummy_macaddress));
1809c381f59SAmarnath Hullur Subramanyam 
1819c381f59SAmarnath Hullur Subramanyam 			/* Look for ip address */
1829c381f59SAmarnath Hullur Subramanyam 			str1 = strtok_r(NULL, " ", &dummy_str);
1839c381f59SAmarnath Hullur Subramanyam 			if (str1 == NULL)
1849c381f59SAmarnath Hullur Subramanyam 				break;
1859c381f59SAmarnath Hullur Subramanyam 
1869c381f59SAmarnath Hullur Subramanyam 			strlcpy(ipaddr,str1,32);
1879c381f59SAmarnath Hullur Subramanyam 
1889c381f59SAmarnath Hullur Subramanyam 			sigma_dut_print(dut, DUT_MSG_INFO,
1899c381f59SAmarnath Hullur Subramanyam 					"Peer IP Address obtained and mac %s %s",
1909c381f59SAmarnath Hullur Subramanyam 					ipaddr, dummy_macaddress);
1919c381f59SAmarnath Hullur Subramanyam 
192bf9bcdf6SSunil Dutt 			/* Match all the octets of MAC address */
193bf9bcdf6SSunil Dutt 			if (strncasecmp(macaddr, dummy_macaddress, 17) == 0) {
1949c381f59SAmarnath Hullur Subramanyam 				ip_found = 1;
1959c381f59SAmarnath Hullur Subramanyam 				sigma_dut_print(dut, DUT_MSG_INFO,
1969c381f59SAmarnath Hullur Subramanyam 						"Obtained the IP address %s",
1979c381f59SAmarnath Hullur Subramanyam 						ipaddr);
1989c381f59SAmarnath Hullur Subramanyam 				break;
1999c381f59SAmarnath Hullur Subramanyam 			}
2009c381f59SAmarnath Hullur Subramanyam 		}
2019c381f59SAmarnath Hullur Subramanyam 
2029c381f59SAmarnath Hullur Subramanyam 		if (ip_found)
2039c381f59SAmarnath Hullur Subramanyam 			break;
2049c381f59SAmarnath Hullur Subramanyam 
2059c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
2069c381f59SAmarnath Hullur Subramanyam 				"Failed to find IP from DHCP lease file");
2079c381f59SAmarnath Hullur Subramanyam 		sleep(1);
2089c381f59SAmarnath Hullur Subramanyam 		wait_limit--;
2099c381f59SAmarnath Hullur Subramanyam 	}
2109c381f59SAmarnath Hullur Subramanyam 	fclose(fp);
2119c381f59SAmarnath Hullur Subramanyam 	return 0;
2129c381f59SAmarnath Hullur Subramanyam }
2139c381f59SAmarnath Hullur Subramanyam 
2149c381f59SAmarnath Hullur Subramanyam 
miracast_start_dhcp_client(struct sigma_dut * dut,const char * ifname)2159c381f59SAmarnath Hullur Subramanyam static int miracast_start_dhcp_client(struct sigma_dut *dut, const char *ifname)
2169c381f59SAmarnath Hullur Subramanyam {
2179c381f59SAmarnath Hullur Subramanyam 	int ret = ifc_init();
2189c381f59SAmarnath Hullur Subramanyam 
2199c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "ifc init returned %d", ret);
2209c381f59SAmarnath Hullur Subramanyam 	ret = do_dhcp((char *) ifname);
2219c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "do dhcp returned %d", ret);
2229c381f59SAmarnath Hullur Subramanyam 	return 0;
2239c381f59SAmarnath Hullur Subramanyam }
2249c381f59SAmarnath Hullur Subramanyam 
2259c381f59SAmarnath Hullur Subramanyam 
miracast_stop_dhcp_client(struct sigma_dut * dut,const char * ifname)226016ae6c8SJouni Malinen static void miracast_stop_dhcp_client(struct sigma_dut *dut, const char *ifname)
2279c381f59SAmarnath Hullur Subramanyam {
2289c381f59SAmarnath Hullur Subramanyam 	ifc_close();
2299c381f59SAmarnath Hullur Subramanyam }
2309c381f59SAmarnath Hullur Subramanyam 
2319c381f59SAmarnath Hullur Subramanyam 
get_peer_ip_p2p_client(struct sigma_dut * dut,char * ipAddr,const char * intf,unsigned int wait_limit)2329c381f59SAmarnath Hullur Subramanyam static int get_peer_ip_p2p_client(struct sigma_dut *dut, char *ipAddr,
2339c381f59SAmarnath Hullur Subramanyam 				  const char *intf, unsigned int wait_limit)
2349c381f59SAmarnath Hullur Subramanyam {
2359c381f59SAmarnath Hullur Subramanyam 	uint32_t ipaddress, gateway, prefixLength,
2369c381f59SAmarnath Hullur Subramanyam 		dns1, dns2, serveraddr, lease;
2379c381f59SAmarnath Hullur Subramanyam 
2389c381f59SAmarnath Hullur Subramanyam 	get_dhcp_info(&ipaddress, &gateway, &prefixLength, &dns1, &dns2,
2399c381f59SAmarnath Hullur Subramanyam 		      &serveraddr, &lease);
2409c381f59SAmarnath Hullur Subramanyam 	while (wait_limit > 0) {
2419c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO, "Peer IP: %u", ipaddress);
2429c381f59SAmarnath Hullur Subramanyam 		if (strlen(ipaddr(serveraddr)) > 8) {
2439c381f59SAmarnath Hullur Subramanyam 			/* connected */
244b8fc5cc8SPeng Xu 			strlcpy(ipAddr, ipaddr(serveraddr), 16);
2459c381f59SAmarnath Hullur Subramanyam 			break;
2469c381f59SAmarnath Hullur Subramanyam 		}
2479c381f59SAmarnath Hullur Subramanyam 		sleep(1);
2489c381f59SAmarnath Hullur Subramanyam 		wait_limit--;
2499c381f59SAmarnath Hullur Subramanyam 	}
2509c381f59SAmarnath Hullur Subramanyam 	return wait_limit == 0 ? -1 : 0;
2519c381f59SAmarnath Hullur Subramanyam }
2529c381f59SAmarnath Hullur Subramanyam 
2539c381f59SAmarnath Hullur Subramanyam 
get_p2p_connection_event(struct sigma_dut * dut,const char * input_intf,char * output_intf,int size_output_intf,int * is_group_owner)2549c381f59SAmarnath Hullur Subramanyam static int get_p2p_connection_event(struct sigma_dut *dut,
2559c381f59SAmarnath Hullur Subramanyam 				    const char *input_intf,
2569c381f59SAmarnath Hullur Subramanyam 				    char *output_intf,
2579c381f59SAmarnath Hullur Subramanyam 				    int size_output_intf,
2589c381f59SAmarnath Hullur Subramanyam 				    int *is_group_owner)
2599c381f59SAmarnath Hullur Subramanyam {
2609c381f59SAmarnath Hullur Subramanyam 	/*
2619c381f59SAmarnath Hullur Subramanyam 	* Poll for the P2P Connection
2629c381f59SAmarnath Hullur Subramanyam 	* Then poll for IP
2639c381f59SAmarnath Hullur Subramanyam 	* Then poll for WFD session ID and exit
2649c381f59SAmarnath Hullur Subramanyam 	* P2P connection done
2659c381f59SAmarnath Hullur Subramanyam 	* Loop till connection is ready
2669c381f59SAmarnath Hullur Subramanyam 	*/
2679c381f59SAmarnath Hullur Subramanyam 	struct wpa_ctrl *ctrl;
2689c381f59SAmarnath Hullur Subramanyam 	char *mode_string;
2699c381f59SAmarnath Hullur Subramanyam 	char event_buf[256];
2709c381f59SAmarnath Hullur Subramanyam 	char *ifname;
2719c381f59SAmarnath Hullur Subramanyam 	char *pos;
2729c381f59SAmarnath Hullur Subramanyam 	int res = 0;
2739c381f59SAmarnath Hullur Subramanyam 	const char *events[] = {
2749c381f59SAmarnath Hullur Subramanyam 		"P2P-GROUP-STARTED",
2759c381f59SAmarnath Hullur Subramanyam 		"P2P-GO-NEG-FAILURE",
2769c381f59SAmarnath Hullur Subramanyam 		"P2P-GROUP-FORMATION-FAILURE",
2779c381f59SAmarnath Hullur Subramanyam 		NULL
2789c381f59SAmarnath Hullur Subramanyam 	};
2799c381f59SAmarnath Hullur Subramanyam 
2809c381f59SAmarnath Hullur Subramanyam 	/* Wait for WPA CLI EVENTS */
2819c381f59SAmarnath Hullur Subramanyam 	/* Default timeout is 120s */
2829c381f59SAmarnath Hullur Subramanyam 	ctrl = open_wpa_mon(input_intf);
2839c381f59SAmarnath Hullur Subramanyam 	if (!ctrl) {
2849c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR,
2859c381f59SAmarnath Hullur Subramanyam 				"Failed to open wpa_supplicant monitor connection");
2869c381f59SAmarnath Hullur Subramanyam 		return -1;
2879c381f59SAmarnath Hullur Subramanyam 	}
2889c381f59SAmarnath Hullur Subramanyam 
2899c381f59SAmarnath Hullur Subramanyam 	res = get_wpa_cli_events(dut, ctrl, events, event_buf,
2909c381f59SAmarnath Hullur Subramanyam 				 sizeof(event_buf));
2919c381f59SAmarnath Hullur Subramanyam 
2929c381f59SAmarnath Hullur Subramanyam 	wpa_ctrl_detach(ctrl);
2939c381f59SAmarnath Hullur Subramanyam 	wpa_ctrl_close(ctrl);
2949c381f59SAmarnath Hullur Subramanyam 
2959c381f59SAmarnath Hullur Subramanyam 	if (res < 0) {
2969c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR,
2979c381f59SAmarnath Hullur Subramanyam 				"Group formation did not complete");
2989c381f59SAmarnath Hullur Subramanyam 		return -1;
2999c381f59SAmarnath Hullur Subramanyam 	}
3009c381f59SAmarnath Hullur Subramanyam 
3019c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Received event %s", event_buf);
3029c381f59SAmarnath Hullur Subramanyam 
3039c381f59SAmarnath Hullur Subramanyam 	if (strstr(event_buf, "P2P-GROUP-FORMATION-FAILURE") ||
3049c381f59SAmarnath Hullur Subramanyam 	    strstr(event_buf, "P2P-GO-NEG-FAILURE"))
3059c381f59SAmarnath Hullur Subramanyam 		return -1;
3069c381f59SAmarnath Hullur Subramanyam 
3079c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_INFO, "P2P connection done");
3089c381f59SAmarnath Hullur Subramanyam 	ifname = strchr(event_buf, ' ');
3099c381f59SAmarnath Hullur Subramanyam 	if (!ifname) {
3109c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO, "No P2P interface found");
3119c381f59SAmarnath Hullur Subramanyam 		return -1;
3129c381f59SAmarnath Hullur Subramanyam 	}
3139c381f59SAmarnath Hullur Subramanyam 	ifname++;
3149c381f59SAmarnath Hullur Subramanyam 	pos = strchr(ifname, ' ');
3159c381f59SAmarnath Hullur Subramanyam 	if (!pos) {
3169c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR, "No P2P interface found");
3179c381f59SAmarnath Hullur Subramanyam 		return -1;
3189c381f59SAmarnath Hullur Subramanyam 	}
3199c381f59SAmarnath Hullur Subramanyam 	*pos++ = '\0';
3209c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Group interface %s", ifname);
3219c381f59SAmarnath Hullur Subramanyam 
3229c381f59SAmarnath Hullur Subramanyam 	strlcpy(output_intf, ifname, size_output_intf);
3239c381f59SAmarnath Hullur Subramanyam 
3249c381f59SAmarnath Hullur Subramanyam 	mode_string = pos;
3259c381f59SAmarnath Hullur Subramanyam 	pos = strchr(mode_string, ' ');
3269c381f59SAmarnath Hullur Subramanyam 	if (!pos) {
3279c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR, "No group role found");
3289c381f59SAmarnath Hullur Subramanyam 		return -1;
3299c381f59SAmarnath Hullur Subramanyam 	}
3309c381f59SAmarnath Hullur Subramanyam 
3319c381f59SAmarnath Hullur Subramanyam 	*pos++ = '\0';
3329c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Group Role %s", mode_string);
3339c381f59SAmarnath Hullur Subramanyam 
334bf9bcdf6SSunil Dutt 	if (strcmp(mode_string, "GO") == 0) {
3359c381f59SAmarnath Hullur Subramanyam 		*is_group_owner = 1;
336bf9bcdf6SSunil Dutt 		get_modified_peer_mac_address(dut);
337bf9bcdf6SSunil Dutt 	}
3389c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Value of is_group_owner %d",
3399c381f59SAmarnath Hullur Subramanyam 			*is_group_owner);
3409c381f59SAmarnath Hullur Subramanyam 	return 0;
3419c381f59SAmarnath Hullur Subramanyam }
3429c381f59SAmarnath Hullur Subramanyam 
3439c381f59SAmarnath Hullur Subramanyam 
3449c381f59SAmarnath Hullur Subramanyam /* Following serves as an entry point function to perform rtsp tasks */
miracast_rtsp_thread_entry(void * ptr)3459c381f59SAmarnath Hullur Subramanyam static void * miracast_rtsp_thread_entry(void *ptr)
3469c381f59SAmarnath Hullur Subramanyam {
3479c381f59SAmarnath Hullur Subramanyam 	struct sigma_dut *dut = ptr;
3489c381f59SAmarnath Hullur Subramanyam 	char output_ifname[16];
3499c381f59SAmarnath Hullur Subramanyam 	int is_group_owner = 0;
350d2095485SJouni Malinen 	const char *intf = dut->station_ifname;
3519c381f59SAmarnath Hullur Subramanyam 	unsigned int wait_limit;
3529c381f59SAmarnath Hullur Subramanyam 	char peer_ip_address[32];
353b7c08448SSunil Dutt 	int rtsp_session_id = -1;
3549c381f59SAmarnath Hullur Subramanyam 	int (*extn_start_wfd_connection)(const char *,
3559c381f59SAmarnath Hullur Subramanyam 					 const char *, /* Peer IP */
3569c381f59SAmarnath Hullur Subramanyam 					 int, /* RTSP port number */
3579c381f59SAmarnath Hullur Subramanyam 					 int, /* WFD Device Type; 0-Source,
3589c381f59SAmarnath Hullur Subramanyam 						 1-P-Sink, 2-Secondary Sink */
359b7c08448SSunil Dutt 					 int *); /* for returning session ID */
3609c381f59SAmarnath Hullur Subramanyam 
3619c381f59SAmarnath Hullur Subramanyam 	miracast_load(dut);
3629c381f59SAmarnath Hullur Subramanyam 
363d2095485SJouni Malinen 	if (dut->main_ifname) {
3645ea3092bSJouni Malinen 		intf = get_main_ifname(dut);
3659c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_DEBUG,
3669c381f59SAmarnath Hullur Subramanyam 				"miracast_rtsp_thread_entry: sigma_main_ifname = [%s]",
3679c381f59SAmarnath Hullur Subramanyam 				intf);
3689c381f59SAmarnath Hullur Subramanyam 	} else {
3699c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_DEBUG,
3709c381f59SAmarnath Hullur Subramanyam 				"miracast_rtsp_thread_entry: sigma_main_ifname is NULL");
3719c381f59SAmarnath Hullur Subramanyam 	}
3729c381f59SAmarnath Hullur Subramanyam 
3739c381f59SAmarnath Hullur Subramanyam 	if (get_p2p_connection_event(dut, intf, output_ifname,
3749c381f59SAmarnath Hullur Subramanyam 				     sizeof(output_ifname),
3759c381f59SAmarnath Hullur Subramanyam 				     &is_group_owner) < 0) {
3769c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR, "P2P connection failure");
3779c381f59SAmarnath Hullur Subramanyam 		goto EXIT;
3789c381f59SAmarnath Hullur Subramanyam 	}
3799c381f59SAmarnath Hullur Subramanyam 
3809c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting to start dhcp");
3819c381f59SAmarnath Hullur Subramanyam 
3829c381f59SAmarnath Hullur Subramanyam 	/* Calling WFD APIs now */
3839c381f59SAmarnath Hullur Subramanyam 	/* If you are a source, go ahead and start the RTSP server */
3849c381f59SAmarnath Hullur Subramanyam 	if (dut->wfd_device_type != 0)
3859c381f59SAmarnath Hullur Subramanyam 		wait_limit = HUNDRED_SECOND_TIMEOUT;
3869c381f59SAmarnath Hullur Subramanyam 	else
3879c381f59SAmarnath Hullur Subramanyam 		wait_limit = 500;
3889c381f59SAmarnath Hullur Subramanyam 
3899c381f59SAmarnath Hullur Subramanyam 	if (!is_group_owner) {
3909c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
3919c381f59SAmarnath Hullur Subramanyam 				"Waiting to start dhcp client");
3929c381f59SAmarnath Hullur Subramanyam 		sleep(5); /* Wait for IP */
3939c381f59SAmarnath Hullur Subramanyam 		miracast_start_dhcp_client(dut, output_ifname);
3949c381f59SAmarnath Hullur Subramanyam 		sleep(5); /* Wait for IP */
3959c381f59SAmarnath Hullur Subramanyam 		if (get_peer_ip_p2p_client(dut, peer_ip_address, output_ifname,
3969c381f59SAmarnath Hullur Subramanyam 					   wait_limit) < 0) {
3979c381f59SAmarnath Hullur Subramanyam 			sigma_dut_print(dut, DUT_MSG_ERROR,
3989c381f59SAmarnath Hullur Subramanyam 					"Could not get peer IP");
3999c381f59SAmarnath Hullur Subramanyam 			goto EXIT;
4009c381f59SAmarnath Hullur Subramanyam 		}
4019c381f59SAmarnath Hullur Subramanyam 	} else {
4029c381f59SAmarnath Hullur Subramanyam 		stop_dhcp(dut, output_ifname, 1);
4039c381f59SAmarnath Hullur Subramanyam 		/* For GO read the DHCP Lease File */
4049c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
4059c381f59SAmarnath Hullur Subramanyam 				"Waiting to start dhcp server");
4069c381f59SAmarnath Hullur Subramanyam 		start_dhcp(dut, output_ifname, 1);
4079c381f59SAmarnath Hullur Subramanyam 		sleep(5);
408bf9bcdf6SSunil Dutt 		if (get_peer_ip_p2p_go(dut, peer_ip_address, wait_limit) < 0) {
4099c381f59SAmarnath Hullur Subramanyam 			sigma_dut_print(dut, DUT_MSG_ERROR,
4109c381f59SAmarnath Hullur Subramanyam 					"Could not get peer IP");
4119c381f59SAmarnath Hullur Subramanyam 			goto EXIT;
4129c381f59SAmarnath Hullur Subramanyam 		}
4139c381f59SAmarnath Hullur Subramanyam 	}
4149c381f59SAmarnath Hullur Subramanyam 
4159c381f59SAmarnath Hullur Subramanyam 	extn_start_wfd_connection = dlsym(dut->miracast_lib,
4169c381f59SAmarnath Hullur Subramanyam 					  "start_wfd_connection");
4179c381f59SAmarnath Hullur Subramanyam 	if (extn_start_wfd_connection) {
4189c381f59SAmarnath Hullur Subramanyam 		extn_start_wfd_connection(NULL, peer_ip_address,
4199c381f59SAmarnath Hullur Subramanyam 					  session_management_control_port,
4209c381f59SAmarnath Hullur Subramanyam 					  1 - dut->wfd_device_type,
421b7c08448SSunil Dutt 					  &rtsp_session_id);
4229c381f59SAmarnath Hullur Subramanyam 	} else {
4239c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
4249c381f59SAmarnath Hullur Subramanyam 				"dlsym seems to have error %p %p",
4259c381f59SAmarnath Hullur Subramanyam 				dut->miracast_lib, extn_start_wfd_connection);
4269c381f59SAmarnath Hullur Subramanyam 	}
4279c381f59SAmarnath Hullur Subramanyam 
4289c381f59SAmarnath Hullur Subramanyam EXIT:
4299c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_INFO, "Reached Miracast thread exit");
4309c381f59SAmarnath Hullur Subramanyam 
4319c381f59SAmarnath Hullur Subramanyam 	return NULL;
4329c381f59SAmarnath Hullur Subramanyam }
4339c381f59SAmarnath Hullur Subramanyam 
4349c381f59SAmarnath Hullur Subramanyam 
4359c381f59SAmarnath Hullur Subramanyam /*----------------------------------------------------------------------
4369c381f59SAmarnath Hullur Subramanyam   WFD Source IE: 000601101c440036
4379c381f59SAmarnath Hullur Subramanyam   len        WFD device info          control port              throughput
4389c381f59SAmarnath Hullur Subramanyam   110]    [00000 00100010 000]    [00011 10001000 100]    [00000 00000110 110]
4399c381f59SAmarnath Hullur Subramanyam 				       = 7236
4409c381f59SAmarnath Hullur Subramanyam 
4419c381f59SAmarnath Hullur Subramanyam   WFD Sink IE: 000601511c440036
4429c381f59SAmarnath Hullur Subramanyam   len        WFD device info          control port              throughput
4439c381f59SAmarnath Hullur Subramanyam   110]    [00000 00101010 001]    [00011 10001000 100]    [00000 00000110 110]
4449c381f59SAmarnath Hullur Subramanyam 				       = 7236
4459c381f59SAmarnath Hullur Subramanyam 
4469c381f59SAmarnath Hullur Subramanyam   WFD device info:
4479c381f59SAmarnath Hullur Subramanyam   BITS        NAME                DESCRIPTION
4489c381f59SAmarnath Hullur Subramanyam   -------------------------------------------
4499c381f59SAmarnath Hullur Subramanyam   1:0     WFD Device Type     0b00: WFD Source
4509c381f59SAmarnath Hullur Subramanyam 			      0b01: Primary Sink
4519c381f59SAmarnath Hullur Subramanyam 			      0b10: Secondary Sink
4529c381f59SAmarnath Hullur Subramanyam 			      0b11: Dual Role, either WFD Source/Primary sink
4539c381f59SAmarnath Hullur Subramanyam 
4549c381f59SAmarnath Hullur Subramanyam   5:4     WFD Session         0b00: Not available for WFD Session
4559c381f59SAmarnath Hullur Subramanyam 			Availibility	0b01: Available for WFD Session
4569c381f59SAmarnath Hullur Subramanyam 							0b10, 0b11: Reserved
4579c381f59SAmarnath Hullur Subramanyam 
4589c381f59SAmarnath Hullur Subramanyam   6       WSD Support Bit     0b0: WFD Service Discovery not supported
4599c381f59SAmarnath Hullur Subramanyam 			      0b1: WFD Service Discovery supported
4609c381f59SAmarnath Hullur Subramanyam 
4619c381f59SAmarnath Hullur Subramanyam   8       CP Support Bit      0b0: Content Protection via HDCP not supported
4629c381f59SAmarnath Hullur Subramanyam 			      0b1: Content Protection via HDCP supported
4639c381f59SAmarnath Hullur Subramanyam ---------------------------------------------------------------------------
4649c381f59SAmarnath Hullur Subramanyam */
4659c381f59SAmarnath Hullur Subramanyam 
miracast_set_wfd_ie(struct sigma_dut * sigma_dut)4669c381f59SAmarnath Hullur Subramanyam static void miracast_set_wfd_ie(struct sigma_dut *sigma_dut)
4679c381f59SAmarnath Hullur Subramanyam {
468d2095485SJouni Malinen 	const char *intf = sigma_dut->station_ifname;
4699c381f59SAmarnath Hullur Subramanyam 
470d2095485SJouni Malinen 	if (sigma_dut->main_ifname != NULL)
4715ea3092bSJouni Malinen 		intf = get_main_ifname(sigma_dut);
4729c381f59SAmarnath Hullur Subramanyam 
4739c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(sigma_dut, DUT_MSG_DEBUG, "miracast_set_wfd_ie() = intf = %s",
4749c381f59SAmarnath Hullur Subramanyam 			intf);
4759c381f59SAmarnath Hullur Subramanyam 	wpa_command(intf, "SET wifi_display 1");
4769c381f59SAmarnath Hullur Subramanyam 
4779c381f59SAmarnath Hullur Subramanyam 	if (sigma_dut->wfd_device_type == 0) {
4789c381f59SAmarnath Hullur Subramanyam 		wpa_command(intf, "WFD_SUBELEM_SET 0 000601101c440036");
4799c381f59SAmarnath Hullur Subramanyam 		wpa_command(intf, "WFD_SUBELEM_SET 11 00020000");
4809c381f59SAmarnath Hullur Subramanyam 	} else {
4819c381f59SAmarnath Hullur Subramanyam 		wpa_command(intf, "WFD_SUBELEM_SET 0 000601511c440036");
4829c381f59SAmarnath Hullur Subramanyam 		wpa_command(intf, "WFD_SUBELEM_SET 11 00020001");
4839c381f59SAmarnath Hullur Subramanyam 	}
4849c381f59SAmarnath Hullur Subramanyam }
4859c381f59SAmarnath Hullur Subramanyam 
4869c381f59SAmarnath Hullur Subramanyam 
miracast_init(struct sigma_dut * dut)4879c381f59SAmarnath Hullur Subramanyam void miracast_init(struct sigma_dut *dut)
4889c381f59SAmarnath Hullur Subramanyam {
4899c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Create thread pool for VDS");
4909c381f59SAmarnath Hullur Subramanyam 	miracast_set_wfd_ie(dut);
4919c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Clear groupID @ start");
4929c381f59SAmarnath Hullur Subramanyam }
4939c381f59SAmarnath Hullur Subramanyam 
4949c381f59SAmarnath Hullur Subramanyam 
miracast_deinit(struct sigma_dut * dut)4959c381f59SAmarnath Hullur Subramanyam void miracast_deinit(struct sigma_dut *dut)
4969c381f59SAmarnath Hullur Subramanyam {
4979c381f59SAmarnath Hullur Subramanyam 	(void) miracast_unload(dut);
4989c381f59SAmarnath Hullur Subramanyam }
4999c381f59SAmarnath Hullur Subramanyam 
5009c381f59SAmarnath Hullur Subramanyam 
miracast_generate_string_cmd(struct sigma_cmd * cmd,char * strcmd,size_t size)5019c381f59SAmarnath Hullur Subramanyam static void miracast_generate_string_cmd(struct sigma_cmd *cmd, char *strcmd,
5029c381f59SAmarnath Hullur Subramanyam 					 size_t size)
5039c381f59SAmarnath Hullur Subramanyam {
5049c381f59SAmarnath Hullur Subramanyam 	int i = 0;
5059c381f59SAmarnath Hullur Subramanyam 	char *pos, *end;
5069c381f59SAmarnath Hullur Subramanyam 	int ret;
5079c381f59SAmarnath Hullur Subramanyam 
5089c381f59SAmarnath Hullur Subramanyam 	if (!strcmd)
5099c381f59SAmarnath Hullur Subramanyam 		return;
5109c381f59SAmarnath Hullur Subramanyam 	strcmd[0] = '\0';
5119c381f59SAmarnath Hullur Subramanyam 	pos = strcmd;
5129c381f59SAmarnath Hullur Subramanyam 	end = strcmd + size;
5139c381f59SAmarnath Hullur Subramanyam 	for (i = 0; i < cmd->count; i++) {
5149c381f59SAmarnath Hullur Subramanyam 		ret = snprintf(pos, end - pos, "%s,%s,", cmd->params[i],
5159c381f59SAmarnath Hullur Subramanyam 			       cmd->values[i]);
516d2c14390SAmarnath Hullur Subramanyam 		if (ret < 0 || ret >= end - pos)
5179c381f59SAmarnath Hullur Subramanyam 			break;
5189c381f59SAmarnath Hullur Subramanyam 		pos += ret;
5199c381f59SAmarnath Hullur Subramanyam 	}
5209c381f59SAmarnath Hullur Subramanyam 
5219c381f59SAmarnath Hullur Subramanyam 	pos = strrchr(strcmd, ',');
5229c381f59SAmarnath Hullur Subramanyam 	if (pos)
5239c381f59SAmarnath Hullur Subramanyam 		*pos = '\0';
5249c381f59SAmarnath Hullur Subramanyam 	printf("Miracast: generated command: %s\n", strcmd);
5259c381f59SAmarnath Hullur Subramanyam }
5269c381f59SAmarnath Hullur Subramanyam 
5279c381f59SAmarnath Hullur Subramanyam 
auto_go_thread_entry(void * ptr)5289c381f59SAmarnath Hullur Subramanyam static void * auto_go_thread_entry(void *ptr)
5299c381f59SAmarnath Hullur Subramanyam {
5309c381f59SAmarnath Hullur Subramanyam 	struct sigma_dut *dut = ptr;
5319c381f59SAmarnath Hullur Subramanyam 	struct wpa_ctrl *ctrl;
5329c381f59SAmarnath Hullur Subramanyam 	char event_buf[64];
5339c381f59SAmarnath Hullur Subramanyam 	char *peer = NULL;
5349c381f59SAmarnath Hullur Subramanyam 	int res = 0;
5359c381f59SAmarnath Hullur Subramanyam 	char macaddress[32];
5369c381f59SAmarnath Hullur Subramanyam 	char peer_ip_address[32];
537b7c08448SSunil Dutt 	int rtsp_session_id = -1;
5389c381f59SAmarnath Hullur Subramanyam 	int (*extn_start_wfd_connection)(const char *,
5399c381f59SAmarnath Hullur Subramanyam 					 const char *, /* Peer IP */
5409c381f59SAmarnath Hullur Subramanyam 					 int, /* RTSP port number */
5419c381f59SAmarnath Hullur Subramanyam 					 int, /* WFD Device Type; 0-Source,
5429c381f59SAmarnath Hullur Subramanyam 						1-P-Sink, 2-Secondary Sink */
543b7c08448SSunil Dutt 					 int *); /* for returning session ID */
5449c381f59SAmarnath Hullur Subramanyam 
5459c381f59SAmarnath Hullur Subramanyam 	stop_dhcp(dut, wfd_ifname, 1);
5469c381f59SAmarnath Hullur Subramanyam 	/* For auto-GO, start the DHCP server and wait for 5 seconds */
5479c381f59SAmarnath Hullur Subramanyam 	start_dhcp(dut, wfd_ifname, 1);
5489c381f59SAmarnath Hullur Subramanyam 	sleep(5); /* Wait for IP */
5499c381f59SAmarnath Hullur Subramanyam 
5509c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_INFO, "Wait for AP-STA-CONNECTED");
5519c381f59SAmarnath Hullur Subramanyam 	ctrl = open_wpa_mon(wfd_ifname); /* Refer to wfd_ifname */
5529c381f59SAmarnath Hullur Subramanyam 	if (!ctrl) {
5539c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR,
5549c381f59SAmarnath Hullur Subramanyam 				"Failed to open wpa_supplicant monitor connection");
5559c381f59SAmarnath Hullur Subramanyam 		goto THR_EXIT;
5569c381f59SAmarnath Hullur Subramanyam 	}
5579c381f59SAmarnath Hullur Subramanyam 	res = get_wpa_cli_event(dut, ctrl, "AP-STA-CONNECTED",
5589c381f59SAmarnath Hullur Subramanyam 				event_buf, sizeof(event_buf));
5599c381f59SAmarnath Hullur Subramanyam 	wpa_ctrl_detach(ctrl);
5609c381f59SAmarnath Hullur Subramanyam 	wpa_ctrl_close(ctrl);
5619c381f59SAmarnath Hullur Subramanyam 
5629c381f59SAmarnath Hullur Subramanyam 	if (res < 0) {
5639c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR,
5649c381f59SAmarnath Hullur Subramanyam 				"Could not get event before timeout");
5659c381f59SAmarnath Hullur Subramanyam 		goto THR_EXIT;
5669c381f59SAmarnath Hullur Subramanyam 	}
5679c381f59SAmarnath Hullur Subramanyam 
5689c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "STA Connected Event: '%s'",
5699c381f59SAmarnath Hullur Subramanyam 			event_buf);
5709c381f59SAmarnath Hullur Subramanyam 	peer = strchr(event_buf, ' ');
5719c381f59SAmarnath Hullur Subramanyam 	if (!peer) {
5729c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR, "Could not find STA MAC");
5739c381f59SAmarnath Hullur Subramanyam 		goto THR_EXIT;
5749c381f59SAmarnath Hullur Subramanyam 	}
5759c381f59SAmarnath Hullur Subramanyam 
5769c381f59SAmarnath Hullur Subramanyam 	peer++;
577b8fc5cc8SPeng Xu 	strlcpy(macaddress, peer, sizeof(macaddress));
578bf9bcdf6SSunil Dutt 	if (get_peer_ip_p2p_go(dut, peer_ip_address, 30) < 0) {
5799c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR, "Could not get peer IP");
5809c381f59SAmarnath Hullur Subramanyam 		goto THR_EXIT;
5819c381f59SAmarnath Hullur Subramanyam 	}
5829c381f59SAmarnath Hullur Subramanyam 
5839c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_INFO, "dlsym %p", dut->miracast_lib);
5849c381f59SAmarnath Hullur Subramanyam 	extn_start_wfd_connection = dlsym(dut->miracast_lib,
5859c381f59SAmarnath Hullur Subramanyam 					  "start_wfd_connection");
5869c381f59SAmarnath Hullur Subramanyam 	if (!extn_start_wfd_connection)
5879c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO, "dlsym function NULL");
5889c381f59SAmarnath Hullur Subramanyam 	else
5899c381f59SAmarnath Hullur Subramanyam 		extn_start_wfd_connection(NULL, peer_ip_address,
5909c381f59SAmarnath Hullur Subramanyam 					  session_management_control_port,
5919c381f59SAmarnath Hullur Subramanyam 					  1 - dut->wfd_device_type,
592b7c08448SSunil Dutt 					  &rtsp_session_id);
5939c381f59SAmarnath Hullur Subramanyam 
5949c381f59SAmarnath Hullur Subramanyam THR_EXIT:
5959c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_INFO, "Reached auto GO thread exit");
5969c381f59SAmarnath Hullur Subramanyam 	return NULL;
5979c381f59SAmarnath Hullur Subramanyam }
5989c381f59SAmarnath Hullur Subramanyam 
5999c381f59SAmarnath Hullur Subramanyam 
miracast_sta_reset_default(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)6009c381f59SAmarnath Hullur Subramanyam void miracast_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
6019c381f59SAmarnath Hullur Subramanyam 				struct sigma_cmd *cmd)
6029c381f59SAmarnath Hullur Subramanyam {
603d2095485SJouni Malinen 	const char *intf = dut->station_ifname;
604ed5e050dSSunil Dutt 	int (*extn_sta_reset_default)(const char *);
6059c381f59SAmarnath Hullur Subramanyam 	char string_cmd[MIRACAST_CMD_LEN] = { 0 };
6069c381f59SAmarnath Hullur Subramanyam 
607d2095485SJouni Malinen 	if (dut->main_ifname != NULL)
6085ea3092bSJouni Malinen 		intf = get_main_ifname(dut);
6099c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG,
6109c381f59SAmarnath Hullur Subramanyam 			"miracast_sta_reset_default() = intf = %s", intf);
6119c381f59SAmarnath Hullur Subramanyam 	stop_dhcp(dut, intf, 1); /* IFNAME argument is ignored */
6129c381f59SAmarnath Hullur Subramanyam 	miracast_stop_dhcp_client(dut, intf);
6139c381f59SAmarnath Hullur Subramanyam 
6149c381f59SAmarnath Hullur Subramanyam 	/* This is where vendor Miracast library is loaded and function pointers
6159c381f59SAmarnath Hullur Subramanyam 	 * to Miracast functions (defined by CAPI) are loaded. */
6169c381f59SAmarnath Hullur Subramanyam 
6179c381f59SAmarnath Hullur Subramanyam 	if (miracast_load(dut) != 0) {
6189c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
6199c381f59SAmarnath Hullur Subramanyam 				"Fail to load Miracast library");
6209c381f59SAmarnath Hullur Subramanyam 		return;
6219c381f59SAmarnath Hullur Subramanyam 	}
6229c381f59SAmarnath Hullur Subramanyam 
6239c381f59SAmarnath Hullur Subramanyam 	if (!dut->miracast_lib) {
6249c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR,
6259c381f59SAmarnath Hullur Subramanyam 				"Miracast library is absent");
6269c381f59SAmarnath Hullur Subramanyam 		return;
6279c381f59SAmarnath Hullur Subramanyam 	}
6289c381f59SAmarnath Hullur Subramanyam 
6299c381f59SAmarnath Hullur Subramanyam 	dlerror();
6309c381f59SAmarnath Hullur Subramanyam 
6319c381f59SAmarnath Hullur Subramanyam 	miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd));
6329c381f59SAmarnath Hullur Subramanyam 	extn_sta_reset_default = dlsym(dut->miracast_lib, "sta_reset_default");
6339c381f59SAmarnath Hullur Subramanyam 	if (extn_sta_reset_default)
6349c381f59SAmarnath Hullur Subramanyam 		extn_sta_reset_default(string_cmd);
6359c381f59SAmarnath Hullur Subramanyam 
6369c381f59SAmarnath Hullur Subramanyam 	/* delete threads if any */
6379c381f59SAmarnath Hullur Subramanyam 	/* TODO: if dut->rtsp_thread_handle running, call
6389c381f59SAmarnath Hullur Subramanyam 	 * miracast_release_rtsp_thread_resources(dut); */
6399c381f59SAmarnath Hullur Subramanyam }
6409c381f59SAmarnath Hullur Subramanyam 
6419c381f59SAmarnath Hullur Subramanyam 
miracast_start_autonomous_go(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd,char * ifname)6429c381f59SAmarnath Hullur Subramanyam void miracast_start_autonomous_go(struct sigma_dut *dut,
6439c381f59SAmarnath Hullur Subramanyam 				  struct sigma_conn *conn,
6449c381f59SAmarnath Hullur Subramanyam 				  struct sigma_cmd *cmd, char *ifname)
6459c381f59SAmarnath Hullur Subramanyam {
6469c381f59SAmarnath Hullur Subramanyam 	strlcpy(wfd_ifname, ifname, sizeof(wfd_ifname));
6479c381f59SAmarnath Hullur Subramanyam 	(void) pthread_create(&dut->rtsp_thread_handle, NULL,
6489c381f59SAmarnath Hullur Subramanyam 			      auto_go_thread_entry, dut);
6499c381f59SAmarnath Hullur Subramanyam }
6509c381f59SAmarnath Hullur Subramanyam 
6519c381f59SAmarnath Hullur Subramanyam 
miracast_rtsp_thread_create(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)6529c381f59SAmarnath Hullur Subramanyam static void miracast_rtsp_thread_create(struct sigma_dut *dut,
6539c381f59SAmarnath Hullur Subramanyam 					struct sigma_conn *conn,
6549c381f59SAmarnath Hullur Subramanyam 					struct sigma_cmd *cmd)
6559c381f59SAmarnath Hullur Subramanyam {
6569c381f59SAmarnath Hullur Subramanyam 	(void) pthread_create(&dut->rtsp_thread_handle, NULL,
6579c381f59SAmarnath Hullur Subramanyam 			      miracast_rtsp_thread_entry, dut);
6589c381f59SAmarnath Hullur Subramanyam }
6599c381f59SAmarnath Hullur Subramanyam 
6609c381f59SAmarnath Hullur Subramanyam 
miracast_dev_send_frame(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)6619c381f59SAmarnath Hullur Subramanyam int miracast_dev_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
6629c381f59SAmarnath Hullur Subramanyam 			    struct sigma_cmd *cmd)
6639c381f59SAmarnath Hullur Subramanyam {
6649c381f59SAmarnath Hullur Subramanyam 	const char *frame_name = get_param(cmd, "FrameName");
6659c381f59SAmarnath Hullur Subramanyam 	/* const char *source = get_param(cmd, "Source"); */
6669c381f59SAmarnath Hullur Subramanyam 	/* const char *destination = get_param(cmd, "Destination"); */
6679c381f59SAmarnath Hullur Subramanyam 	/* const char *dev_type = get_param(cmd, "DevType"); */
6689c381f59SAmarnath Hullur Subramanyam 	const char *rtsp_msg_type = get_param(cmd, "RtspMsgType");
6699c381f59SAmarnath Hullur Subramanyam 	/* const char *wfd_session_id = get_param(cmd, "WfdSessionID"); */
6709c381f59SAmarnath Hullur Subramanyam 	int (*dev_send_frame)(const char *);
6719c381f59SAmarnath Hullur Subramanyam 	char string_cmd[MIRACAST_CMD_LEN] = { 0 };
6729c381f59SAmarnath Hullur Subramanyam 
6739c381f59SAmarnath Hullur Subramanyam 	dev_send_frame = dlsym(dut->miracast_lib, "dev_send_frame");
6749c381f59SAmarnath Hullur Subramanyam 	if (!dev_send_frame)
6759c381f59SAmarnath Hullur Subramanyam 		return -1;
6769c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "miracast_dev_send_frame 1");
6779c381f59SAmarnath Hullur Subramanyam 	miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd));
6789e1dcf80SJouni Malinen 	if (!frame_name)
6799e1dcf80SJouni Malinen 		return 0;
6809e1dcf80SJouni Malinen 	if (strcasecmp(frame_name, "RTSP") != 0)
681e9fa7953SPeng Xu 		return 0;
682e9fa7953SPeng Xu 
683e9fa7953SPeng Xu 	if (!rtsp_msg_type)
6849c381f59SAmarnath Hullur Subramanyam 		return 0;
6859c381f59SAmarnath Hullur Subramanyam 
6869c381f59SAmarnath Hullur Subramanyam 	if (strcasecmp(rtsp_msg_type, "PAUSE") == 0 ||
6879c381f59SAmarnath Hullur Subramanyam 	    strcasecmp(rtsp_msg_type, "TRIGGER-PAUSE") == 0) {
6889c381f59SAmarnath Hullur Subramanyam 		/* Call RTSP Pause */
6899c381f59SAmarnath Hullur Subramanyam 		dev_send_frame(string_cmd);
6909c381f59SAmarnath Hullur Subramanyam 		return 1;
6919c381f59SAmarnath Hullur Subramanyam 	}
6929c381f59SAmarnath Hullur Subramanyam 
6939c381f59SAmarnath Hullur Subramanyam 	if (strcasecmp(rtsp_msg_type, "PLAY") == 0 ||
6949c381f59SAmarnath Hullur Subramanyam 	    strcasecmp(rtsp_msg_type, "TRIGGER-PLAY") == 0) {
6959c381f59SAmarnath Hullur Subramanyam 		/* Call RTSP Play */;
6969c381f59SAmarnath Hullur Subramanyam 		dev_send_frame(string_cmd); /* Not for secure playback */
6979c381f59SAmarnath Hullur Subramanyam 		return 1;
6989c381f59SAmarnath Hullur Subramanyam 	}
6999c381f59SAmarnath Hullur Subramanyam 
7009c381f59SAmarnath Hullur Subramanyam 	if (strcasecmp(rtsp_msg_type, "TEARDOWN") == 0 ||
7019c381f59SAmarnath Hullur Subramanyam 	    strcasecmp(rtsp_msg_type, "TRIGGER-TEARDOWN") == 0) {
7029c381f59SAmarnath Hullur Subramanyam 		dev_send_frame(string_cmd); /* RTSP Teardown */
7039c381f59SAmarnath Hullur Subramanyam 		return 1;
7049c381f59SAmarnath Hullur Subramanyam 	}
7059c381f59SAmarnath Hullur Subramanyam 
7069c381f59SAmarnath Hullur Subramanyam 	if (strcasecmp(rtsp_msg_type,"SET_PARAMETER") == 0) {
7079c381f59SAmarnath Hullur Subramanyam 		const char *set_parameter = get_param(cmd, "SetParameter");
7089c381f59SAmarnath Hullur Subramanyam 		const char *transportType = get_param(cmd, "TransportType");
7099c381f59SAmarnath Hullur Subramanyam 
7109c381f59SAmarnath Hullur Subramanyam 		if (set_parameter == NULL && transportType == NULL) {
7119c381f59SAmarnath Hullur Subramanyam 			send_resp(dut, conn, SIGMA_ERROR,
7129c381f59SAmarnath Hullur Subramanyam 				  "errorCode,Invalid Set Parameter value");
7139c381f59SAmarnath Hullur Subramanyam 			return 0;
7149c381f59SAmarnath Hullur Subramanyam 		}
7159c381f59SAmarnath Hullur Subramanyam 
7169c381f59SAmarnath Hullur Subramanyam 		if (1) /* (strcasecmp(set_parameter, "Standby") == 0) */ {
7179c381f59SAmarnath Hullur Subramanyam 			dev_send_frame(string_cmd);
7189c381f59SAmarnath Hullur Subramanyam 			return 1;
7199c381f59SAmarnath Hullur Subramanyam 		}
7209c381f59SAmarnath Hullur Subramanyam 		/* TODO More needs to be implemented when the spec is clearer */
7219c381f59SAmarnath Hullur Subramanyam 		return 1;
7229c381f59SAmarnath Hullur Subramanyam 	}
7239c381f59SAmarnath Hullur Subramanyam 
7249c381f59SAmarnath Hullur Subramanyam 	if (strcasecmp(rtsp_msg_type, "SETUP") == 0) {
7259c381f59SAmarnath Hullur Subramanyam 		dev_send_frame(string_cmd);
7269c381f59SAmarnath Hullur Subramanyam 		/* TODO More needs to be implemented when the spec is clearer */
7279c381f59SAmarnath Hullur Subramanyam 		return 1;
7289c381f59SAmarnath Hullur Subramanyam 	}
7299c381f59SAmarnath Hullur Subramanyam 
7309c381f59SAmarnath Hullur Subramanyam 	if (strcasecmp(frame_name, "WFD_ProbeReq") == 0) {
7319c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR,
7329c381f59SAmarnath Hullur Subramanyam 			  "errorCode,Unsupported WFD Probe Request");
7339c381f59SAmarnath Hullur Subramanyam 		return 0;
7349c381f59SAmarnath Hullur Subramanyam 	}
7359c381f59SAmarnath Hullur Subramanyam 
7369c381f59SAmarnath Hullur Subramanyam 	if (strcasecmp(frame_name, "WFD_ServiceDiscReq") == 0) {
7379c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR,
7389c381f59SAmarnath Hullur Subramanyam 			  "errorCode,Unsupported WFD Service Discovery");
7399c381f59SAmarnath Hullur Subramanyam 		return 0;
7409c381f59SAmarnath Hullur Subramanyam 	}
7419c381f59SAmarnath Hullur Subramanyam 
7429c381f59SAmarnath Hullur Subramanyam 	send_resp(dut, conn, SIGMA_ERROR,
7439c381f59SAmarnath Hullur Subramanyam 		  "errorCode,Unsupported dev_send_frame");
7449c381f59SAmarnath Hullur Subramanyam 	return 0;
7459c381f59SAmarnath Hullur Subramanyam }
7469c381f59SAmarnath Hullur Subramanyam 
7479c381f59SAmarnath Hullur Subramanyam 
miracast_dev_exec_action(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)7489c381f59SAmarnath Hullur Subramanyam int miracast_dev_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
7499c381f59SAmarnath Hullur Subramanyam 			     struct sigma_cmd *cmd)
7509c381f59SAmarnath Hullur Subramanyam {
7519c381f59SAmarnath Hullur Subramanyam 	const char *service_type = get_param(cmd,"ServiceType");
7529c381f59SAmarnath Hullur Subramanyam 	int (*dev_exec_action)(const char *);
7539c381f59SAmarnath Hullur Subramanyam 	char string_cmd[MIRACAST_CMD_LEN] = { 0 };
7549c381f59SAmarnath Hullur Subramanyam 
7559c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "miracast_dev_exec_frame");
7569c381f59SAmarnath Hullur Subramanyam 
7579c381f59SAmarnath Hullur Subramanyam 	if (service_type) {
7589c381f59SAmarnath Hullur Subramanyam 		char resp_buf[128];
7599c381f59SAmarnath Hullur Subramanyam 
7609c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_DEBUG, "MDNS Instance Name = %s",
7619c381f59SAmarnath Hullur Subramanyam 				dut->mdns_instance_name);
7629c381f59SAmarnath Hullur Subramanyam 		strlcpy(resp_buf, "InstanceName,", sizeof(resp_buf));
7639c381f59SAmarnath Hullur Subramanyam 		strlcat(resp_buf + strlen(resp_buf), dut->mdns_instance_name,
7649c381f59SAmarnath Hullur Subramanyam 			sizeof(resp_buf) - strlen(resp_buf));
7659c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
7669c381f59SAmarnath Hullur Subramanyam 		return 0;
7679c381f59SAmarnath Hullur Subramanyam 	}
7689c381f59SAmarnath Hullur Subramanyam 
7699c381f59SAmarnath Hullur Subramanyam 	miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd));
7709c381f59SAmarnath Hullur Subramanyam 	dev_exec_action = dlsym(dut->miracast_lib, "dev_exec_action");
7719c381f59SAmarnath Hullur Subramanyam 	if (!dev_exec_action)
7729c381f59SAmarnath Hullur Subramanyam 		return -2;
7739c381f59SAmarnath Hullur Subramanyam 	return dev_exec_action(string_cmd);
7749c381f59SAmarnath Hullur Subramanyam }
7759c381f59SAmarnath Hullur Subramanyam 
7769c381f59SAmarnath Hullur Subramanyam 
miracast_preset_testparameters(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)7779c381f59SAmarnath Hullur Subramanyam int miracast_preset_testparameters(struct sigma_dut *dut,
7789c381f59SAmarnath Hullur Subramanyam 				   struct sigma_conn *conn,
7799c381f59SAmarnath Hullur Subramanyam 				   struct sigma_cmd *cmd)
7809c381f59SAmarnath Hullur Subramanyam {
7819c381f59SAmarnath Hullur Subramanyam 	const char *mdns_disc = get_param(cmd, "mdns_disc");
7829c381f59SAmarnath Hullur Subramanyam 	const char *mdns_role = get_param(cmd, "mdns_role");
7839c381f59SAmarnath Hullur Subramanyam 	char string_cmd[MIRACAST_CMD_LEN];
7849c381f59SAmarnath Hullur Subramanyam 	int ret = 0;
7859c381f59SAmarnath Hullur Subramanyam 	char string_resp[64] = { 0 };
7869c381f59SAmarnath Hullur Subramanyam 	int (*extn_sta_preset_test_parameter)(const char *, char *, int);
7879c381f59SAmarnath Hullur Subramanyam 
7889c381f59SAmarnath Hullur Subramanyam 	miracast_load(dut);
7899c381f59SAmarnath Hullur Subramanyam 	miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd));
7909c381f59SAmarnath Hullur Subramanyam 	extn_sta_preset_test_parameter =
7919c381f59SAmarnath Hullur Subramanyam 		dlsym(dut->miracast_lib, "sta_preset_testparameters");
7929c381f59SAmarnath Hullur Subramanyam 	if (!extn_sta_preset_test_parameter)
7939c381f59SAmarnath Hullur Subramanyam 		return -1;
7949c381f59SAmarnath Hullur Subramanyam 	ret = extn_sta_preset_test_parameter(string_cmd, string_resp,
7959c381f59SAmarnath Hullur Subramanyam 					     sizeof(string_resp));
7969c381f59SAmarnath Hullur Subramanyam 	if (ret == SIGMA_ERROR) {
7979c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR,
7989c381f59SAmarnath Hullur Subramanyam 			  "Miracast extension reported error in the command sta_preset_testparameters");
7999c381f59SAmarnath Hullur Subramanyam 		return 0;
8009c381f59SAmarnath Hullur Subramanyam 	}
8019c381f59SAmarnath Hullur Subramanyam 
8029c381f59SAmarnath Hullur Subramanyam 	if (mdns_disc && mdns_role) {
8039c381f59SAmarnath Hullur Subramanyam 		if (strlen(string_resp))
8049c381f59SAmarnath Hullur Subramanyam 			strlcpy(dut->mdns_instance_name, string_resp,
8059c381f59SAmarnath Hullur Subramanyam 				sizeof(dut->mdns_instance_name));
8069c381f59SAmarnath Hullur Subramanyam 		else
8079c381f59SAmarnath Hullur Subramanyam 			dut->mdns_instance_name[0] = '\0';
8089c381f59SAmarnath Hullur Subramanyam 	}
8099c381f59SAmarnath Hullur Subramanyam 
8109c381f59SAmarnath Hullur Subramanyam 	return 1;
8119c381f59SAmarnath Hullur Subramanyam }
8129c381f59SAmarnath Hullur Subramanyam 
8139c381f59SAmarnath Hullur Subramanyam 
get_p2p_peers(struct sigma_dut * dut,char * respbuf,size_t bufsize)814016ae6c8SJouni Malinen static int get_p2p_peers(struct sigma_dut *dut, char *respbuf, size_t bufsize)
8159c381f59SAmarnath Hullur Subramanyam {
8169c381f59SAmarnath Hullur Subramanyam 	char addr[1024], cmd[64];
817016ae6c8SJouni Malinen 	const char *intf = get_main_ifname(dut);
8189c381f59SAmarnath Hullur Subramanyam 	int ret;
8199c381f59SAmarnath Hullur Subramanyam 	char *pos, *end;
8209c381f59SAmarnath Hullur Subramanyam 
8219c381f59SAmarnath Hullur Subramanyam 	pos = respbuf;
8229c381f59SAmarnath Hullur Subramanyam 	end = respbuf + bufsize;
8239c381f59SAmarnath Hullur Subramanyam 
8249c381f59SAmarnath Hullur Subramanyam 	if (wpa_command_resp(intf, "P2P_PEER FIRST", addr, 128) >= 0) {
8259c381f59SAmarnath Hullur Subramanyam 		addr[17] = '\0';
826c59f41ccSAmarnath Hullur Subramanyam 		strlcpy(respbuf, addr, bufsize);
827c59f41ccSAmarnath Hullur Subramanyam 		pos += strlen(respbuf);
828d9d6e643SJouni Malinen 		ret = snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
829d9d6e643SJouni Malinen 		if (ret < 0 || ret >= sizeof(cmd))
830d9d6e643SJouni Malinen 			return -1;
8319c381f59SAmarnath Hullur Subramanyam 		memset(addr, 0, sizeof(addr));
8329c381f59SAmarnath Hullur Subramanyam 		while (wpa_command_resp(intf, cmd, addr, sizeof(addr)) >= 0) {
8339c381f59SAmarnath Hullur Subramanyam 			if (memcmp(addr, "FAIL", 4) == 0)
8349c381f59SAmarnath Hullur Subramanyam 				break;
8359c381f59SAmarnath Hullur Subramanyam 			addr[17] = '\0';
8369c381f59SAmarnath Hullur Subramanyam 			ret = snprintf(pos, end - pos, " %s", addr);
8379c381f59SAmarnath Hullur Subramanyam 			if (ret < 0 || ret >= end - pos)
8389c381f59SAmarnath Hullur Subramanyam 				break;
8399c381f59SAmarnath Hullur Subramanyam 			pos += ret;
840d9d6e643SJouni Malinen 			ret = snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s",
841d9d6e643SJouni Malinen 				       addr);
842d9d6e643SJouni Malinen 			if (ret < 0 || ret >= sizeof(cmd))
843d9d6e643SJouni Malinen 				break;
8449c381f59SAmarnath Hullur Subramanyam 			memset(addr, 0, sizeof(addr));
8459c381f59SAmarnath Hullur Subramanyam 		}
8469c381f59SAmarnath Hullur Subramanyam 	}
8479c381f59SAmarnath Hullur Subramanyam 
8489c381f59SAmarnath Hullur Subramanyam 	return 0;
8499c381f59SAmarnath Hullur Subramanyam }
8509c381f59SAmarnath Hullur Subramanyam 
8519c381f59SAmarnath Hullur Subramanyam 
miracast_cmd_sta_get_parameter(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)8529c381f59SAmarnath Hullur Subramanyam int miracast_cmd_sta_get_parameter(struct sigma_dut *dut,
8539c381f59SAmarnath Hullur Subramanyam 				   struct sigma_conn *conn,
8549c381f59SAmarnath Hullur Subramanyam 				   struct sigma_cmd *cmd)
8559c381f59SAmarnath Hullur Subramanyam {
8569c381f59SAmarnath Hullur Subramanyam 	/* const char *intf = get_param(cmd, "Interface"); */
8579c381f59SAmarnath Hullur Subramanyam 	/* const char *program = get_param(cmd, "Program"); */
8589c381f59SAmarnath Hullur Subramanyam 	const char *parameter = get_param(cmd, "Parameter");
8599c381f59SAmarnath Hullur Subramanyam 	char resp_buf[1024]; /* may need to change depending on number of peer
8609c381f59SAmarnath Hullur Subramanyam 				devices found */
8619c381f59SAmarnath Hullur Subramanyam 
8629c381f59SAmarnath Hullur Subramanyam 	if (!parameter) {
8639c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
8649c381f59SAmarnath Hullur Subramanyam 		return 0;
8659c381f59SAmarnath Hullur Subramanyam 	}
8669c381f59SAmarnath Hullur Subramanyam 
8679c381f59SAmarnath Hullur Subramanyam 	if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
8689c381f59SAmarnath Hullur Subramanyam 		int len = strlen("DeviceList,");
8699c381f59SAmarnath Hullur Subramanyam 
8709c381f59SAmarnath Hullur Subramanyam 		snprintf(resp_buf, sizeof(resp_buf), "DeviceList,");
871016ae6c8SJouni Malinen 		get_p2p_peers(dut, resp_buf + len, 1024 - len);
8729c381f59SAmarnath Hullur Subramanyam 	} else {
8739c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
8749c381f59SAmarnath Hullur Subramanyam 		return 0;
8759c381f59SAmarnath Hullur Subramanyam 	}
8769c381f59SAmarnath Hullur Subramanyam 
8779c381f59SAmarnath Hullur Subramanyam 	send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
8789c381f59SAmarnath Hullur Subramanyam 	return 0;
8799c381f59SAmarnath Hullur Subramanyam }
8809c381f59SAmarnath Hullur Subramanyam 
8819c381f59SAmarnath Hullur Subramanyam 
miracast_mdns_start_wfd_connection(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)8829c381f59SAmarnath Hullur Subramanyam int miracast_mdns_start_wfd_connection(struct sigma_dut *dut,
8839c381f59SAmarnath Hullur Subramanyam 				       struct sigma_conn *conn,
8849c381f59SAmarnath Hullur Subramanyam 				       struct sigma_cmd *cmd)
8859c381f59SAmarnath Hullur Subramanyam {
8869c381f59SAmarnath Hullur Subramanyam 	const char *init_wfd = get_param(cmd, "init_wfd");
8879c381f59SAmarnath Hullur Subramanyam 	int int_init_wfd = -1;
888b7c08448SSunil Dutt 	int rtsp_session_id = -1;
889d6e8a820SAmarnath Hullur Subramanyam 	char cmd_response[128];
8909c381f59SAmarnath Hullur Subramanyam 	int (*extn_start_wfd_connection)(const char *,
8919c381f59SAmarnath Hullur Subramanyam 					 const char *, /* Peer IP */
8929c381f59SAmarnath Hullur Subramanyam 					 int, /* RTSP port number */
8939c381f59SAmarnath Hullur Subramanyam 					 int, /* WFD Device Type; 0-Source,
8949c381f59SAmarnath Hullur Subramanyam 						1-P-Sink, 2-Secondary Sink */
895b7c08448SSunil Dutt 					 int *); /* for returning session ID */
8969c381f59SAmarnath Hullur Subramanyam 	int count = 0;
8979c381f59SAmarnath Hullur Subramanyam 	char *sig_resp = NULL;
8989c381f59SAmarnath Hullur Subramanyam 
8999c381f59SAmarnath Hullur Subramanyam 	if (init_wfd)
9009c381f59SAmarnath Hullur Subramanyam 		int_init_wfd = atoi(init_wfd);
9019c381f59SAmarnath Hullur Subramanyam 
9029c381f59SAmarnath Hullur Subramanyam 	extn_start_wfd_connection = dlsym(dut->miracast_lib,
9039c381f59SAmarnath Hullur Subramanyam 					  "start_wfd_connection");
9049c381f59SAmarnath Hullur Subramanyam 	if (!extn_start_wfd_connection)
9059c381f59SAmarnath Hullur Subramanyam 		return -1;
9069c381f59SAmarnath Hullur Subramanyam 	if (int_init_wfd != 0) {
9079c381f59SAmarnath Hullur Subramanyam 		extn_start_wfd_connection(NULL, NULL, -100,
9089c381f59SAmarnath Hullur Subramanyam 					  1 - dut->wfd_device_type,
909b7c08448SSunil Dutt 					  &rtsp_session_id);
910b7c08448SSunil Dutt 		while (rtsp_session_id == -1 && count < 60) {
9119c381f59SAmarnath Hullur Subramanyam 			count++;
9129c381f59SAmarnath Hullur Subramanyam 			sleep(1);
9139c381f59SAmarnath Hullur Subramanyam 		}
914d6e8a820SAmarnath Hullur Subramanyam 		snprintf(cmd_response, sizeof(cmd_response),
915b7c08448SSunil Dutt 			 "result,NULL,GroupID,NULL,WFDSessionID,%.8d",
916b7c08448SSunil Dutt 			 rtsp_session_id);
917d6e8a820SAmarnath Hullur Subramanyam 		sig_resp = cmd_response;
9189c381f59SAmarnath Hullur Subramanyam 	} else {
919*30088a7cSVinita S. Maloo 		rtsp_session_id = 0;
9209c381f59SAmarnath Hullur Subramanyam 		extn_start_wfd_connection(NULL, NULL, -100,
921*30088a7cSVinita S. Maloo 					  1 - dut->wfd_device_type,
922*30088a7cSVinita S. Maloo 					  &rtsp_session_id);
9239c381f59SAmarnath Hullur Subramanyam 		sig_resp = "result,NULL,GroupID,NULL,WFDSessionID,NULL";
9249c381f59SAmarnath Hullur Subramanyam 	}
9259c381f59SAmarnath Hullur Subramanyam 
9269c381f59SAmarnath Hullur Subramanyam 	send_resp(dut, conn, SIGMA_COMPLETE, sig_resp);
9279c381f59SAmarnath Hullur Subramanyam 	return 0;
9289c381f59SAmarnath Hullur Subramanyam }
9299c381f59SAmarnath Hullur Subramanyam 
9309c381f59SAmarnath Hullur Subramanyam 
cmd_start_wfd_connection(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)931f722271eSJouni Malinen static enum sigma_cmd_result cmd_start_wfd_connection(struct sigma_dut *dut,
9329c381f59SAmarnath Hullur Subramanyam 						      struct sigma_conn *conn,
9339c381f59SAmarnath Hullur Subramanyam 						      struct sigma_cmd *cmd)
9349c381f59SAmarnath Hullur Subramanyam {
9359c381f59SAmarnath Hullur Subramanyam 	const char *intf = get_param(cmd, "Interface");
9369c381f59SAmarnath Hullur Subramanyam 	const char *peer_address = get_param(cmd, "PeerAddress");
9379c381f59SAmarnath Hullur Subramanyam 	const char *init_wfd = get_param(cmd, "init_wfd");
9389c381f59SAmarnath Hullur Subramanyam 	const char *intent_val = get_param(cmd, "intent_val");
9399c381f59SAmarnath Hullur Subramanyam 	const char *oper_chan = get_param(cmd, "oper_chn");
9409c381f59SAmarnath Hullur Subramanyam 	const char *coupled_session = get_param(cmd, "coupledSession");
9419c381f59SAmarnath Hullur Subramanyam 	const char *tdls = get_param(cmd, "TDLS");
9429c381f59SAmarnath Hullur Subramanyam 	const char *r2_connection = get_param(cmd, "R2ConnectionType");
9439c381f59SAmarnath Hullur Subramanyam 	char ssid[128];
9449c381f59SAmarnath Hullur Subramanyam 	char p2p_dev_address[18];
9459c381f59SAmarnath Hullur Subramanyam 	char output_intf[16];
9469c381f59SAmarnath Hullur Subramanyam 	char sig_resp_buf[1024];
9479c381f59SAmarnath Hullur Subramanyam 	char cmd_buf[256]; /* Command buffer */
9489c381f59SAmarnath Hullur Subramanyam 	char resp_buf[256]; /* Response buffer to UCC */
9499c381f59SAmarnath Hullur Subramanyam 	int go_intent = 0;
9509c381f59SAmarnath Hullur Subramanyam 	int freq;
9519c381f59SAmarnath Hullur Subramanyam 	int res = 0;
9529c381f59SAmarnath Hullur Subramanyam 	char buf_peer[4096];
9539c381f59SAmarnath Hullur Subramanyam 	char *availability = NULL;
9549c381f59SAmarnath Hullur Subramanyam 	char command[64];
9559c381f59SAmarnath Hullur Subramanyam 	int avail_bit;
9569c381f59SAmarnath Hullur Subramanyam 	char ctemp[2];
9579c381f59SAmarnath Hullur Subramanyam 	char rtspport[5] = { '7', '2', '3', '6', '\0' };
9589c381f59SAmarnath Hullur Subramanyam 	int is_group_owner = 0;
9599c381f59SAmarnath Hullur Subramanyam 	char peer_ip_address[32];
9609c381f59SAmarnath Hullur Subramanyam 	int sm_control_port = 7236;
961b7c08448SSunil Dutt 	int rtsp_session_id = -1;
9629c381f59SAmarnath Hullur Subramanyam 	int (*extn_start_wfd_connection)(const char *,
9639c381f59SAmarnath Hullur Subramanyam 					 const char *, /* Peer IP */
9649c381f59SAmarnath Hullur Subramanyam 					 int, /* RTSP port number */
9659c381f59SAmarnath Hullur Subramanyam 					 int, /* WFD Device Type; 0-Source,
9669c381f59SAmarnath Hullur Subramanyam 						 1-P-Sink, 2-Secondary Sink */
967b7c08448SSunil Dutt 					 int *); /* for returning session ID */
9689c381f59SAmarnath Hullur Subramanyam 	int count = 0;
9699c381f59SAmarnath Hullur Subramanyam 
9709c381f59SAmarnath Hullur Subramanyam 	if (r2_connection) {
9719c381f59SAmarnath Hullur Subramanyam 		if (strcasecmp(r2_connection, "Infrastructure") == 0)
9729c381f59SAmarnath Hullur Subramanyam 			return miracast_mdns_start_wfd_connection(dut, conn,
9739c381f59SAmarnath Hullur Subramanyam 								  cmd);
9749c381f59SAmarnath Hullur Subramanyam 	}
9759c381f59SAmarnath Hullur Subramanyam 
9769c381f59SAmarnath Hullur Subramanyam 	if (coupled_session && atoi(coupled_session) == 1) {
9779c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR,
9789c381f59SAmarnath Hullur Subramanyam 			  "errorCode,Coupled Session is unsupported");
9799c381f59SAmarnath Hullur Subramanyam 		return 0;
9809c381f59SAmarnath Hullur Subramanyam 	}
9819c381f59SAmarnath Hullur Subramanyam 
9829c381f59SAmarnath Hullur Subramanyam 	if (tdls && atoi(tdls) == 1) {
9839c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR,
9849c381f59SAmarnath Hullur Subramanyam 			  "errorCode,TDLS is unsupported");
9859c381f59SAmarnath Hullur Subramanyam 		return 0;
9869c381f59SAmarnath Hullur Subramanyam 	}
9879c381f59SAmarnath Hullur Subramanyam 
9889c381f59SAmarnath Hullur Subramanyam 	if (intent_val) {
9899c381f59SAmarnath Hullur Subramanyam 		go_intent = atoi(intent_val);
9909c381f59SAmarnath Hullur Subramanyam 		if (go_intent > 15)
9919c381f59SAmarnath Hullur Subramanyam 			go_intent = 1;
9929c381f59SAmarnath Hullur Subramanyam 	}
9939c381f59SAmarnath Hullur Subramanyam 
9949c381f59SAmarnath Hullur Subramanyam 	if (p2p_discover_peer(dut, intf, peer_address, 1) < 0) {
9959c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR,
9969c381f59SAmarnath Hullur Subramanyam 			  "errorCode,Could not find peer");
9979c381f59SAmarnath Hullur Subramanyam 		return 0;
9989c381f59SAmarnath Hullur Subramanyam 	}
9999c381f59SAmarnath Hullur Subramanyam 
10009c381f59SAmarnath Hullur Subramanyam 	snprintf(cmd_buf, sizeof(cmd_buf), "P2P_CONNECT %s", peer_address);
10019c381f59SAmarnath Hullur Subramanyam 
10029c381f59SAmarnath Hullur Subramanyam 	switch (dut->wps_method) {
10039c381f59SAmarnath Hullur Subramanyam 	case WFA_CS_WPS_PIN_DISPLAY:
10049c381f59SAmarnath Hullur Subramanyam 		snprintf(cmd_buf + strlen(cmd_buf),
100539dc4500SWu Gao 			 sizeof(cmd_buf) - strlen(cmd_buf), " %s display",
100639dc4500SWu Gao 			 dut->wps_pin);
10079c381f59SAmarnath Hullur Subramanyam 		break;
10089c381f59SAmarnath Hullur Subramanyam 	case WFA_CS_WPS_PIN_LABEL:
10099c381f59SAmarnath Hullur Subramanyam 		snprintf(cmd_buf + strlen(cmd_buf),
10109c381f59SAmarnath Hullur Subramanyam 			 sizeof(cmd_buf) - strlen(cmd_buf), " pin label");
10119c381f59SAmarnath Hullur Subramanyam 		break;
10129c381f59SAmarnath Hullur Subramanyam 	case WFA_CS_WPS_PIN_KEYPAD:
10139c381f59SAmarnath Hullur Subramanyam 		snprintf(cmd_buf + strlen(cmd_buf),
10149c381f59SAmarnath Hullur Subramanyam 			 sizeof(cmd_buf) - strlen(cmd_buf), " %s keypad",
10159c381f59SAmarnath Hullur Subramanyam 			 dut->wps_pin);
10169c381f59SAmarnath Hullur Subramanyam 		break;
10179c381f59SAmarnath Hullur Subramanyam 	case WFA_CS_WPS_PBC:
10189c381f59SAmarnath Hullur Subramanyam 	default: /* Configuring default to PBC */
10199c381f59SAmarnath Hullur Subramanyam 		snprintf(cmd_buf + strlen(cmd_buf),
10209c381f59SAmarnath Hullur Subramanyam 			 sizeof(cmd_buf) - strlen(cmd_buf), " pbc");
10219c381f59SAmarnath Hullur Subramanyam 		break;
10229c381f59SAmarnath Hullur Subramanyam 	}
10239c381f59SAmarnath Hullur Subramanyam 
1024ff376dfcSAmarnath Hullur Subramanyam 	if (dut->persistent) {
1025ff376dfcSAmarnath Hullur Subramanyam 		snprintf(cmd_buf + strlen(cmd_buf),
1026ff376dfcSAmarnath Hullur Subramanyam 			 sizeof(cmd_buf) - strlen(cmd_buf), " persistent");
1027ff376dfcSAmarnath Hullur Subramanyam 	}
10289c381f59SAmarnath Hullur Subramanyam 	snprintf(cmd_buf + strlen(cmd_buf), sizeof(cmd_buf) - strlen(cmd_buf),
10299c381f59SAmarnath Hullur Subramanyam 		 " go_intent=%d", go_intent);
10309c381f59SAmarnath Hullur Subramanyam 
10319c381f59SAmarnath Hullur Subramanyam 	if (init_wfd && atoi(init_wfd) == 0) {
10329c381f59SAmarnath Hullur Subramanyam 		snprintf(cmd_buf + strlen(cmd_buf),
10339c381f59SAmarnath Hullur Subramanyam 			 sizeof(cmd_buf) - strlen(cmd_buf), " auth");
10349c381f59SAmarnath Hullur Subramanyam 	}
10359c381f59SAmarnath Hullur Subramanyam 
10369c381f59SAmarnath Hullur Subramanyam 	if (oper_chan) {
10379c381f59SAmarnath Hullur Subramanyam 		int chan;
10389c381f59SAmarnath Hullur Subramanyam 
10399c381f59SAmarnath Hullur Subramanyam 		chan = atoi(oper_chan);
10409c381f59SAmarnath Hullur Subramanyam 		if (chan >= 1 && chan <= 13)
10419c381f59SAmarnath Hullur Subramanyam 			freq = 2407 + chan * 5;
10429c381f59SAmarnath Hullur Subramanyam 		else if (chan == 14)
10439c381f59SAmarnath Hullur Subramanyam 			freq = 2484;
10449c381f59SAmarnath Hullur Subramanyam 		else
10459c381f59SAmarnath Hullur Subramanyam 			freq = 5000 + chan * 5;
10469c381f59SAmarnath Hullur Subramanyam 
10479c381f59SAmarnath Hullur Subramanyam 		snprintf(cmd_buf + strlen(cmd_buf),
10489c381f59SAmarnath Hullur Subramanyam 			 sizeof(cmd_buf) - strlen(cmd_buf), " freq=%d", freq);
10499c381f59SAmarnath Hullur Subramanyam 	}
10509c381f59SAmarnath Hullur Subramanyam 
10519c381f59SAmarnath Hullur Subramanyam 	/* WFD SESSION AVAILABILITY CHECK */
10529c381f59SAmarnath Hullur Subramanyam 
10539c381f59SAmarnath Hullur Subramanyam 	memset(buf_peer, 0, sizeof(buf_peer));
10549c381f59SAmarnath Hullur Subramanyam 	snprintf(command, sizeof(command), "P2P_PEER %s", peer_address);
10559c381f59SAmarnath Hullur Subramanyam 	strlcpy(dut->peer_mac_address, peer_address,
10569c381f59SAmarnath Hullur Subramanyam 		sizeof(dut->peer_mac_address));
105700852b5bSJouni Malinen 	if (wpa_command_resp(intf, command, buf_peer, sizeof(buf_peer)) >= 0 &&
105800852b5bSJouni Malinen 	    strlen(buf_peer) != 0)
10599c381f59SAmarnath Hullur Subramanyam 		availability = strstr(buf_peer, "wfd_subelems=");
10609c381f59SAmarnath Hullur Subramanyam 
10619c381f59SAmarnath Hullur Subramanyam 	if (!availability || strlen(availability) < 21) {
10629c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO, "Did not get WFD SUBELEMS");
10639c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_COMPLETE,
10649c381f59SAmarnath Hullur Subramanyam 			  "result,NULL,GroupID,NULL,WFDSessionID,NULL");
10659c381f59SAmarnath Hullur Subramanyam 		return 0;
10669c381f59SAmarnath Hullur Subramanyam 	}
10679c381f59SAmarnath Hullur Subramanyam 
10689c381f59SAmarnath Hullur Subramanyam 	/* Extracting Availability Bit */
10699c381f59SAmarnath Hullur Subramanyam 	ctemp[0] = availability[21];
10709c381f59SAmarnath Hullur Subramanyam 	ctemp[1] = '\0';
10719c381f59SAmarnath Hullur Subramanyam 	avail_bit = (int) strtol(ctemp, NULL, 16);
10729c381f59SAmarnath Hullur Subramanyam 
10739c381f59SAmarnath Hullur Subramanyam 	if ((avail_bit & 0x3) == 0) {
10749c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_COMPLETE,
10759c381f59SAmarnath Hullur Subramanyam 			  "result,NULL,GroupID,NULL,WFDSessionID,NULL");
10769c381f59SAmarnath Hullur Subramanyam 		return 0;
10779c381f59SAmarnath Hullur Subramanyam 	}
10789c381f59SAmarnath Hullur Subramanyam 
10799c381f59SAmarnath Hullur Subramanyam 	/* Extract RTSP Port for Sink */
10809c381f59SAmarnath Hullur Subramanyam 
10819c381f59SAmarnath Hullur Subramanyam 	if (dut->wfd_device_type != 0) {
10829c381f59SAmarnath Hullur Subramanyam 		if (strlen(availability) >= 23) {
10839c381f59SAmarnath Hullur Subramanyam 			availability += 23;
10849c381f59SAmarnath Hullur Subramanyam 			if (availability[0])
10859c381f59SAmarnath Hullur Subramanyam 				snprintf(rtspport, 5, "%s", availability);
10869c381f59SAmarnath Hullur Subramanyam 		}
10879c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
10889c381f59SAmarnath Hullur Subramanyam 				"rtsp_port = %s, availability = %s ",
10899c381f59SAmarnath Hullur Subramanyam 				rtspport, availability);
10909c381f59SAmarnath Hullur Subramanyam 		session_management_control_port = (int) strtol(rtspport, NULL,
10919c381f59SAmarnath Hullur Subramanyam 							       16);
10929c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
10939c381f59SAmarnath Hullur Subramanyam 				"SessionManagementControlPort = %d",
10949c381f59SAmarnath Hullur Subramanyam 				session_management_control_port);
10959c381f59SAmarnath Hullur Subramanyam 	}
10969c381f59SAmarnath Hullur Subramanyam 
10979c381f59SAmarnath Hullur Subramanyam 	memset(resp_buf, 0, sizeof(resp_buf));
10989c381f59SAmarnath Hullur Subramanyam 	res = wpa_command_resp(intf, cmd_buf, resp_buf, sizeof(resp_buf));
10990262c72cSPeng Xu 	if (res < 0) {
11000262c72cSPeng Xu 		sigma_dut_print(dut, DUT_MSG_ERROR,
11010262c72cSPeng Xu 				"wpa_command_resp failed");
11020262c72cSPeng Xu 		return 1;
11030262c72cSPeng Xu 	}
11049c381f59SAmarnath Hullur Subramanyam 	if (strncmp(resp_buf, "FAIL", 4) == 0) {
11059c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
11069c381f59SAmarnath Hullur Subramanyam 				"wpa_command: Command failed (FAIL received)");
11079c381f59SAmarnath Hullur Subramanyam 		return 1;
11089c381f59SAmarnath Hullur Subramanyam 	}
11099c381f59SAmarnath Hullur Subramanyam 
11109c381f59SAmarnath Hullur Subramanyam 	if (init_wfd && atoi(init_wfd) == 0) {
11119c381f59SAmarnath Hullur Subramanyam 		/* Start thread to wait for P2P connection */
11129c381f59SAmarnath Hullur Subramanyam 		miracast_rtsp_thread_create(dut, conn, cmd);
11139c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_COMPLETE,
11149c381f59SAmarnath Hullur Subramanyam 			  "result,NULL,GroupID,NULL,WFDSessionID,NULL");
11159c381f59SAmarnath Hullur Subramanyam 		return 0;
11169c381f59SAmarnath Hullur Subramanyam 	}
11179c381f59SAmarnath Hullur Subramanyam 
11189c381f59SAmarnath Hullur Subramanyam 	res = get_p2p_connection_event(dut, intf, output_intf,
11199c381f59SAmarnath Hullur Subramanyam 				       sizeof(output_intf), &is_group_owner);
11209c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "p2p connection done %d",
11219c381f59SAmarnath Hullur Subramanyam 			is_group_owner);
11229c381f59SAmarnath Hullur Subramanyam 	if (res < 0) {
11239c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR,
11249c381f59SAmarnath Hullur Subramanyam 				"Group Formation did not complete");
11259c381f59SAmarnath Hullur Subramanyam 		return 1;
11269c381f59SAmarnath Hullur Subramanyam 	}
11279c381f59SAmarnath Hullur Subramanyam 
11289c381f59SAmarnath Hullur Subramanyam 	snprintf(sig_resp_buf, sizeof(sig_resp_buf), "result");
11299c381f59SAmarnath Hullur Subramanyam 
11309c381f59SAmarnath Hullur Subramanyam 	if (is_group_owner) {
11319c381f59SAmarnath Hullur Subramanyam 		stop_dhcp(dut, output_intf,1);
11329c381f59SAmarnath Hullur Subramanyam 		snprintf(sig_resp_buf + strlen(sig_resp_buf),
11339c381f59SAmarnath Hullur Subramanyam 			 sizeof(sig_resp_buf) - strlen(sig_resp_buf), ",GO");
11349c381f59SAmarnath Hullur Subramanyam 		start_dhcp(dut, output_intf,1);
11359c381f59SAmarnath Hullur Subramanyam 		sleep(5);
11369c381f59SAmarnath Hullur Subramanyam 	} else {
11379c381f59SAmarnath Hullur Subramanyam 		snprintf(sig_resp_buf + strlen(sig_resp_buf),
11389c381f59SAmarnath Hullur Subramanyam 			 sizeof(sig_resp_buf) - strlen(sig_resp_buf),
11399c381f59SAmarnath Hullur Subramanyam 			 ",CLIENT");
11409c381f59SAmarnath Hullur Subramanyam 		miracast_start_dhcp_client(dut, output_intf);
11419c381f59SAmarnath Hullur Subramanyam 		sleep(5);
11429c381f59SAmarnath Hullur Subramanyam 	}
11439c381f59SAmarnath Hullur Subramanyam 
11449c381f59SAmarnath Hullur Subramanyam 	snprintf(sig_resp_buf + strlen(sig_resp_buf),
11459c381f59SAmarnath Hullur Subramanyam 		 sizeof(sig_resp_buf) - strlen(sig_resp_buf), ",GroupID,");
11469c381f59SAmarnath Hullur Subramanyam 
11479c381f59SAmarnath Hullur Subramanyam 	res = get_wpa_status(output_intf, "p2p_device_address",
11489c381f59SAmarnath Hullur Subramanyam 			     p2p_dev_address, sizeof(p2p_dev_address));
11499c381f59SAmarnath Hullur Subramanyam 	if (res < 0)
11509c381f59SAmarnath Hullur Subramanyam 		return -1;
11519c381f59SAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_INFO, "p2p_dev_address %s",
11529c381f59SAmarnath Hullur Subramanyam 			p2p_dev_address);
11539c381f59SAmarnath Hullur Subramanyam 	strlcpy(sig_resp_buf + strlen(sig_resp_buf), p2p_dev_address,
11549c381f59SAmarnath Hullur Subramanyam 		sizeof(sig_resp_buf) - strlen(sig_resp_buf));
11559c381f59SAmarnath Hullur Subramanyam 
11569c381f59SAmarnath Hullur Subramanyam 	res = get_wpa_status(output_intf, "ssid", ssid, sizeof(ssid));
11579c381f59SAmarnath Hullur Subramanyam 	if (res < 0) {
11589c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_DEBUG,
11599c381f59SAmarnath Hullur Subramanyam 				"get_wpa_status failed to get ssid");
11609c381f59SAmarnath Hullur Subramanyam 		return -1;
11619c381f59SAmarnath Hullur Subramanyam 	}
11629c381f59SAmarnath Hullur Subramanyam 
11639c381f59SAmarnath Hullur Subramanyam 	snprintf(sig_resp_buf + strlen(sig_resp_buf),
11649c381f59SAmarnath Hullur Subramanyam 		 sizeof(sig_resp_buf) - strlen(sig_resp_buf),
11659c381f59SAmarnath Hullur Subramanyam 		 " %s,WFDSessionId,", ssid);
11669c381f59SAmarnath Hullur Subramanyam 
11679c381f59SAmarnath Hullur Subramanyam 	if (!is_group_owner) {
11689c381f59SAmarnath Hullur Subramanyam 		if (get_peer_ip_p2p_client(dut, peer_ip_address, output_intf,
11699c381f59SAmarnath Hullur Subramanyam 					   60) < 0) {
11709c381f59SAmarnath Hullur Subramanyam 			send_resp(dut, conn, SIGMA_ERROR,
11719c381f59SAmarnath Hullur Subramanyam 				  "Could not get remote IP");
11729c381f59SAmarnath Hullur Subramanyam 			return 0;
11739c381f59SAmarnath Hullur Subramanyam 		}
11749c381f59SAmarnath Hullur Subramanyam 	} else {
1175bf9bcdf6SSunil Dutt 		if (get_peer_ip_p2p_go(dut, peer_ip_address, 30) < 0) {
11769c381f59SAmarnath Hullur Subramanyam 			send_resp(dut, conn, SIGMA_ERROR,
11779c381f59SAmarnath Hullur Subramanyam 				  "Could not get remote IP");
11789c381f59SAmarnath Hullur Subramanyam 			return 0;
11799c381f59SAmarnath Hullur Subramanyam 		}
11809c381f59SAmarnath Hullur Subramanyam 	}
11819c381f59SAmarnath Hullur Subramanyam 
11829c381f59SAmarnath Hullur Subramanyam 	if (dut->wfd_device_type != 0)
11839c381f59SAmarnath Hullur Subramanyam 		sm_control_port = (int) strtol(rtspport, NULL, 16);
11849c381f59SAmarnath Hullur Subramanyam 	else
11859c381f59SAmarnath Hullur Subramanyam 		sm_control_port = 7236;
11869c381f59SAmarnath Hullur Subramanyam 
11879c381f59SAmarnath Hullur Subramanyam 	extn_start_wfd_connection = dlsym(dut->miracast_lib,
11889c381f59SAmarnath Hullur Subramanyam 					  "start_wfd_connection");
11899c381f59SAmarnath Hullur Subramanyam 	if (!extn_start_wfd_connection)
11909c381f59SAmarnath Hullur Subramanyam 		return -1;
11919c381f59SAmarnath Hullur Subramanyam 	extn_start_wfd_connection(NULL, peer_ip_address, sm_control_port,
1192b7c08448SSunil Dutt 				  1 - dut->wfd_device_type, &rtsp_session_id);
11939c381f59SAmarnath Hullur Subramanyam 
1194b7c08448SSunil Dutt 	while (rtsp_session_id == -1 && count < 60) {
11959c381f59SAmarnath Hullur Subramanyam 		count++;
11969c381f59SAmarnath Hullur Subramanyam 		sleep(1);
11979c381f59SAmarnath Hullur Subramanyam 	}
11989c381f59SAmarnath Hullur Subramanyam 
1199b7c08448SSunil Dutt 	snprintf(sig_resp_buf + strlen(sig_resp_buf),
1200b7c08448SSunil Dutt 		 sizeof(sig_resp_buf) - strlen(sig_resp_buf), "%.8d",
1201b7c08448SSunil Dutt 		 rtsp_session_id);
12029c381f59SAmarnath Hullur Subramanyam 	send_resp(dut, conn, SIGMA_COMPLETE, sig_resp_buf);
12039c381f59SAmarnath Hullur Subramanyam 	return 0;
12049c381f59SAmarnath Hullur Subramanyam }
12059c381f59SAmarnath Hullur Subramanyam 
12069c381f59SAmarnath Hullur Subramanyam 
cmd_connect_go_start_wfd(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)1207f722271eSJouni Malinen static enum sigma_cmd_result cmd_connect_go_start_wfd(struct sigma_dut *dut,
12089c381f59SAmarnath Hullur Subramanyam 						      struct sigma_conn *conn,
12099c381f59SAmarnath Hullur Subramanyam 						      struct sigma_cmd *cmd)
12109c381f59SAmarnath Hullur Subramanyam {
12119c381f59SAmarnath Hullur Subramanyam 	const char *intf = get_param(cmd, "Interface");
12129c381f59SAmarnath Hullur Subramanyam 	const char *p2p_dev_id = get_param(cmd, "P2PdevID");
12139c381f59SAmarnath Hullur Subramanyam 	/* const char *p2p_group_id = get_param(cmd, "GroupID"); */
12149c381f59SAmarnath Hullur Subramanyam 	char sig_resp_buf[1024];
12159c381f59SAmarnath Hullur Subramanyam 	char method[12];
12169c381f59SAmarnath Hullur Subramanyam 	char cmd_buf[256];
12179c381f59SAmarnath Hullur Subramanyam 	char buf[256];
12189c381f59SAmarnath Hullur Subramanyam 	char resp_buf[256];
12199c381f59SAmarnath Hullur Subramanyam 	int go = 0;
12209c381f59SAmarnath Hullur Subramanyam 	int res = 0;
12219c381f59SAmarnath Hullur Subramanyam 	char output_ifname[32];
12229c381f59SAmarnath Hullur Subramanyam 	char peer_ip_address[32];
1223b7c08448SSunil Dutt 	int rtsp_session_id = -1;
12249c381f59SAmarnath Hullur Subramanyam 	int (*extn_connect_go_start_wfd)(const char *,
12259c381f59SAmarnath Hullur Subramanyam 					 const char * /* Peer IP */,
12269c381f59SAmarnath Hullur Subramanyam 					 int /* RTSP port number */,
12279c381f59SAmarnath Hullur Subramanyam 					 int /* WFD Device Type; 0-Source,
12289c381f59SAmarnath Hullur Subramanyam 						1-P-Sink, 2-Secondary Sink */,
1229b7c08448SSunil Dutt 					 int *); /* for returning session ID */
12309c381f59SAmarnath Hullur Subramanyam 
12319c381f59SAmarnath Hullur Subramanyam 	snprintf(cmd_buf, sizeof(cmd_buf), "P2P_CONNECT %s", p2p_dev_id);
12329c381f59SAmarnath Hullur Subramanyam 
12339c381f59SAmarnath Hullur Subramanyam 	switch (dut->wps_method) {
12349c381f59SAmarnath Hullur Subramanyam 	case WFA_CS_WPS_PBC:
12359c381f59SAmarnath Hullur Subramanyam 		snprintf(cmd_buf + strlen(cmd_buf),
12369c381f59SAmarnath Hullur Subramanyam 			 sizeof(cmd_buf) - strlen(cmd_buf), " pbc");
12379c381f59SAmarnath Hullur Subramanyam 		strlcpy(method, "pbc", sizeof(method));
12389c381f59SAmarnath Hullur Subramanyam 		break;
12399c381f59SAmarnath Hullur Subramanyam 	case WFA_CS_WPS_PIN_DISPLAY:
12409c381f59SAmarnath Hullur Subramanyam 		snprintf(cmd_buf + strlen(cmd_buf),
124139dc4500SWu Gao 			 sizeof(cmd_buf) - strlen(cmd_buf), " %s display",
124239dc4500SWu Gao 			 dut->wps_pin);
12439c381f59SAmarnath Hullur Subramanyam 		strlcpy(method, "display", sizeof(method));
12449c381f59SAmarnath Hullur Subramanyam 		break;
12459c381f59SAmarnath Hullur Subramanyam 	case WFA_CS_WPS_PIN_LABEL:
12469c381f59SAmarnath Hullur Subramanyam 		snprintf(cmd_buf + strlen(cmd_buf),
12479c381f59SAmarnath Hullur Subramanyam 			 sizeof(cmd_buf) - strlen(cmd_buf), " pin label");
12489c381f59SAmarnath Hullur Subramanyam 		strlcpy(method, "label", sizeof(method));
12499c381f59SAmarnath Hullur Subramanyam 		break;
12509c381f59SAmarnath Hullur Subramanyam 	case WFA_CS_WPS_PIN_KEYPAD:
12519c381f59SAmarnath Hullur Subramanyam 		snprintf(cmd_buf + strlen(cmd_buf),
12529c381f59SAmarnath Hullur Subramanyam 			 sizeof(cmd_buf) - strlen(cmd_buf), " %s keypad",
12539c381f59SAmarnath Hullur Subramanyam 			 dut->wps_pin);
12549c381f59SAmarnath Hullur Subramanyam 		strlcpy(method, "keypad", sizeof(method));
12559c381f59SAmarnath Hullur Subramanyam 		break;
12569c381f59SAmarnath Hullur Subramanyam 	default: /* Configuring to PBC */
12579c381f59SAmarnath Hullur Subramanyam 		snprintf(cmd_buf + strlen(cmd_buf),
12589c381f59SAmarnath Hullur Subramanyam 			 sizeof(cmd_buf) - strlen(cmd_buf), " pbc");
12599c381f59SAmarnath Hullur Subramanyam 		strlcpy(method, "pbc", sizeof(method));
12609c381f59SAmarnath Hullur Subramanyam 		break;
12619c381f59SAmarnath Hullur Subramanyam 	}
12629c381f59SAmarnath Hullur Subramanyam 	snprintf(cmd_buf + strlen(cmd_buf),
12639c381f59SAmarnath Hullur Subramanyam 		 sizeof(cmd_buf) - strlen(cmd_buf), " join");
12649c381f59SAmarnath Hullur Subramanyam 
12659c381f59SAmarnath Hullur Subramanyam 	/* run provisional discovery */
12669c381f59SAmarnath Hullur Subramanyam 	if (p2p_discover_peer(dut, intf, p2p_dev_id, 0) < 0) {
12679c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR,
12689c381f59SAmarnath Hullur Subramanyam 			  "ErrorCode,Could not discover the requested peer");
12699c381f59SAmarnath Hullur Subramanyam 		return 0;
12709c381f59SAmarnath Hullur Subramanyam 	}
12719c381f59SAmarnath Hullur Subramanyam 
12729c381f59SAmarnath Hullur Subramanyam 	snprintf(buf, sizeof(buf), "P2P_PROV_DISC %s %s", p2p_dev_id, method);
12739c381f59SAmarnath Hullur Subramanyam 	if (wpa_command(intf, buf) < 0) {
12749c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
12759c381f59SAmarnath Hullur Subramanyam 				"Failed to send provision discovery request");
12769c381f59SAmarnath Hullur Subramanyam 		return -2;
12779c381f59SAmarnath Hullur Subramanyam 	}
12789c381f59SAmarnath Hullur Subramanyam 
12799c381f59SAmarnath Hullur Subramanyam 	res = wpa_command_resp(intf, cmd_buf, resp_buf, sizeof(resp_buf));
12800262c72cSPeng Xu 	if (res < 0) {
12810262c72cSPeng Xu 		sigma_dut_print(dut, DUT_MSG_ERROR,
12820262c72cSPeng Xu 				"wpa_command_resp failed");
12830262c72cSPeng Xu 		return 1;
12840262c72cSPeng Xu 	}
12859c381f59SAmarnath Hullur Subramanyam 	if (strncmp(resp_buf, "FAIL", 4) == 0) {
12869c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR,
12879c381f59SAmarnath Hullur Subramanyam 			  "errorCode,failed P2P connection");
12889c381f59SAmarnath Hullur Subramanyam 		return 0;
12899c381f59SAmarnath Hullur Subramanyam 	}
12909c381f59SAmarnath Hullur Subramanyam 
12919c381f59SAmarnath Hullur Subramanyam 	res = get_p2p_connection_event(dut, intf, output_ifname,
12929c381f59SAmarnath Hullur Subramanyam 				       sizeof(output_ifname), &go);
12939c381f59SAmarnath Hullur Subramanyam 	if (res < 0) {
12949c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR,
12959c381f59SAmarnath Hullur Subramanyam 			  "errorCode,failed P2P connection");
12969c381f59SAmarnath Hullur Subramanyam 		return 0;
12979c381f59SAmarnath Hullur Subramanyam 	}
12989c381f59SAmarnath Hullur Subramanyam 
12999c381f59SAmarnath Hullur Subramanyam 	miracast_start_dhcp_client(dut, output_ifname);
13009c381f59SAmarnath Hullur Subramanyam 
13019c381f59SAmarnath Hullur Subramanyam 	if (get_peer_ip_p2p_client(dut, peer_ip_address, output_ifname,
13029c381f59SAmarnath Hullur Subramanyam 				   30) < 0) {
13039c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR, "Could not get remote IP");
13049c381f59SAmarnath Hullur Subramanyam 		return 0;
13059c381f59SAmarnath Hullur Subramanyam 	}
13069c381f59SAmarnath Hullur Subramanyam 
13079c381f59SAmarnath Hullur Subramanyam 	if (dut->wfd_device_type != 0) {
13089c381f59SAmarnath Hullur Subramanyam 		char rtsp_buff[1000], cmd_buff[32];
13099c381f59SAmarnath Hullur Subramanyam 		char *sub_elem = NULL;
13109c381f59SAmarnath Hullur Subramanyam 		char rtspport[5] = { '7', '2', '3', '6', '\0' };
13119c381f59SAmarnath Hullur Subramanyam 
13129c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_DEBUG,
13139c381f59SAmarnath Hullur Subramanyam 				"Log --- p2p address = %s", p2p_dev_id);
13149c381f59SAmarnath Hullur Subramanyam 		snprintf(cmd_buff, sizeof(cmd_buff), "P2P_PEER %s", p2p_dev_id);
131500852b5bSJouni Malinen 		if (wpa_command_resp(output_ifname, cmd_buff, rtsp_buff,
131600852b5bSJouni Malinen 				     sizeof(rtsp_buff)) >= 0 &&
131700852b5bSJouni Malinen 		    strlen(rtsp_buff) != 0)
13189c381f59SAmarnath Hullur Subramanyam 			sub_elem = strstr(rtsp_buff, "wfd_subelems=");
13199c381f59SAmarnath Hullur Subramanyam 
13209c381f59SAmarnath Hullur Subramanyam 		/* Extract RTSP Port for Sink */
13219c381f59SAmarnath Hullur Subramanyam 		if (sub_elem && strlen(sub_elem) >= 23) {
13229c381f59SAmarnath Hullur Subramanyam 			sub_elem += 23;
13239c381f59SAmarnath Hullur Subramanyam 			snprintf(rtspport, 5, "%s", sub_elem);
13249c381f59SAmarnath Hullur Subramanyam 			sigma_dut_print(dut, DUT_MSG_DEBUG,
13259c381f59SAmarnath Hullur Subramanyam 				"rtsp_port = %s, subElem = %s",
13269c381f59SAmarnath Hullur Subramanyam 				rtspport, sub_elem);
13279c381f59SAmarnath Hullur Subramanyam 		}
13289c381f59SAmarnath Hullur Subramanyam 		session_management_control_port = (int) strtol(rtspport, NULL,
13299c381f59SAmarnath Hullur Subramanyam 							       16);
13309c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_DEBUG,
13319c381f59SAmarnath Hullur Subramanyam 				"SessionManagementControlPort = %d",
13329c381f59SAmarnath Hullur Subramanyam 				session_management_control_port);
13339c381f59SAmarnath Hullur Subramanyam 
13349c381f59SAmarnath Hullur Subramanyam 	} else {
13359c381f59SAmarnath Hullur Subramanyam 		session_management_control_port = 7236;
13369c381f59SAmarnath Hullur Subramanyam 	}
13379c381f59SAmarnath Hullur Subramanyam 
13389c381f59SAmarnath Hullur Subramanyam 	extn_connect_go_start_wfd = dlsym(dut->miracast_lib,
13399c381f59SAmarnath Hullur Subramanyam 					  "connect_go_start_wfd");
13409c381f59SAmarnath Hullur Subramanyam 	if (!extn_connect_go_start_wfd)
13419c381f59SAmarnath Hullur Subramanyam 		return -1;
13429c381f59SAmarnath Hullur Subramanyam 	extn_connect_go_start_wfd(NULL, peer_ip_address,
13439c381f59SAmarnath Hullur Subramanyam 				  session_management_control_port,
1344b7c08448SSunil Dutt 				  1 - dut->wfd_device_type, &rtsp_session_id);
13459ed647c0SAmarnath Hullur Subramanyam 	/* Null terminating regardless of what was returned */
1346b7c08448SSunil Dutt 	snprintf(sig_resp_buf, sizeof(sig_resp_buf), "WFDSessionId,%.8d",
13479ed647c0SAmarnath Hullur Subramanyam 		 rtsp_session_id);
13489c381f59SAmarnath Hullur Subramanyam 
13499c381f59SAmarnath Hullur Subramanyam 	send_resp(dut, conn, SIGMA_COMPLETE, sig_resp_buf);
13509c381f59SAmarnath Hullur Subramanyam 	return 0;
13519c381f59SAmarnath Hullur Subramanyam }
13529c381f59SAmarnath Hullur Subramanyam 
13539c381f59SAmarnath Hullur Subramanyam 
cmd_sta_generate_event(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)1354f722271eSJouni Malinen static enum sigma_cmd_result cmd_sta_generate_event(struct sigma_dut *dut,
13559c381f59SAmarnath Hullur Subramanyam 						    struct sigma_conn *conn,
13569c381f59SAmarnath Hullur Subramanyam 						    struct sigma_cmd *cmd)
13579c381f59SAmarnath Hullur Subramanyam {
13589c381f59SAmarnath Hullur Subramanyam 
13599c381f59SAmarnath Hullur Subramanyam 	/* const char *intf = get_param(cmd, "Interface"); */
13609c381f59SAmarnath Hullur Subramanyam 	/* const char *program = get_param(cmd, "Program"); */
13619c381f59SAmarnath Hullur Subramanyam 	const char *type = get_param(cmd, "Type");
13629c381f59SAmarnath Hullur Subramanyam 	char string_cmd[MIRACAST_CMD_LEN];
13639c381f59SAmarnath Hullur Subramanyam 	int (*extn_sta_generate_event)(const char *);
13649c381f59SAmarnath Hullur Subramanyam 
13659c381f59SAmarnath Hullur Subramanyam 	if (!type) {
13669c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_INVALID,
13679c381f59SAmarnath Hullur Subramanyam 			  "errorCode, Invalid Type for Generate Event");
13689c381f59SAmarnath Hullur Subramanyam 		return 0;
13699c381f59SAmarnath Hullur Subramanyam 	}
13709c381f59SAmarnath Hullur Subramanyam 	miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd));
13719c381f59SAmarnath Hullur Subramanyam 	extn_sta_generate_event = dlsym(dut->miracast_lib,
13729c381f59SAmarnath Hullur Subramanyam 					"sta_generate_event");
13739c381f59SAmarnath Hullur Subramanyam 	if (!extn_sta_generate_event)
13749c381f59SAmarnath Hullur Subramanyam 		return -1;
13759c381f59SAmarnath Hullur Subramanyam 	if (strcasecmp(type, "UIBC_Gen") == 0 ||
13769c381f59SAmarnath Hullur Subramanyam 	    strcasecmp(type, "UIBC_HID") == 0) {
13779c381f59SAmarnath Hullur Subramanyam 		extn_sta_generate_event(string_cmd);
13789c381f59SAmarnath Hullur Subramanyam 	} else if (strcasecmp(type, "FrameSkip") == 0) {
13797cd7f4f9SAmarnath Hullur Subramanyam 		return 1;
13809c381f59SAmarnath Hullur Subramanyam 	} else if (strcasecmp(type, "InputContent") == 0) {
13819c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_COMPLETE, NULL);
13829c381f59SAmarnath Hullur Subramanyam 		return 0;
13839c381f59SAmarnath Hullur Subramanyam 	} else if (strcasecmp(type, "I2cRead") == 0) {
13849c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR,
13859c381f59SAmarnath Hullur Subramanyam 			  "errorCode,Unsupported Type for Generate Event");
13869c381f59SAmarnath Hullur Subramanyam 		return 0;
13879c381f59SAmarnath Hullur Subramanyam 	} else if (strcasecmp(type, "I2cWrite") == 0) {
13889c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR,
13899c381f59SAmarnath Hullur Subramanyam 			  "errorCode, Unsupported Type for Generate Event");
13909c381f59SAmarnath Hullur Subramanyam 		return 0;
13919c381f59SAmarnath Hullur Subramanyam 	} else if (strcasecmp(type, "IdrReq") == 0) {
13929c381f59SAmarnath Hullur Subramanyam 		if (dut->wfd_device_type == 0) { /* Source */
13939c381f59SAmarnath Hullur Subramanyam 			send_resp(dut, conn, SIGMA_ERROR,
13949c381f59SAmarnath Hullur Subramanyam 				  "errorCode, Unsupported Type for Generate Event");
13959c381f59SAmarnath Hullur Subramanyam 		} else {
13969c381f59SAmarnath Hullur Subramanyam 			send_resp(dut, conn, SIGMA_COMPLETE, NULL);
13979c381f59SAmarnath Hullur Subramanyam 			extn_sta_generate_event(string_cmd);
13989c381f59SAmarnath Hullur Subramanyam 		}
13999c381f59SAmarnath Hullur Subramanyam 		return 0;
14009c381f59SAmarnath Hullur Subramanyam 	}
14019c381f59SAmarnath Hullur Subramanyam 	return 1;
14029c381f59SAmarnath Hullur Subramanyam }
14039c381f59SAmarnath Hullur Subramanyam 
14049c381f59SAmarnath Hullur Subramanyam 
cmd_reinvoke_wfd_session(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)1405f722271eSJouni Malinen static enum sigma_cmd_result cmd_reinvoke_wfd_session(struct sigma_dut *dut,
14069c381f59SAmarnath Hullur Subramanyam 						      struct sigma_conn *conn,
14079c381f59SAmarnath Hullur Subramanyam 						      struct sigma_cmd *cmd)
14089c381f59SAmarnath Hullur Subramanyam {
14099c381f59SAmarnath Hullur Subramanyam 	const char *intf = get_param(cmd, "Interface");
14109c381f59SAmarnath Hullur Subramanyam 	const char *grp_id = get_param(cmd, "GroupID");
14119c381f59SAmarnath Hullur Subramanyam 	const char *peer_address = get_param(cmd, "peeraddress");
14129c381f59SAmarnath Hullur Subramanyam 	const char *invitation_action = get_param(cmd, "InvitationAction");
14139c381f59SAmarnath Hullur Subramanyam 	char buf[256];
1414ff376dfcSAmarnath Hullur Subramanyam 	struct wpa_ctrl *ctrl;
1415ff376dfcSAmarnath Hullur Subramanyam 	int res, id;
1416ff376dfcSAmarnath Hullur Subramanyam 	char *ssid, *pos;
1417ff376dfcSAmarnath Hullur Subramanyam 	unsigned int wait_limit;
1418ff376dfcSAmarnath Hullur Subramanyam 	char peer_ip_address[32];
1419b7c08448SSunil Dutt 	int rtsp_session_id = -1;
1420ff376dfcSAmarnath Hullur Subramanyam 	int (*extn_start_wfd_connection)(const char *,
1421ff376dfcSAmarnath Hullur Subramanyam 					 const char *, /* Peer IP */
1422ff376dfcSAmarnath Hullur Subramanyam 					 int, /* RTSP port number */
1423ff376dfcSAmarnath Hullur Subramanyam 					 int, /* WFD Device Type; 0-Source,
1424ff376dfcSAmarnath Hullur Subramanyam 						 1-P-Sink, 2-Secondary Sink */
1425b7c08448SSunil Dutt 					 int *); /* for returning session ID */
14269c381f59SAmarnath Hullur Subramanyam 
14279c381f59SAmarnath Hullur Subramanyam 	/* All are compulsory parameters */
14289c381f59SAmarnath Hullur Subramanyam 	if (!intf || !grp_id || !invitation_action || !peer_address) {
14299c381f59SAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_INVALID,
14309c381f59SAmarnath Hullur Subramanyam 			  "errorCode,Invalid parameters for Reinvoke WFD Session");
14319c381f59SAmarnath Hullur Subramanyam 		return 0;
14329c381f59SAmarnath Hullur Subramanyam 	}
14339c381f59SAmarnath Hullur Subramanyam 
14349c381f59SAmarnath Hullur Subramanyam 	if (strcmp(invitation_action, "accept") == 0) {
14359c381f59SAmarnath Hullur Subramanyam 		/*
14369c381f59SAmarnath Hullur Subramanyam 		 * In a client-joining-a-running-group case, we need to
14379c381f59SAmarnath Hullur Subramanyam 		 * separately authorize the invitation.
14389c381f59SAmarnath Hullur Subramanyam 		 */
14399c381f59SAmarnath Hullur Subramanyam 		miracast_stop_dhcp_client(dut, NULL);
14409c381f59SAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_DEBUG, "Trying to discover GO %s",
14419c381f59SAmarnath Hullur Subramanyam 				peer_address);
14429c381f59SAmarnath Hullur Subramanyam 		if (p2p_discover_peer(dut, intf, peer_address, 1) < 0) {
14439c381f59SAmarnath Hullur Subramanyam 			send_resp(dut, conn, SIGMA_ERROR,
14449c381f59SAmarnath Hullur Subramanyam 				  "ErrorCode,Could not discover the requested peer");
14459c381f59SAmarnath Hullur Subramanyam 			return 0;
14469c381f59SAmarnath Hullur Subramanyam 		}
14479c381f59SAmarnath Hullur Subramanyam 
14489c381f59SAmarnath Hullur Subramanyam 		snprintf(buf, sizeof(buf), "P2P_CONNECT %s %s join auth",
14499c381f59SAmarnath Hullur Subramanyam 			 peer_address, dut->wps_method == WFA_CS_WPS_PBC ?
14509c381f59SAmarnath Hullur Subramanyam 			 "pbc" : dut->wps_pin);
14519c381f59SAmarnath Hullur Subramanyam 		if (wpa_command(intf, buf) < 0)
14529c381f59SAmarnath Hullur Subramanyam 			return -2;
14539c381f59SAmarnath Hullur Subramanyam 
14549c381f59SAmarnath Hullur Subramanyam 		miracast_rtsp_thread_create(dut, conn, cmd);
14559c381f59SAmarnath Hullur Subramanyam 		return 1;
14569c381f59SAmarnath Hullur Subramanyam 	}
14579c381f59SAmarnath Hullur Subramanyam 
1458ff376dfcSAmarnath Hullur Subramanyam 	ssid = strchr(grp_id, ' ');
1459ff376dfcSAmarnath Hullur Subramanyam 	if (!ssid) {
1460ff376dfcSAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO, "Invalid grpid");
1461ff376dfcSAmarnath Hullur Subramanyam 		return -1;
1462ff376dfcSAmarnath Hullur Subramanyam 	}
1463ff376dfcSAmarnath Hullur Subramanyam 	ssid++;
1464ff376dfcSAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG,
1465ff376dfcSAmarnath Hullur Subramanyam 			"Search for persistent group credentials based on SSID: '%s'",
1466ff376dfcSAmarnath Hullur Subramanyam 			ssid);
1467ff376dfcSAmarnath Hullur Subramanyam 	if (wpa_command_resp(intf, "LIST_NETWORKS", buf, sizeof(buf)) < 0)
1468ff376dfcSAmarnath Hullur Subramanyam 		return -2;
1469ff376dfcSAmarnath Hullur Subramanyam 	pos = strstr(buf, ssid);
1470ff376dfcSAmarnath Hullur Subramanyam 	if (!pos || pos == buf || pos[-1] != '\t' ||
1471ff376dfcSAmarnath Hullur Subramanyam 	    pos[strlen(ssid)] != '\t') {
1472ff376dfcSAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR,
1473ff376dfcSAmarnath Hullur Subramanyam 			  "ErrorCode,Persistent group credentials not found");
14749c381f59SAmarnath Hullur Subramanyam 		return 0;
14759c381f59SAmarnath Hullur Subramanyam 	}
1476ff376dfcSAmarnath Hullur Subramanyam 	while (pos > buf && pos[-1] != '\n')
1477ff376dfcSAmarnath Hullur Subramanyam 		pos--;
1478ff376dfcSAmarnath Hullur Subramanyam 	id = atoi(pos);
1479ff376dfcSAmarnath Hullur Subramanyam 	snprintf(buf, sizeof(buf), "P2P_INVITE persistent=%d peer=%s",
1480ff376dfcSAmarnath Hullur Subramanyam 		 id, peer_address);
1481ff376dfcSAmarnath Hullur Subramanyam 
1482ff376dfcSAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG,
1483ff376dfcSAmarnath Hullur Subramanyam 			"Trying to discover peer %s for invitation",
1484ff376dfcSAmarnath Hullur Subramanyam 			peer_address);
1485ff376dfcSAmarnath Hullur Subramanyam 	if (p2p_discover_peer(dut, intf, peer_address, 0) < 0) {
1486ff376dfcSAmarnath Hullur Subramanyam 		send_resp(dut, conn, SIGMA_ERROR,
1487ff376dfcSAmarnath Hullur Subramanyam 			  "ErrorCode,Could not discover the requested peer");
1488ff376dfcSAmarnath Hullur Subramanyam 		return 0;
1489ff376dfcSAmarnath Hullur Subramanyam 	}
1490ff376dfcSAmarnath Hullur Subramanyam 
1491ff376dfcSAmarnath Hullur Subramanyam 	ctrl = open_wpa_mon(intf);
1492ff376dfcSAmarnath Hullur Subramanyam 	if (!ctrl) {
1493ff376dfcSAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR,
1494ff376dfcSAmarnath Hullur Subramanyam 				"Failed to open wpa_supplicant monitor connection");
1495ff376dfcSAmarnath Hullur Subramanyam 		return -2;
1496ff376dfcSAmarnath Hullur Subramanyam 	}
1497ff376dfcSAmarnath Hullur Subramanyam 
1498ff376dfcSAmarnath Hullur Subramanyam 	if (wpa_command(intf, buf) < 0) {
1499ff376dfcSAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
1500ff376dfcSAmarnath Hullur Subramanyam 				"Failed to send invitation request");
1501ff376dfcSAmarnath Hullur Subramanyam 		wpa_ctrl_detach(ctrl);
1502ff376dfcSAmarnath Hullur Subramanyam 		wpa_ctrl_close(ctrl);
1503ff376dfcSAmarnath Hullur Subramanyam 		return -2;
1504ff376dfcSAmarnath Hullur Subramanyam 	}
1505ff376dfcSAmarnath Hullur Subramanyam 
1506ff376dfcSAmarnath Hullur Subramanyam 	res = get_wpa_cli_event(dut, ctrl, "P2P-INVITATION-RESULT",
1507ff376dfcSAmarnath Hullur Subramanyam 				buf, sizeof(buf));
1508ff376dfcSAmarnath Hullur Subramanyam 	wpa_ctrl_detach(ctrl);
1509ff376dfcSAmarnath Hullur Subramanyam 	wpa_ctrl_close(ctrl);
1510ff376dfcSAmarnath Hullur Subramanyam 	if (res < 0)
1511ff376dfcSAmarnath Hullur Subramanyam 		return -2;
1512ff376dfcSAmarnath Hullur Subramanyam 
1513ff376dfcSAmarnath Hullur Subramanyam 	miracast_load(dut);
1514ff376dfcSAmarnath Hullur Subramanyam 
1515ff376dfcSAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting to start DHCP");
1516ff376dfcSAmarnath Hullur Subramanyam 
1517ff376dfcSAmarnath Hullur Subramanyam 	/* Calling Miracast multimedia APIs */
1518ff376dfcSAmarnath Hullur Subramanyam 	if (dut->wfd_device_type != 0)
1519ff376dfcSAmarnath Hullur Subramanyam 		wait_limit = HUNDRED_SECOND_TIMEOUT;
1520ff376dfcSAmarnath Hullur Subramanyam 	else
1521ff376dfcSAmarnath Hullur Subramanyam 		wait_limit = 500;
1522ff376dfcSAmarnath Hullur Subramanyam 
1523ff376dfcSAmarnath Hullur Subramanyam 	stop_dhcp(dut, intf, 1);
1524ff376dfcSAmarnath Hullur Subramanyam 	/* For GO read the DHCP lease file */
1525ff376dfcSAmarnath Hullur Subramanyam 	sigma_dut_print(dut, DUT_MSG_INFO, "Waiting to start DHCP server");
1526ff376dfcSAmarnath Hullur Subramanyam 	start_dhcp(dut, intf, 1);
1527ff376dfcSAmarnath Hullur Subramanyam 	sleep(5);
1528bf9bcdf6SSunil Dutt 	if (get_peer_ip_p2p_go(dut, peer_ip_address, wait_limit) < 0) {
1529ff376dfcSAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_ERROR, "Could not get peer IP");
1530ff376dfcSAmarnath Hullur Subramanyam 		return -2;
1531ff376dfcSAmarnath Hullur Subramanyam 	}
1532ff376dfcSAmarnath Hullur Subramanyam 
1533ff376dfcSAmarnath Hullur Subramanyam 	extn_start_wfd_connection = dlsym(dut->miracast_lib,
1534ff376dfcSAmarnath Hullur Subramanyam 					  "start_wfd_connection");
1535ff376dfcSAmarnath Hullur Subramanyam 	if (extn_start_wfd_connection) {
1536ff376dfcSAmarnath Hullur Subramanyam 		extn_start_wfd_connection(NULL, peer_ip_address,
1537ff376dfcSAmarnath Hullur Subramanyam 					  session_management_control_port,
1538ff376dfcSAmarnath Hullur Subramanyam 					  1 - dut->wfd_device_type,
1539b7c08448SSunil Dutt 					  &rtsp_session_id);
1540ff376dfcSAmarnath Hullur Subramanyam 	} else {
1541ff376dfcSAmarnath Hullur Subramanyam 		sigma_dut_print(dut, DUT_MSG_INFO,
1542ff376dfcSAmarnath Hullur Subramanyam 				"dlsym seems to have error %p %p",
1543ff376dfcSAmarnath Hullur Subramanyam 				dut->miracast_lib,
1544ff376dfcSAmarnath Hullur Subramanyam 				extn_start_wfd_connection);
1545ff376dfcSAmarnath Hullur Subramanyam 	}
1546ff376dfcSAmarnath Hullur Subramanyam 
1547ff376dfcSAmarnath Hullur Subramanyam 	return 1;
1548ff376dfcSAmarnath Hullur Subramanyam }
15499c381f59SAmarnath Hullur Subramanyam 
15509c381f59SAmarnath Hullur Subramanyam 
req_intf_peer(struct sigma_cmd * cmd)15519c381f59SAmarnath Hullur Subramanyam static int req_intf_peer(struct sigma_cmd *cmd)
15529c381f59SAmarnath Hullur Subramanyam {
15539c381f59SAmarnath Hullur Subramanyam 	if (!get_param(cmd, "interface") ||
15549c381f59SAmarnath Hullur Subramanyam 	    !get_param(cmd, "PeerAddress"))
15559c381f59SAmarnath Hullur Subramanyam 		return -1;
15569c381f59SAmarnath Hullur Subramanyam 	return 0;
15579c381f59SAmarnath Hullur Subramanyam }
15589c381f59SAmarnath Hullur Subramanyam 
15599c381f59SAmarnath Hullur Subramanyam 
req_intf_p2pdev_grpid(struct sigma_cmd * cmd)15609c381f59SAmarnath Hullur Subramanyam static int req_intf_p2pdev_grpid(struct sigma_cmd *cmd)
15619c381f59SAmarnath Hullur Subramanyam {
15629c381f59SAmarnath Hullur Subramanyam 	if (!get_param(cmd, "interface") ||
15639c381f59SAmarnath Hullur Subramanyam 	    !get_param(cmd, "P2pdevID") ||
15649c381f59SAmarnath Hullur Subramanyam 	    !get_param(cmd, "GroupID"))
15659c381f59SAmarnath Hullur Subramanyam 		return -1;
15669c381f59SAmarnath Hullur Subramanyam 	return 0;
15679c381f59SAmarnath Hullur Subramanyam }
15689c381f59SAmarnath Hullur Subramanyam 
15699c381f59SAmarnath Hullur Subramanyam 
req_intf_prog_type(struct sigma_cmd * cmd)15709c381f59SAmarnath Hullur Subramanyam static int req_intf_prog_type(struct sigma_cmd *cmd)
15719c381f59SAmarnath Hullur Subramanyam {
15729c381f59SAmarnath Hullur Subramanyam 	const char *prog = get_param(cmd, "Program");
15739c381f59SAmarnath Hullur Subramanyam 
15749c381f59SAmarnath Hullur Subramanyam 	if (!get_param(cmd, "interface") ||
15759c381f59SAmarnath Hullur Subramanyam 	    !get_param(cmd, "Type") ||
15769c381f59SAmarnath Hullur Subramanyam 	    !prog || strcmp(prog, "WFD") != 0)
15779c381f59SAmarnath Hullur Subramanyam 		return -1;
15789c381f59SAmarnath Hullur Subramanyam 	return 0;
15799c381f59SAmarnath Hullur Subramanyam }
15809c381f59SAmarnath Hullur Subramanyam 
15819c381f59SAmarnath Hullur Subramanyam 
req_intf_peeradd_inv(struct sigma_cmd * cmd)15829c381f59SAmarnath Hullur Subramanyam static int req_intf_peeradd_inv(struct sigma_cmd *cmd)
15839c381f59SAmarnath Hullur Subramanyam {
15849c381f59SAmarnath Hullur Subramanyam 	if (!get_param(cmd, "interface") ||
15859c381f59SAmarnath Hullur Subramanyam 	    !get_param(cmd, "peerAddress") ||
15869c381f59SAmarnath Hullur Subramanyam 	    !get_param(cmd, "InvitationAction"))
15879c381f59SAmarnath Hullur Subramanyam 		return -1;
15889c381f59SAmarnath Hullur Subramanyam 	return 0;
15899c381f59SAmarnath Hullur Subramanyam }
15909c381f59SAmarnath Hullur Subramanyam 
15919c381f59SAmarnath Hullur Subramanyam 
miracast_register_cmds(void)15929c381f59SAmarnath Hullur Subramanyam void miracast_register_cmds(void)
15939c381f59SAmarnath Hullur Subramanyam {
15949c381f59SAmarnath Hullur Subramanyam 	sigma_dut_reg_cmd("start_wfd_connection", req_intf_peer,
15959c381f59SAmarnath Hullur Subramanyam 			  cmd_start_wfd_connection);
15969c381f59SAmarnath Hullur Subramanyam 	sigma_dut_reg_cmd("connect_go_start_wfd", req_intf_p2pdev_grpid,
15979c381f59SAmarnath Hullur Subramanyam 			  cmd_connect_go_start_wfd);
15989c381f59SAmarnath Hullur Subramanyam 	sigma_dut_reg_cmd("sta_generate_event", req_intf_prog_type,
15999c381f59SAmarnath Hullur Subramanyam 			  cmd_sta_generate_event);
16009c381f59SAmarnath Hullur Subramanyam 	sigma_dut_reg_cmd("reinvoke_wfd_session", req_intf_peeradd_inv,
16019c381f59SAmarnath Hullur Subramanyam 			  cmd_reinvoke_wfd_session);
16029c381f59SAmarnath Hullur Subramanyam }
1603