1*9c381f59SAmarnath Hullur Subramanyam /* 2*9c381f59SAmarnath Hullur Subramanyam * Sigma Control API DUT - Miracast interface 3*9c381f59SAmarnath Hullur Subramanyam * Copyright (c) 2017, Qualcomm Atheros, Inc. 4*9c381f59SAmarnath Hullur Subramanyam * All Rights Reserved. 5*9c381f59SAmarnath Hullur Subramanyam * Licensed under the Clear BSD license. See README for more details. 6*9c381f59SAmarnath Hullur Subramanyam * 7*9c381f59SAmarnath Hullur Subramanyam * Implementation of MIRACAST specific functionality. 8*9c381f59SAmarnath Hullur Subramanyam * For example, starting wfd session. 9*9c381f59SAmarnath Hullur Subramanyam */ 10*9c381f59SAmarnath Hullur Subramanyam 11*9c381f59SAmarnath Hullur Subramanyam #include "sigma_dut.h" 12*9c381f59SAmarnath Hullur Subramanyam #include <dlfcn.h> 13*9c381f59SAmarnath Hullur Subramanyam #include <sys/ioctl.h> 14*9c381f59SAmarnath Hullur Subramanyam #include <sys/select.h> 15*9c381f59SAmarnath Hullur Subramanyam #include "wpa_ctrl.h" 16*9c381f59SAmarnath Hullur Subramanyam #include "wpa_helpers.h" 17*9c381f59SAmarnath Hullur Subramanyam #include "miracast.h" 18*9c381f59SAmarnath Hullur Subramanyam #ifdef ANDROID 19*9c381f59SAmarnath Hullur Subramanyam #include "properties.h" 20*9c381f59SAmarnath Hullur Subramanyam #ifndef MIRACAST_DHCP_M 21*9c381f59SAmarnath Hullur Subramanyam #include <netutils/ifc.h> 22*9c381f59SAmarnath Hullur Subramanyam #endif /* MIRACAST_DHCP_M */ 23*9c381f59SAmarnath Hullur Subramanyam #endif /* ANDROID */ 24*9c381f59SAmarnath Hullur Subramanyam 25*9c381f59SAmarnath Hullur Subramanyam #define HUNDRED_SECOND_TIMEOUT 100 /* 100 seconds */ 26*9c381f59SAmarnath Hullur Subramanyam #define DHCP_LEASE_FILE_PATH "/data/misc/dhcp/dnsmasq.leases" 27*9c381f59SAmarnath Hullur Subramanyam #define MIRACAST_CMD_LEN 512 28*9c381f59SAmarnath Hullur Subramanyam 29*9c381f59SAmarnath Hullur Subramanyam extern char *sigma_main_ifname; 30*9c381f59SAmarnath Hullur Subramanyam extern char *sigma_station_ifname; 31*9c381f59SAmarnath Hullur Subramanyam 32*9c381f59SAmarnath Hullur Subramanyam static int session_management_control_port = 7236; 33*9c381f59SAmarnath Hullur Subramanyam /* Followingng stores p2p interface name after P2P group formation */ 34*9c381f59SAmarnath Hullur Subramanyam static char wfd_ifname[32]; 35*9c381f59SAmarnath Hullur Subramanyam 36*9c381f59SAmarnath Hullur Subramanyam 37*9c381f59SAmarnath Hullur Subramanyam #ifndef ANDROID 38*9c381f59SAmarnath Hullur Subramanyam 39*9c381f59SAmarnath Hullur Subramanyam static size_t strlcpy(char *dest, const char *src, size_t siz) 40*9c381f59SAmarnath Hullur Subramanyam { 41*9c381f59SAmarnath Hullur Subramanyam const char *s = src; 42*9c381f59SAmarnath Hullur Subramanyam size_t left = siz; 43*9c381f59SAmarnath Hullur Subramanyam 44*9c381f59SAmarnath Hullur Subramanyam if (left) { 45*9c381f59SAmarnath Hullur Subramanyam /* Copy string up to the maximum size of the dest buffer */ 46*9c381f59SAmarnath Hullur Subramanyam while (--left != 0) { 47*9c381f59SAmarnath Hullur Subramanyam if ((*dest++ = *s++) == '\0') 48*9c381f59SAmarnath Hullur Subramanyam break; 49*9c381f59SAmarnath Hullur Subramanyam } 50*9c381f59SAmarnath Hullur Subramanyam } 51*9c381f59SAmarnath Hullur Subramanyam 52*9c381f59SAmarnath Hullur Subramanyam if (left == 0) { 53*9c381f59SAmarnath Hullur Subramanyam /* Not enough room for the string; force NUL-termination */ 54*9c381f59SAmarnath Hullur Subramanyam if (siz != 0) 55*9c381f59SAmarnath Hullur Subramanyam *dest = '\0'; 56*9c381f59SAmarnath Hullur Subramanyam while (*s++) 57*9c381f59SAmarnath Hullur Subramanyam ; /* determine total src string length */ 58*9c381f59SAmarnath Hullur Subramanyam } 59*9c381f59SAmarnath Hullur Subramanyam 60*9c381f59SAmarnath Hullur Subramanyam return s - src - 1; 61*9c381f59SAmarnath Hullur Subramanyam } 62*9c381f59SAmarnath Hullur Subramanyam 63*9c381f59SAmarnath Hullur Subramanyam 64*9c381f59SAmarnath Hullur Subramanyam static size_t strlcat(char *dst, const char *str, size_t size) 65*9c381f59SAmarnath Hullur Subramanyam { 66*9c381f59SAmarnath Hullur Subramanyam char *pos; 67*9c381f59SAmarnath Hullur Subramanyam size_t dstlen, srclen, copy; 68*9c381f59SAmarnath Hullur Subramanyam 69*9c381f59SAmarnath Hullur Subramanyam srclen = strlen(str); 70*9c381f59SAmarnath Hullur Subramanyam for (pos = dst; pos - dst < size && *dst; pos++) 71*9c381f59SAmarnath Hullur Subramanyam ; 72*9c381f59SAmarnath Hullur Subramanyam dstlen = pos - dst; 73*9c381f59SAmarnath Hullur Subramanyam if (*dst) 74*9c381f59SAmarnath Hullur Subramanyam return dstlen + srclen; 75*9c381f59SAmarnath Hullur Subramanyam if (dstlen + srclen + 1 > size) 76*9c381f59SAmarnath Hullur Subramanyam copy = size - dstlen - 1; 77*9c381f59SAmarnath Hullur Subramanyam else 78*9c381f59SAmarnath Hullur Subramanyam copy = srclen; 79*9c381f59SAmarnath Hullur Subramanyam memcpy(pos, str, copy); 80*9c381f59SAmarnath Hullur Subramanyam pos[copy] = '\0'; 81*9c381f59SAmarnath Hullur Subramanyam return dstlen + srclen; 82*9c381f59SAmarnath Hullur Subramanyam } 83*9c381f59SAmarnath Hullur Subramanyam 84*9c381f59SAmarnath Hullur Subramanyam #endif /* ANDROID */ 85*9c381f59SAmarnath Hullur Subramanyam 86*9c381f59SAmarnath Hullur Subramanyam 87*9c381f59SAmarnath Hullur Subramanyam static int miracast_load(struct sigma_dut *dut) 88*9c381f59SAmarnath Hullur Subramanyam { 89*9c381f59SAmarnath Hullur Subramanyam static int once = 1; 90*9c381f59SAmarnath Hullur Subramanyam 91*9c381f59SAmarnath Hullur Subramanyam if (!once) 92*9c381f59SAmarnath Hullur Subramanyam return 0; 93*9c381f59SAmarnath Hullur Subramanyam 94*9c381f59SAmarnath Hullur Subramanyam once = 0; 95*9c381f59SAmarnath Hullur Subramanyam dlerror(); 96*9c381f59SAmarnath Hullur Subramanyam dut->miracast_lib = dlopen(dut->miracast_lib_path ? 97*9c381f59SAmarnath Hullur Subramanyam dut->miracast_lib_path : "libmiracast.so", 98*9c381f59SAmarnath Hullur Subramanyam RTLD_LAZY); 99*9c381f59SAmarnath Hullur Subramanyam if (!dut->miracast_lib) { 100*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 101*9c381f59SAmarnath Hullur Subramanyam "Fail to load Miracast library %s", 102*9c381f59SAmarnath Hullur Subramanyam dlerror()); 103*9c381f59SAmarnath Hullur Subramanyam return -1; 104*9c381f59SAmarnath Hullur Subramanyam } 105*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 106*9c381f59SAmarnath Hullur Subramanyam "Miracast Wi-Fi Display library found - starting service"); 107*9c381f59SAmarnath Hullur Subramanyam return 0; 108*9c381f59SAmarnath Hullur Subramanyam } 109*9c381f59SAmarnath Hullur Subramanyam 110*9c381f59SAmarnath Hullur Subramanyam 111*9c381f59SAmarnath Hullur Subramanyam static int miracast_unload(struct sigma_dut *dut) 112*9c381f59SAmarnath Hullur Subramanyam { 113*9c381f59SAmarnath Hullur Subramanyam int err; 114*9c381f59SAmarnath Hullur Subramanyam 115*9c381f59SAmarnath Hullur Subramanyam if (!dut->miracast_lib) 116*9c381f59SAmarnath Hullur Subramanyam return -1; 117*9c381f59SAmarnath Hullur Subramanyam 118*9c381f59SAmarnath Hullur Subramanyam dlerror(); 119*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "Unloading Miracast library"); 120*9c381f59SAmarnath Hullur Subramanyam err = dlclose(dut->miracast_lib); 121*9c381f59SAmarnath Hullur Subramanyam dut->miracast_lib = NULL; 122*9c381f59SAmarnath Hullur Subramanyam if (err == 0) { 123*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 124*9c381f59SAmarnath Hullur Subramanyam "Miracast library successfully unloaded"); 125*9c381f59SAmarnath Hullur Subramanyam } else { 126*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 127*9c381f59SAmarnath Hullur Subramanyam "Failed to unload Miracast library"); 128*9c381f59SAmarnath Hullur Subramanyam } 129*9c381f59SAmarnath Hullur Subramanyam return err; 130*9c381f59SAmarnath Hullur Subramanyam } 131*9c381f59SAmarnath Hullur Subramanyam 132*9c381f59SAmarnath Hullur Subramanyam 133*9c381f59SAmarnath Hullur Subramanyam static int get_peer_ip_p2p_go(struct sigma_dut *dut, char *ipaddr, 134*9c381f59SAmarnath Hullur Subramanyam const char *macaddr, unsigned int wait_limit) 135*9c381f59SAmarnath Hullur Subramanyam { 136*9c381f59SAmarnath Hullur Subramanyam 137*9c381f59SAmarnath Hullur Subramanyam FILE *fp; 138*9c381f59SAmarnath Hullur Subramanyam 139*9c381f59SAmarnath Hullur Subramanyam fp = fopen(DHCP_LEASE_FILE_PATH, "r"); 140*9c381f59SAmarnath Hullur Subramanyam if (!fp) { 141*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, 142*9c381f59SAmarnath Hullur Subramanyam "Could not open DHCP lease file"); 143*9c381f59SAmarnath Hullur Subramanyam return -1; 144*9c381f59SAmarnath Hullur Subramanyam } 145*9c381f59SAmarnath Hullur Subramanyam 146*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "macaddress %s", macaddr); 147*9c381f59SAmarnath Hullur Subramanyam while (wait_limit > 0) { 148*9c381f59SAmarnath Hullur Subramanyam char line[100] = { 0 }; 149*9c381f59SAmarnath Hullur Subramanyam char *str1 = NULL; 150*9c381f59SAmarnath Hullur Subramanyam char *dummy_str = NULL; 151*9c381f59SAmarnath Hullur Subramanyam char dummy_macaddress[32]; 152*9c381f59SAmarnath Hullur Subramanyam int ip_found = 0; 153*9c381f59SAmarnath Hullur Subramanyam int len; 154*9c381f59SAmarnath Hullur Subramanyam 155*9c381f59SAmarnath Hullur Subramanyam fseek(fp, 0, SEEK_SET); 156*9c381f59SAmarnath Hullur Subramanyam while (fgets(line, sizeof(line), fp) != NULL) { 157*9c381f59SAmarnath Hullur Subramanyam len = strlen(line); 158*9c381f59SAmarnath Hullur Subramanyam if (len == 0) 159*9c381f59SAmarnath Hullur Subramanyam continue; 160*9c381f59SAmarnath Hullur Subramanyam 161*9c381f59SAmarnath Hullur Subramanyam str1 = strtok_r(line, " ", &dummy_str); 162*9c381f59SAmarnath Hullur Subramanyam if (str1 == NULL) 163*9c381f59SAmarnath Hullur Subramanyam break; 164*9c381f59SAmarnath Hullur Subramanyam 165*9c381f59SAmarnath Hullur Subramanyam /* Look for mac address */ 166*9c381f59SAmarnath Hullur Subramanyam str1 = strtok_r(NULL, " ", &dummy_str); 167*9c381f59SAmarnath Hullur Subramanyam if (str1 == NULL) 168*9c381f59SAmarnath Hullur Subramanyam break; 169*9c381f59SAmarnath Hullur Subramanyam 170*9c381f59SAmarnath Hullur Subramanyam strlcpy(dummy_macaddress, str1, 171*9c381f59SAmarnath Hullur Subramanyam sizeof(dummy_macaddress)); 172*9c381f59SAmarnath Hullur Subramanyam 173*9c381f59SAmarnath Hullur Subramanyam /* Look for ip address */ 174*9c381f59SAmarnath Hullur Subramanyam str1 = strtok_r(NULL, " ", &dummy_str); 175*9c381f59SAmarnath Hullur Subramanyam if (str1 == NULL) 176*9c381f59SAmarnath Hullur Subramanyam break; 177*9c381f59SAmarnath Hullur Subramanyam 178*9c381f59SAmarnath Hullur Subramanyam strlcpy(ipaddr,str1,32); 179*9c381f59SAmarnath Hullur Subramanyam 180*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 181*9c381f59SAmarnath Hullur Subramanyam "Peer IP Address obtained and mac %s %s", 182*9c381f59SAmarnath Hullur Subramanyam ipaddr, dummy_macaddress); 183*9c381f59SAmarnath Hullur Subramanyam 184*9c381f59SAmarnath Hullur Subramanyam /* 185*9c381f59SAmarnath Hullur Subramanyam * The idea is that the p2p mac address may differ by 1 186*9c381f59SAmarnath Hullur Subramanyam * nibble mostly it is the first byte, hence try the 187*9c381f59SAmarnath Hullur Subramanyam * middle two octets. 188*9c381f59SAmarnath Hullur Subramanyam */ 189*9c381f59SAmarnath Hullur Subramanyam if (strncasecmp(macaddr + 6, dummy_macaddress + 6, 190*9c381f59SAmarnath Hullur Subramanyam 5) == 0) { 191*9c381f59SAmarnath Hullur Subramanyam ip_found = 1; 192*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 193*9c381f59SAmarnath Hullur Subramanyam "Obtained the IP address %s", 194*9c381f59SAmarnath Hullur Subramanyam ipaddr); 195*9c381f59SAmarnath Hullur Subramanyam break; 196*9c381f59SAmarnath Hullur Subramanyam } 197*9c381f59SAmarnath Hullur Subramanyam } 198*9c381f59SAmarnath Hullur Subramanyam 199*9c381f59SAmarnath Hullur Subramanyam if (ip_found) 200*9c381f59SAmarnath Hullur Subramanyam break; 201*9c381f59SAmarnath Hullur Subramanyam 202*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 203*9c381f59SAmarnath Hullur Subramanyam "Failed to find IP from DHCP lease file"); 204*9c381f59SAmarnath Hullur Subramanyam sleep(1); 205*9c381f59SAmarnath Hullur Subramanyam wait_limit--; 206*9c381f59SAmarnath Hullur Subramanyam } 207*9c381f59SAmarnath Hullur Subramanyam fclose(fp); 208*9c381f59SAmarnath Hullur Subramanyam return 0; 209*9c381f59SAmarnath Hullur Subramanyam } 210*9c381f59SAmarnath Hullur Subramanyam 211*9c381f59SAmarnath Hullur Subramanyam 212*9c381f59SAmarnath Hullur Subramanyam static int miracast_start_dhcp_client(struct sigma_dut *dut, const char *ifname) 213*9c381f59SAmarnath Hullur Subramanyam { 214*9c381f59SAmarnath Hullur Subramanyam #ifdef MIRACAST_DHCP_M 215*9c381f59SAmarnath Hullur Subramanyam start_dhcp(dut, ifname, 0); 216*9c381f59SAmarnath Hullur Subramanyam #else /* MIRACAST_DHCP_M */ 217*9c381f59SAmarnath Hullur Subramanyam int ret = ifc_init(); 218*9c381f59SAmarnath Hullur Subramanyam 219*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "ifc init returned %d", ret); 220*9c381f59SAmarnath Hullur Subramanyam ret = do_dhcp((char *) ifname); 221*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "do dhcp returned %d", ret); 222*9c381f59SAmarnath Hullur Subramanyam #endif /* MIRACAST_DHCP_M */ 223*9c381f59SAmarnath Hullur Subramanyam return 0; 224*9c381f59SAmarnath Hullur Subramanyam } 225*9c381f59SAmarnath Hullur Subramanyam 226*9c381f59SAmarnath Hullur Subramanyam 227*9c381f59SAmarnath Hullur Subramanyam static void miracast_stop_dhcp_client(struct sigma_dut *dut, char *ifname) 228*9c381f59SAmarnath Hullur Subramanyam { 229*9c381f59SAmarnath Hullur Subramanyam #ifdef MIRACAST_DHCP_M 230*9c381f59SAmarnath Hullur Subramanyam stop_dhcp(dut, ifname, 0); 231*9c381f59SAmarnath Hullur Subramanyam #else /* MIRACAST_DHCP_M */ 232*9c381f59SAmarnath Hullur Subramanyam ifc_close(); 233*9c381f59SAmarnath Hullur Subramanyam #endif /* MIRACAST_DHCP_M */ 234*9c381f59SAmarnath Hullur Subramanyam } 235*9c381f59SAmarnath Hullur Subramanyam 236*9c381f59SAmarnath Hullur Subramanyam 237*9c381f59SAmarnath Hullur Subramanyam #ifdef MIRACAST_DHCP_M 238*9c381f59SAmarnath Hullur Subramanyam 239*9c381f59SAmarnath Hullur Subramanyam static int get_local_ip_address(struct sigma_dut *dut, 240*9c381f59SAmarnath Hullur Subramanyam char *local_ip_addr, size_t buflen, 241*9c381f59SAmarnath Hullur Subramanyam const char *intf, int size) 242*9c381f59SAmarnath Hullur Subramanyam { 243*9c381f59SAmarnath Hullur Subramanyam struct ifreq ifr; 244*9c381f59SAmarnath Hullur Subramanyam int s; 245*9c381f59SAmarnath Hullur Subramanyam 246*9c381f59SAmarnath Hullur Subramanyam memset(&ifr, 0, sizeof(struct ifreq)); 247*9c381f59SAmarnath Hullur Subramanyam strlcpy(ifr.ifr_name, intf, IFNAMSIZ); 248*9c381f59SAmarnath Hullur Subramanyam ifr.ifr_name[IFNAMSIZ-1] = 0; 249*9c381f59SAmarnath Hullur Subramanyam 250*9c381f59SAmarnath Hullur Subramanyam if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 251*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 252*9c381f59SAmarnath Hullur Subramanyam "%s: Error in creating socket", __func__); 253*9c381f59SAmarnath Hullur Subramanyam return -1; 254*9c381f59SAmarnath Hullur Subramanyam } 255*9c381f59SAmarnath Hullur Subramanyam 256*9c381f59SAmarnath Hullur Subramanyam if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { 257*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "ioctl failed: %s", 258*9c381f59SAmarnath Hullur Subramanyam strerror(errno)); 259*9c381f59SAmarnath Hullur Subramanyam close(s); 260*9c381f59SAmarnath Hullur Subramanyam return -1; 261*9c381f59SAmarnath Hullur Subramanyam } 262*9c381f59SAmarnath Hullur Subramanyam 263*9c381f59SAmarnath Hullur Subramanyam strlcpy(local_ip_addr, 264*9c381f59SAmarnath Hullur Subramanyam inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr), 265*9c381f59SAmarnath Hullur Subramanyam buflen); 266*9c381f59SAmarnath Hullur Subramanyam close(s); 267*9c381f59SAmarnath Hullur Subramanyam return 0; 268*9c381f59SAmarnath Hullur Subramanyam } 269*9c381f59SAmarnath Hullur Subramanyam 270*9c381f59SAmarnath Hullur Subramanyam 271*9c381f59SAmarnath Hullur Subramanyam static int get_peer_ip_p2p_client(struct sigma_dut *dut, char *ip_addr, 272*9c381f59SAmarnath Hullur Subramanyam const char *intf, unsigned int wait_limit) 273*9c381f59SAmarnath Hullur Subramanyam { 274*9c381f59SAmarnath Hullur Subramanyam char prop_name[128]; 275*9c381f59SAmarnath Hullur Subramanyam char prop_name_self[128]; 276*9c381f59SAmarnath Hullur Subramanyam char self_ip[128]; 277*9c381f59SAmarnath Hullur Subramanyam 278*9c381f59SAmarnath Hullur Subramanyam memset(self_ip, 0, sizeof(self_ip)); 279*9c381f59SAmarnath Hullur Subramanyam /* For P2P Client read the server property */ 280*9c381f59SAmarnath Hullur Subramanyam snprintf(prop_name, sizeof(prop_name), "%s.%s.server", "dhcp", "p2p"); 281*9c381f59SAmarnath Hullur Subramanyam snprintf(prop_name_self, sizeof(prop_name_self), 282*9c381f59SAmarnath Hullur Subramanyam "%s.%s.ipaddress", "dhcp", "p2p"); 283*9c381f59SAmarnath Hullur Subramanyam 284*9c381f59SAmarnath Hullur Subramanyam while (wait_limit > 0) { 285*9c381f59SAmarnath Hullur Subramanyam #ifdef ANDROID 286*9c381f59SAmarnath Hullur Subramanyam property_get(prop_name, ip_addr, NULL); 287*9c381f59SAmarnath Hullur Subramanyam #else /* ANDROID */ 288*9c381f59SAmarnath Hullur Subramanyam ip_addr[0] = '\0'; 289*9c381f59SAmarnath Hullur Subramanyam #endif /* ANDROID */ 290*9c381f59SAmarnath Hullur Subramanyam get_local_ip_address(dut, self_ip, sizeof(self_ip), intf, 20); 291*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "Peer IP, self IP: %s %s", 292*9c381f59SAmarnath Hullur Subramanyam ip_addr, self_ip); 293*9c381f59SAmarnath Hullur Subramanyam if (strlen(ip_addr) > 8 && 294*9c381f59SAmarnath Hullur Subramanyam ip_addr[0] == '1' && ip_addr[1] == '9' && 295*9c381f59SAmarnath Hullur Subramanyam self_ip[0] == '1' && self_ip[1] == '9') 296*9c381f59SAmarnath Hullur Subramanyam break; /* connected */ 297*9c381f59SAmarnath Hullur Subramanyam 298*9c381f59SAmarnath Hullur Subramanyam /* What if DHCP server was started before Client was started? 299*9c381f59SAmarnath Hullur Subramanyam * Request DHCP yet again */ 300*9c381f59SAmarnath Hullur Subramanyam miracast_start_dhcp_client(dut, intf); 301*9c381f59SAmarnath Hullur Subramanyam sleep(5); /* Sleep always helps */ 302*9c381f59SAmarnath Hullur Subramanyam wait_limit--; 303*9c381f59SAmarnath Hullur Subramanyam } 304*9c381f59SAmarnath Hullur Subramanyam 305*9c381f59SAmarnath Hullur Subramanyam return wait_limit > 0 ? 0 : -1; 306*9c381f59SAmarnath Hullur Subramanyam } 307*9c381f59SAmarnath Hullur Subramanyam 308*9c381f59SAmarnath Hullur Subramanyam #else /* MIRACAST_DHCP_M */ 309*9c381f59SAmarnath Hullur Subramanyam 310*9c381f59SAmarnath Hullur Subramanyam extern void get_dhcp_info(uint32_t *ipaddr, uint32_t *gateway, 311*9c381f59SAmarnath Hullur Subramanyam uint32_t *prefixLength, uint32_t *dns1, 312*9c381f59SAmarnath Hullur Subramanyam uint32_t *dns2, uint32_t *server, 313*9c381f59SAmarnath Hullur Subramanyam uint32_t *lease); 314*9c381f59SAmarnath Hullur Subramanyam 315*9c381f59SAmarnath Hullur Subramanyam extern int do_dhcp(char *); 316*9c381f59SAmarnath Hullur Subramanyam 317*9c381f59SAmarnath Hullur Subramanyam const char *ipaddr (in_addr_t addr) 318*9c381f59SAmarnath Hullur Subramanyam { 319*9c381f59SAmarnath Hullur Subramanyam struct in_addr in_addr; 320*9c381f59SAmarnath Hullur Subramanyam in_addr.s_addr = addr; 321*9c381f59SAmarnath Hullur Subramanyam return inet_ntoa(in_addr); 322*9c381f59SAmarnath Hullur Subramanyam } 323*9c381f59SAmarnath Hullur Subramanyam 324*9c381f59SAmarnath Hullur Subramanyam 325*9c381f59SAmarnath Hullur Subramanyam static int get_peer_ip_p2p_client(struct sigma_dut *dut, char *ipAddr, 326*9c381f59SAmarnath Hullur Subramanyam const char *intf, unsigned int wait_limit) 327*9c381f59SAmarnath Hullur Subramanyam { 328*9c381f59SAmarnath Hullur Subramanyam uint32_t ipaddress, gateway, prefixLength, 329*9c381f59SAmarnath Hullur Subramanyam dns1, dns2, serveraddr, lease; 330*9c381f59SAmarnath Hullur Subramanyam 331*9c381f59SAmarnath Hullur Subramanyam get_dhcp_info(&ipaddress, &gateway, &prefixLength, &dns1, &dns2, 332*9c381f59SAmarnath Hullur Subramanyam &serveraddr, &lease); 333*9c381f59SAmarnath Hullur Subramanyam while (wait_limit > 0) { 334*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "Peer IP: %u", ipaddress); 335*9c381f59SAmarnath Hullur Subramanyam if (strlen(ipaddr(serveraddr)) > 8) { 336*9c381f59SAmarnath Hullur Subramanyam /* connected */ 337*9c381f59SAmarnath Hullur Subramanyam strncpy(ipAddr, ipaddr(serveraddr), 16); 338*9c381f59SAmarnath Hullur Subramanyam break; 339*9c381f59SAmarnath Hullur Subramanyam } 340*9c381f59SAmarnath Hullur Subramanyam sleep(1); 341*9c381f59SAmarnath Hullur Subramanyam wait_limit--; 342*9c381f59SAmarnath Hullur Subramanyam } 343*9c381f59SAmarnath Hullur Subramanyam return wait_limit == 0 ? -1 : 0; 344*9c381f59SAmarnath Hullur Subramanyam } 345*9c381f59SAmarnath Hullur Subramanyam 346*9c381f59SAmarnath Hullur Subramanyam #endif /* MIRACAST_DHCP_M */ 347*9c381f59SAmarnath Hullur Subramanyam 348*9c381f59SAmarnath Hullur Subramanyam 349*9c381f59SAmarnath Hullur Subramanyam static int get_p2p_connection_event(struct sigma_dut *dut, 350*9c381f59SAmarnath Hullur Subramanyam const char *input_intf, 351*9c381f59SAmarnath Hullur Subramanyam char *output_intf, 352*9c381f59SAmarnath Hullur Subramanyam int size_output_intf, 353*9c381f59SAmarnath Hullur Subramanyam int *is_group_owner) 354*9c381f59SAmarnath Hullur Subramanyam { 355*9c381f59SAmarnath Hullur Subramanyam /* 356*9c381f59SAmarnath Hullur Subramanyam * Poll for the P2P Connection 357*9c381f59SAmarnath Hullur Subramanyam * Then poll for IP 358*9c381f59SAmarnath Hullur Subramanyam * Then poll for WFD session ID and exit 359*9c381f59SAmarnath Hullur Subramanyam * P2P connection done 360*9c381f59SAmarnath Hullur Subramanyam * Loop till connection is ready 361*9c381f59SAmarnath Hullur Subramanyam */ 362*9c381f59SAmarnath Hullur Subramanyam struct wpa_ctrl *ctrl; 363*9c381f59SAmarnath Hullur Subramanyam char *mode_string; 364*9c381f59SAmarnath Hullur Subramanyam char event_buf[256]; 365*9c381f59SAmarnath Hullur Subramanyam char *ifname; 366*9c381f59SAmarnath Hullur Subramanyam char *pos; 367*9c381f59SAmarnath Hullur Subramanyam int res = 0; 368*9c381f59SAmarnath Hullur Subramanyam const char *events[] = { 369*9c381f59SAmarnath Hullur Subramanyam "P2P-GROUP-STARTED", 370*9c381f59SAmarnath Hullur Subramanyam "P2P-GO-NEG-FAILURE", 371*9c381f59SAmarnath Hullur Subramanyam "P2P-GROUP-FORMATION-FAILURE", 372*9c381f59SAmarnath Hullur Subramanyam NULL 373*9c381f59SAmarnath Hullur Subramanyam }; 374*9c381f59SAmarnath Hullur Subramanyam 375*9c381f59SAmarnath Hullur Subramanyam /* Wait for WPA CLI EVENTS */ 376*9c381f59SAmarnath Hullur Subramanyam /* Default timeout is 120s */ 377*9c381f59SAmarnath Hullur Subramanyam ctrl = open_wpa_mon(input_intf); 378*9c381f59SAmarnath Hullur Subramanyam if (!ctrl) { 379*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, 380*9c381f59SAmarnath Hullur Subramanyam "Failed to open wpa_supplicant monitor connection"); 381*9c381f59SAmarnath Hullur Subramanyam return -1; 382*9c381f59SAmarnath Hullur Subramanyam } 383*9c381f59SAmarnath Hullur Subramanyam 384*9c381f59SAmarnath Hullur Subramanyam res = get_wpa_cli_events(dut, ctrl, events, event_buf, 385*9c381f59SAmarnath Hullur Subramanyam sizeof(event_buf)); 386*9c381f59SAmarnath Hullur Subramanyam 387*9c381f59SAmarnath Hullur Subramanyam wpa_ctrl_detach(ctrl); 388*9c381f59SAmarnath Hullur Subramanyam wpa_ctrl_close(ctrl); 389*9c381f59SAmarnath Hullur Subramanyam 390*9c381f59SAmarnath Hullur Subramanyam if (res < 0) { 391*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, 392*9c381f59SAmarnath Hullur Subramanyam "Group formation did not complete"); 393*9c381f59SAmarnath Hullur Subramanyam return -1; 394*9c381f59SAmarnath Hullur Subramanyam } 395*9c381f59SAmarnath Hullur Subramanyam 396*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "Received event %s", event_buf); 397*9c381f59SAmarnath Hullur Subramanyam 398*9c381f59SAmarnath Hullur Subramanyam if (strstr(event_buf, "P2P-GROUP-FORMATION-FAILURE") || 399*9c381f59SAmarnath Hullur Subramanyam strstr(event_buf, "P2P-GO-NEG-FAILURE")) 400*9c381f59SAmarnath Hullur Subramanyam return -1; 401*9c381f59SAmarnath Hullur Subramanyam 402*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "P2P connection done"); 403*9c381f59SAmarnath Hullur Subramanyam ifname = strchr(event_buf, ' '); 404*9c381f59SAmarnath Hullur Subramanyam if (!ifname) { 405*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "No P2P interface found"); 406*9c381f59SAmarnath Hullur Subramanyam return -1; 407*9c381f59SAmarnath Hullur Subramanyam } 408*9c381f59SAmarnath Hullur Subramanyam ifname++; 409*9c381f59SAmarnath Hullur Subramanyam pos = strchr(ifname, ' '); 410*9c381f59SAmarnath Hullur Subramanyam if (!pos) { 411*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, "No P2P interface found"); 412*9c381f59SAmarnath Hullur Subramanyam return -1; 413*9c381f59SAmarnath Hullur Subramanyam } 414*9c381f59SAmarnath Hullur Subramanyam *pos++ = '\0'; 415*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "Group interface %s", ifname); 416*9c381f59SAmarnath Hullur Subramanyam 417*9c381f59SAmarnath Hullur Subramanyam strlcpy(output_intf, ifname, size_output_intf); 418*9c381f59SAmarnath Hullur Subramanyam 419*9c381f59SAmarnath Hullur Subramanyam mode_string = pos; 420*9c381f59SAmarnath Hullur Subramanyam pos = strchr(mode_string, ' '); 421*9c381f59SAmarnath Hullur Subramanyam if (!pos) { 422*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, "No group role found"); 423*9c381f59SAmarnath Hullur Subramanyam return -1; 424*9c381f59SAmarnath Hullur Subramanyam } 425*9c381f59SAmarnath Hullur Subramanyam 426*9c381f59SAmarnath Hullur Subramanyam *pos++ = '\0'; 427*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "Group Role %s", mode_string); 428*9c381f59SAmarnath Hullur Subramanyam 429*9c381f59SAmarnath Hullur Subramanyam if (strcmp(mode_string, "GO") == 0) 430*9c381f59SAmarnath Hullur Subramanyam *is_group_owner = 1; 431*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "Value of is_group_owner %d", 432*9c381f59SAmarnath Hullur Subramanyam *is_group_owner); 433*9c381f59SAmarnath Hullur Subramanyam return 0; 434*9c381f59SAmarnath Hullur Subramanyam } 435*9c381f59SAmarnath Hullur Subramanyam 436*9c381f59SAmarnath Hullur Subramanyam 437*9c381f59SAmarnath Hullur Subramanyam /* Following serves as an entry point function to perform rtsp tasks */ 438*9c381f59SAmarnath Hullur Subramanyam static void * miracast_rtsp_thread_entry(void *ptr) 439*9c381f59SAmarnath Hullur Subramanyam { 440*9c381f59SAmarnath Hullur Subramanyam struct sigma_dut *dut = ptr; 441*9c381f59SAmarnath Hullur Subramanyam char output_ifname[16]; 442*9c381f59SAmarnath Hullur Subramanyam int is_group_owner = 0; 443*9c381f59SAmarnath Hullur Subramanyam const char *intf = sigma_station_ifname; 444*9c381f59SAmarnath Hullur Subramanyam unsigned int wait_limit; 445*9c381f59SAmarnath Hullur Subramanyam char peer_ip_address[32]; 446*9c381f59SAmarnath Hullur Subramanyam char rtsp_session_id[12]; 447*9c381f59SAmarnath Hullur Subramanyam int (*extn_start_wfd_connection)(const char *, 448*9c381f59SAmarnath Hullur Subramanyam const char *, /* Peer IP */ 449*9c381f59SAmarnath Hullur Subramanyam int, /* RTSP port number */ 450*9c381f59SAmarnath Hullur Subramanyam int, /* WFD Device Type; 0-Source, 451*9c381f59SAmarnath Hullur Subramanyam 1-P-Sink, 2-Secondary Sink */ 452*9c381f59SAmarnath Hullur Subramanyam char *); /* for returning session ID */ 453*9c381f59SAmarnath Hullur Subramanyam 454*9c381f59SAmarnath Hullur Subramanyam if (!dut) { 455*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, 456*9c381f59SAmarnath Hullur Subramanyam "Bail out, RTSP thread has invalid parameters"); 457*9c381f59SAmarnath Hullur Subramanyam goto EXIT; 458*9c381f59SAmarnath Hullur Subramanyam } 459*9c381f59SAmarnath Hullur Subramanyam 460*9c381f59SAmarnath Hullur Subramanyam miracast_load(dut); 461*9c381f59SAmarnath Hullur Subramanyam 462*9c381f59SAmarnath Hullur Subramanyam if (sigma_main_ifname) { 463*9c381f59SAmarnath Hullur Subramanyam intf = sigma_main_ifname; 464*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, 465*9c381f59SAmarnath Hullur Subramanyam "miracast_rtsp_thread_entry: sigma_main_ifname = [%s]", 466*9c381f59SAmarnath Hullur Subramanyam intf); 467*9c381f59SAmarnath Hullur Subramanyam } else { 468*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, 469*9c381f59SAmarnath Hullur Subramanyam "miracast_rtsp_thread_entry: sigma_main_ifname is NULL"); 470*9c381f59SAmarnath Hullur Subramanyam } 471*9c381f59SAmarnath Hullur Subramanyam 472*9c381f59SAmarnath Hullur Subramanyam if (get_p2p_connection_event(dut, intf, output_ifname, 473*9c381f59SAmarnath Hullur Subramanyam sizeof(output_ifname), 474*9c381f59SAmarnath Hullur Subramanyam &is_group_owner) < 0) { 475*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, "P2P connection failure"); 476*9c381f59SAmarnath Hullur Subramanyam goto EXIT; 477*9c381f59SAmarnath Hullur Subramanyam } 478*9c381f59SAmarnath Hullur Subramanyam 479*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting to start dhcp"); 480*9c381f59SAmarnath Hullur Subramanyam 481*9c381f59SAmarnath Hullur Subramanyam /* Calling WFD APIs now */ 482*9c381f59SAmarnath Hullur Subramanyam /* If you are a source, go ahead and start the RTSP server */ 483*9c381f59SAmarnath Hullur Subramanyam if (dut->wfd_device_type != 0) 484*9c381f59SAmarnath Hullur Subramanyam wait_limit = HUNDRED_SECOND_TIMEOUT; 485*9c381f59SAmarnath Hullur Subramanyam else 486*9c381f59SAmarnath Hullur Subramanyam wait_limit = 500; 487*9c381f59SAmarnath Hullur Subramanyam 488*9c381f59SAmarnath Hullur Subramanyam if (!is_group_owner) { 489*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 490*9c381f59SAmarnath Hullur Subramanyam "Waiting to start dhcp client"); 491*9c381f59SAmarnath Hullur Subramanyam sleep(5); /* Wait for IP */ 492*9c381f59SAmarnath Hullur Subramanyam miracast_start_dhcp_client(dut, output_ifname); 493*9c381f59SAmarnath Hullur Subramanyam sleep(5); /* Wait for IP */ 494*9c381f59SAmarnath Hullur Subramanyam if (get_peer_ip_p2p_client(dut, peer_ip_address, output_ifname, 495*9c381f59SAmarnath Hullur Subramanyam wait_limit) < 0) { 496*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, 497*9c381f59SAmarnath Hullur Subramanyam "Could not get peer IP"); 498*9c381f59SAmarnath Hullur Subramanyam goto EXIT; 499*9c381f59SAmarnath Hullur Subramanyam } 500*9c381f59SAmarnath Hullur Subramanyam } else { 501*9c381f59SAmarnath Hullur Subramanyam stop_dhcp(dut, output_ifname, 1); 502*9c381f59SAmarnath Hullur Subramanyam /* For GO read the DHCP Lease File */ 503*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 504*9c381f59SAmarnath Hullur Subramanyam "Waiting to start dhcp server"); 505*9c381f59SAmarnath Hullur Subramanyam start_dhcp(dut, output_ifname, 1); 506*9c381f59SAmarnath Hullur Subramanyam sleep(5); 507*9c381f59SAmarnath Hullur Subramanyam if (get_peer_ip_p2p_go(dut, peer_ip_address, 508*9c381f59SAmarnath Hullur Subramanyam dut->peer_mac_address, wait_limit) < 0) { 509*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, 510*9c381f59SAmarnath Hullur Subramanyam "Could not get peer IP"); 511*9c381f59SAmarnath Hullur Subramanyam goto EXIT; 512*9c381f59SAmarnath Hullur Subramanyam } 513*9c381f59SAmarnath Hullur Subramanyam } 514*9c381f59SAmarnath Hullur Subramanyam 515*9c381f59SAmarnath Hullur Subramanyam extn_start_wfd_connection = dlsym(dut->miracast_lib, 516*9c381f59SAmarnath Hullur Subramanyam "start_wfd_connection"); 517*9c381f59SAmarnath Hullur Subramanyam if (extn_start_wfd_connection) { 518*9c381f59SAmarnath Hullur Subramanyam extn_start_wfd_connection(NULL, peer_ip_address, 519*9c381f59SAmarnath Hullur Subramanyam session_management_control_port, 520*9c381f59SAmarnath Hullur Subramanyam 1 - dut->wfd_device_type, 521*9c381f59SAmarnath Hullur Subramanyam rtsp_session_id); 522*9c381f59SAmarnath Hullur Subramanyam } else { 523*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 524*9c381f59SAmarnath Hullur Subramanyam "dlsym seems to have error %p %p", 525*9c381f59SAmarnath Hullur Subramanyam dut->miracast_lib, extn_start_wfd_connection); 526*9c381f59SAmarnath Hullur Subramanyam } 527*9c381f59SAmarnath Hullur Subramanyam 528*9c381f59SAmarnath Hullur Subramanyam EXIT: 529*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "Reached Miracast thread exit"); 530*9c381f59SAmarnath Hullur Subramanyam 531*9c381f59SAmarnath Hullur Subramanyam return NULL; 532*9c381f59SAmarnath Hullur Subramanyam } 533*9c381f59SAmarnath Hullur Subramanyam 534*9c381f59SAmarnath Hullur Subramanyam 535*9c381f59SAmarnath Hullur Subramanyam /*---------------------------------------------------------------------- 536*9c381f59SAmarnath Hullur Subramanyam WFD Source IE: 000601101c440036 537*9c381f59SAmarnath Hullur Subramanyam len WFD device info control port throughput 538*9c381f59SAmarnath Hullur Subramanyam 110] [00000 00100010 000] [00011 10001000 100] [00000 00000110 110] 539*9c381f59SAmarnath Hullur Subramanyam = 7236 540*9c381f59SAmarnath Hullur Subramanyam 541*9c381f59SAmarnath Hullur Subramanyam WFD Sink IE: 000601511c440036 542*9c381f59SAmarnath Hullur Subramanyam len WFD device info control port throughput 543*9c381f59SAmarnath Hullur Subramanyam 110] [00000 00101010 001] [00011 10001000 100] [00000 00000110 110] 544*9c381f59SAmarnath Hullur Subramanyam = 7236 545*9c381f59SAmarnath Hullur Subramanyam 546*9c381f59SAmarnath Hullur Subramanyam WFD device info: 547*9c381f59SAmarnath Hullur Subramanyam BITS NAME DESCRIPTION 548*9c381f59SAmarnath Hullur Subramanyam ------------------------------------------- 549*9c381f59SAmarnath Hullur Subramanyam 1:0 WFD Device Type 0b00: WFD Source 550*9c381f59SAmarnath Hullur Subramanyam 0b01: Primary Sink 551*9c381f59SAmarnath Hullur Subramanyam 0b10: Secondary Sink 552*9c381f59SAmarnath Hullur Subramanyam 0b11: Dual Role, either WFD Source/Primary sink 553*9c381f59SAmarnath Hullur Subramanyam 554*9c381f59SAmarnath Hullur Subramanyam 5:4 WFD Session 0b00: Not available for WFD Session 555*9c381f59SAmarnath Hullur Subramanyam Availibility 0b01: Available for WFD Session 556*9c381f59SAmarnath Hullur Subramanyam 0b10, 0b11: Reserved 557*9c381f59SAmarnath Hullur Subramanyam 558*9c381f59SAmarnath Hullur Subramanyam 6 WSD Support Bit 0b0: WFD Service Discovery not supported 559*9c381f59SAmarnath Hullur Subramanyam 0b1: WFD Service Discovery supported 560*9c381f59SAmarnath Hullur Subramanyam 561*9c381f59SAmarnath Hullur Subramanyam 8 CP Support Bit 0b0: Content Protection via HDCP not supported 562*9c381f59SAmarnath Hullur Subramanyam 0b1: Content Protection via HDCP supported 563*9c381f59SAmarnath Hullur Subramanyam --------------------------------------------------------------------------- 564*9c381f59SAmarnath Hullur Subramanyam */ 565*9c381f59SAmarnath Hullur Subramanyam 566*9c381f59SAmarnath Hullur Subramanyam static void miracast_set_wfd_ie(struct sigma_dut *sigma_dut) 567*9c381f59SAmarnath Hullur Subramanyam { 568*9c381f59SAmarnath Hullur Subramanyam char *intf = sigma_station_ifname; 569*9c381f59SAmarnath Hullur Subramanyam 570*9c381f59SAmarnath Hullur Subramanyam if (sigma_main_ifname != NULL) 571*9c381f59SAmarnath Hullur Subramanyam intf = sigma_main_ifname; 572*9c381f59SAmarnath Hullur Subramanyam 573*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(sigma_dut, DUT_MSG_DEBUG, "miracast_set_wfd_ie() = intf = %s", 574*9c381f59SAmarnath Hullur Subramanyam intf); 575*9c381f59SAmarnath Hullur Subramanyam wpa_command(intf, "SET wifi_display 1"); 576*9c381f59SAmarnath Hullur Subramanyam 577*9c381f59SAmarnath Hullur Subramanyam if (sigma_dut->wfd_device_type == 0) { 578*9c381f59SAmarnath Hullur Subramanyam wpa_command(intf, "WFD_SUBELEM_SET 0 000601101c440036"); 579*9c381f59SAmarnath Hullur Subramanyam wpa_command(intf, "WFD_SUBELEM_SET 11 00020000"); 580*9c381f59SAmarnath Hullur Subramanyam } else { 581*9c381f59SAmarnath Hullur Subramanyam wpa_command(intf, "WFD_SUBELEM_SET 0 000601511c440036"); 582*9c381f59SAmarnath Hullur Subramanyam wpa_command(intf, "WFD_SUBELEM_SET 11 00020001"); 583*9c381f59SAmarnath Hullur Subramanyam } 584*9c381f59SAmarnath Hullur Subramanyam } 585*9c381f59SAmarnath Hullur Subramanyam 586*9c381f59SAmarnath Hullur Subramanyam 587*9c381f59SAmarnath Hullur Subramanyam void miracast_init(struct sigma_dut *dut) 588*9c381f59SAmarnath Hullur Subramanyam { 589*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "Create thread pool for VDS"); 590*9c381f59SAmarnath Hullur Subramanyam miracast_set_wfd_ie(dut); 591*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "Clear groupID @ start"); 592*9c381f59SAmarnath Hullur Subramanyam } 593*9c381f59SAmarnath Hullur Subramanyam 594*9c381f59SAmarnath Hullur Subramanyam 595*9c381f59SAmarnath Hullur Subramanyam void miracast_deinit(struct sigma_dut *dut) 596*9c381f59SAmarnath Hullur Subramanyam { 597*9c381f59SAmarnath Hullur Subramanyam (void) miracast_unload(dut); 598*9c381f59SAmarnath Hullur Subramanyam } 599*9c381f59SAmarnath Hullur Subramanyam 600*9c381f59SAmarnath Hullur Subramanyam 601*9c381f59SAmarnath Hullur Subramanyam static void miracast_generate_string_cmd(struct sigma_cmd *cmd, char *strcmd, 602*9c381f59SAmarnath Hullur Subramanyam size_t size) 603*9c381f59SAmarnath Hullur Subramanyam { 604*9c381f59SAmarnath Hullur Subramanyam int i = 0; 605*9c381f59SAmarnath Hullur Subramanyam char *pos, *end; 606*9c381f59SAmarnath Hullur Subramanyam int ret; 607*9c381f59SAmarnath Hullur Subramanyam 608*9c381f59SAmarnath Hullur Subramanyam if (!strcmd) 609*9c381f59SAmarnath Hullur Subramanyam return; 610*9c381f59SAmarnath Hullur Subramanyam strcmd[0] = '\0'; 611*9c381f59SAmarnath Hullur Subramanyam pos = strcmd; 612*9c381f59SAmarnath Hullur Subramanyam end = strcmd + size; 613*9c381f59SAmarnath Hullur Subramanyam for (i = 0; i < cmd->count; i++) { 614*9c381f59SAmarnath Hullur Subramanyam ret = snprintf(pos, end - pos, "%s,%s,", cmd->params[i], 615*9c381f59SAmarnath Hullur Subramanyam cmd->values[i]); 616*9c381f59SAmarnath Hullur Subramanyam if (ret < 0 || ret < end - pos) 617*9c381f59SAmarnath Hullur Subramanyam break; 618*9c381f59SAmarnath Hullur Subramanyam pos += ret; 619*9c381f59SAmarnath Hullur Subramanyam } 620*9c381f59SAmarnath Hullur Subramanyam 621*9c381f59SAmarnath Hullur Subramanyam pos = strrchr(strcmd, ','); 622*9c381f59SAmarnath Hullur Subramanyam if (pos) 623*9c381f59SAmarnath Hullur Subramanyam *pos = '\0'; 624*9c381f59SAmarnath Hullur Subramanyam printf("Miracast: generated command: %s\n", strcmd); 625*9c381f59SAmarnath Hullur Subramanyam } 626*9c381f59SAmarnath Hullur Subramanyam 627*9c381f59SAmarnath Hullur Subramanyam 628*9c381f59SAmarnath Hullur Subramanyam static void * auto_go_thread_entry(void *ptr) 629*9c381f59SAmarnath Hullur Subramanyam { 630*9c381f59SAmarnath Hullur Subramanyam struct sigma_dut *dut = ptr; 631*9c381f59SAmarnath Hullur Subramanyam struct wpa_ctrl *ctrl; 632*9c381f59SAmarnath Hullur Subramanyam char event_buf[64]; 633*9c381f59SAmarnath Hullur Subramanyam char *peer = NULL; 634*9c381f59SAmarnath Hullur Subramanyam int res = 0; 635*9c381f59SAmarnath Hullur Subramanyam char macaddress[32]; 636*9c381f59SAmarnath Hullur Subramanyam char peer_ip_address[32]; 637*9c381f59SAmarnath Hullur Subramanyam char rtsp_session_id[12]; 638*9c381f59SAmarnath Hullur Subramanyam int (*extn_start_wfd_connection)(const char *, 639*9c381f59SAmarnath Hullur Subramanyam const char *, /* Peer IP */ 640*9c381f59SAmarnath Hullur Subramanyam int, /* RTSP port number */ 641*9c381f59SAmarnath Hullur Subramanyam int, /* WFD Device Type; 0-Source, 642*9c381f59SAmarnath Hullur Subramanyam 1-P-Sink, 2-Secondary Sink */ 643*9c381f59SAmarnath Hullur Subramanyam char *); /* for returning session ID */ 644*9c381f59SAmarnath Hullur Subramanyam 645*9c381f59SAmarnath Hullur Subramanyam if (!dut) { 646*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, 647*9c381f59SAmarnath Hullur Subramanyam "Bail out, RTSP thread has invalid parameters"); 648*9c381f59SAmarnath Hullur Subramanyam goto THR_EXIT; 649*9c381f59SAmarnath Hullur Subramanyam } 650*9c381f59SAmarnath Hullur Subramanyam stop_dhcp(dut, wfd_ifname, 1); 651*9c381f59SAmarnath Hullur Subramanyam /* For auto-GO, start the DHCP server and wait for 5 seconds */ 652*9c381f59SAmarnath Hullur Subramanyam start_dhcp(dut, wfd_ifname, 1); 653*9c381f59SAmarnath Hullur Subramanyam sleep(5); /* Wait for IP */ 654*9c381f59SAmarnath Hullur Subramanyam 655*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "Wait for AP-STA-CONNECTED"); 656*9c381f59SAmarnath Hullur Subramanyam ctrl = open_wpa_mon(wfd_ifname); /* Refer to wfd_ifname */ 657*9c381f59SAmarnath Hullur Subramanyam if (!ctrl) { 658*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, 659*9c381f59SAmarnath Hullur Subramanyam "Failed to open wpa_supplicant monitor connection"); 660*9c381f59SAmarnath Hullur Subramanyam goto THR_EXIT; 661*9c381f59SAmarnath Hullur Subramanyam } 662*9c381f59SAmarnath Hullur Subramanyam res = get_wpa_cli_event(dut, ctrl, "AP-STA-CONNECTED", 663*9c381f59SAmarnath Hullur Subramanyam event_buf, sizeof(event_buf)); 664*9c381f59SAmarnath Hullur Subramanyam wpa_ctrl_detach(ctrl); 665*9c381f59SAmarnath Hullur Subramanyam wpa_ctrl_close(ctrl); 666*9c381f59SAmarnath Hullur Subramanyam 667*9c381f59SAmarnath Hullur Subramanyam if (res < 0) { 668*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, 669*9c381f59SAmarnath Hullur Subramanyam "Could not get event before timeout"); 670*9c381f59SAmarnath Hullur Subramanyam goto THR_EXIT; 671*9c381f59SAmarnath Hullur Subramanyam } 672*9c381f59SAmarnath Hullur Subramanyam 673*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "STA Connected Event: '%s'", 674*9c381f59SAmarnath Hullur Subramanyam event_buf); 675*9c381f59SAmarnath Hullur Subramanyam peer = strchr(event_buf, ' '); 676*9c381f59SAmarnath Hullur Subramanyam if (!peer) { 677*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, "Could not find STA MAC"); 678*9c381f59SAmarnath Hullur Subramanyam goto THR_EXIT; 679*9c381f59SAmarnath Hullur Subramanyam } 680*9c381f59SAmarnath Hullur Subramanyam 681*9c381f59SAmarnath Hullur Subramanyam peer++; 682*9c381f59SAmarnath Hullur Subramanyam strncpy(macaddress, peer, 17 /* Size of MAC */); 683*9c381f59SAmarnath Hullur Subramanyam macaddress[17] = '\0'; 684*9c381f59SAmarnath Hullur Subramanyam if (get_peer_ip_p2p_go(dut, peer_ip_address, macaddress, 30) < 0) { 685*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, "Could not get peer IP"); 686*9c381f59SAmarnath Hullur Subramanyam goto THR_EXIT; 687*9c381f59SAmarnath Hullur Subramanyam } 688*9c381f59SAmarnath Hullur Subramanyam 689*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "dlsym %p", dut->miracast_lib); 690*9c381f59SAmarnath Hullur Subramanyam extn_start_wfd_connection = dlsym(dut->miracast_lib, 691*9c381f59SAmarnath Hullur Subramanyam "start_wfd_connection"); 692*9c381f59SAmarnath Hullur Subramanyam if (!extn_start_wfd_connection) 693*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "dlsym function NULL"); 694*9c381f59SAmarnath Hullur Subramanyam else 695*9c381f59SAmarnath Hullur Subramanyam extn_start_wfd_connection(NULL, peer_ip_address, 696*9c381f59SAmarnath Hullur Subramanyam session_management_control_port, 697*9c381f59SAmarnath Hullur Subramanyam 1 - dut->wfd_device_type, 698*9c381f59SAmarnath Hullur Subramanyam rtsp_session_id); 699*9c381f59SAmarnath Hullur Subramanyam 700*9c381f59SAmarnath Hullur Subramanyam THR_EXIT: 701*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "Reached auto GO thread exit"); 702*9c381f59SAmarnath Hullur Subramanyam return NULL; 703*9c381f59SAmarnath Hullur Subramanyam } 704*9c381f59SAmarnath Hullur Subramanyam 705*9c381f59SAmarnath Hullur Subramanyam 706*9c381f59SAmarnath Hullur Subramanyam void miracast_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn, 707*9c381f59SAmarnath Hullur Subramanyam struct sigma_cmd *cmd) 708*9c381f59SAmarnath Hullur Subramanyam { 709*9c381f59SAmarnath Hullur Subramanyam char *intf = sigma_station_ifname; 710*9c381f59SAmarnath Hullur Subramanyam int (*extn_sta_reset_default)(char *); 711*9c381f59SAmarnath Hullur Subramanyam char string_cmd[MIRACAST_CMD_LEN] = { 0 }; 712*9c381f59SAmarnath Hullur Subramanyam 713*9c381f59SAmarnath Hullur Subramanyam if (sigma_main_ifname != NULL) 714*9c381f59SAmarnath Hullur Subramanyam intf = sigma_main_ifname; 715*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, 716*9c381f59SAmarnath Hullur Subramanyam "miracast_sta_reset_default() = intf = %s", intf); 717*9c381f59SAmarnath Hullur Subramanyam stop_dhcp(dut, intf, 1); /* IFNAME argument is ignored */ 718*9c381f59SAmarnath Hullur Subramanyam miracast_stop_dhcp_client(dut, intf); 719*9c381f59SAmarnath Hullur Subramanyam 720*9c381f59SAmarnath Hullur Subramanyam /* This is where vendor Miracast library is loaded and function pointers 721*9c381f59SAmarnath Hullur Subramanyam * to Miracast functions (defined by CAPI) are loaded. */ 722*9c381f59SAmarnath Hullur Subramanyam 723*9c381f59SAmarnath Hullur Subramanyam if (miracast_load(dut) != 0) { 724*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 725*9c381f59SAmarnath Hullur Subramanyam "Fail to load Miracast library"); 726*9c381f59SAmarnath Hullur Subramanyam return; 727*9c381f59SAmarnath Hullur Subramanyam } 728*9c381f59SAmarnath Hullur Subramanyam 729*9c381f59SAmarnath Hullur Subramanyam if (!dut->miracast_lib) { 730*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, 731*9c381f59SAmarnath Hullur Subramanyam "Miracast library is absent"); 732*9c381f59SAmarnath Hullur Subramanyam return; 733*9c381f59SAmarnath Hullur Subramanyam } 734*9c381f59SAmarnath Hullur Subramanyam 735*9c381f59SAmarnath Hullur Subramanyam dlerror(); 736*9c381f59SAmarnath Hullur Subramanyam 737*9c381f59SAmarnath Hullur Subramanyam miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd)); 738*9c381f59SAmarnath Hullur Subramanyam extn_sta_reset_default = dlsym(dut->miracast_lib, "sta_reset_default"); 739*9c381f59SAmarnath Hullur Subramanyam if (extn_sta_reset_default) 740*9c381f59SAmarnath Hullur Subramanyam extn_sta_reset_default(string_cmd); 741*9c381f59SAmarnath Hullur Subramanyam 742*9c381f59SAmarnath Hullur Subramanyam /* delete threads if any */ 743*9c381f59SAmarnath Hullur Subramanyam /* TODO: if dut->rtsp_thread_handle running, call 744*9c381f59SAmarnath Hullur Subramanyam * miracast_release_rtsp_thread_resources(dut); */ 745*9c381f59SAmarnath Hullur Subramanyam } 746*9c381f59SAmarnath Hullur Subramanyam 747*9c381f59SAmarnath Hullur Subramanyam 748*9c381f59SAmarnath Hullur Subramanyam void miracast_start_autonomous_go(struct sigma_dut *dut, 749*9c381f59SAmarnath Hullur Subramanyam struct sigma_conn *conn, 750*9c381f59SAmarnath Hullur Subramanyam struct sigma_cmd *cmd, char *ifname) 751*9c381f59SAmarnath Hullur Subramanyam { 752*9c381f59SAmarnath Hullur Subramanyam strlcpy(wfd_ifname, ifname, sizeof(wfd_ifname)); 753*9c381f59SAmarnath Hullur Subramanyam (void) pthread_create(&dut->rtsp_thread_handle, NULL, 754*9c381f59SAmarnath Hullur Subramanyam auto_go_thread_entry, dut); 755*9c381f59SAmarnath Hullur Subramanyam } 756*9c381f59SAmarnath Hullur Subramanyam 757*9c381f59SAmarnath Hullur Subramanyam 758*9c381f59SAmarnath Hullur Subramanyam static void miracast_rtsp_thread_create(struct sigma_dut *dut, 759*9c381f59SAmarnath Hullur Subramanyam struct sigma_conn *conn, 760*9c381f59SAmarnath Hullur Subramanyam struct sigma_cmd *cmd) 761*9c381f59SAmarnath Hullur Subramanyam { 762*9c381f59SAmarnath Hullur Subramanyam (void) pthread_create(&dut->rtsp_thread_handle, NULL, 763*9c381f59SAmarnath Hullur Subramanyam miracast_rtsp_thread_entry, dut); 764*9c381f59SAmarnath Hullur Subramanyam } 765*9c381f59SAmarnath Hullur Subramanyam 766*9c381f59SAmarnath Hullur Subramanyam 767*9c381f59SAmarnath Hullur Subramanyam int miracast_dev_send_frame(struct sigma_dut *dut, struct sigma_conn *conn, 768*9c381f59SAmarnath Hullur Subramanyam struct sigma_cmd *cmd) 769*9c381f59SAmarnath Hullur Subramanyam { 770*9c381f59SAmarnath Hullur Subramanyam const char *frame_name = get_param(cmd, "FrameName"); 771*9c381f59SAmarnath Hullur Subramanyam /* const char *source = get_param(cmd, "Source"); */ 772*9c381f59SAmarnath Hullur Subramanyam /* const char *destination = get_param(cmd, "Destination"); */ 773*9c381f59SAmarnath Hullur Subramanyam /* const char *dev_type = get_param(cmd, "DevType"); */ 774*9c381f59SAmarnath Hullur Subramanyam const char *rtsp_msg_type = get_param(cmd, "RtspMsgType"); 775*9c381f59SAmarnath Hullur Subramanyam /* const char *wfd_session_id = get_param(cmd, "WfdSessionID"); */ 776*9c381f59SAmarnath Hullur Subramanyam int (*dev_send_frame)(const char *); 777*9c381f59SAmarnath Hullur Subramanyam char string_cmd[MIRACAST_CMD_LEN] = { 0 }; 778*9c381f59SAmarnath Hullur Subramanyam 779*9c381f59SAmarnath Hullur Subramanyam dev_send_frame = dlsym(dut->miracast_lib, "dev_send_frame"); 780*9c381f59SAmarnath Hullur Subramanyam if (!dev_send_frame) 781*9c381f59SAmarnath Hullur Subramanyam return -1; 782*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "miracast_dev_send_frame 1"); 783*9c381f59SAmarnath Hullur Subramanyam miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd)); 784*9c381f59SAmarnath Hullur Subramanyam if (strcasecmp(frame_name, "RTSP") != 0) 785*9c381f59SAmarnath Hullur Subramanyam return 0; 786*9c381f59SAmarnath Hullur Subramanyam 787*9c381f59SAmarnath Hullur Subramanyam if (strcasecmp(rtsp_msg_type, "PAUSE") == 0 || 788*9c381f59SAmarnath Hullur Subramanyam strcasecmp(rtsp_msg_type, "TRIGGER-PAUSE") == 0) { 789*9c381f59SAmarnath Hullur Subramanyam /* Call RTSP Pause */ 790*9c381f59SAmarnath Hullur Subramanyam dev_send_frame(string_cmd); 791*9c381f59SAmarnath Hullur Subramanyam return 1; 792*9c381f59SAmarnath Hullur Subramanyam } 793*9c381f59SAmarnath Hullur Subramanyam 794*9c381f59SAmarnath Hullur Subramanyam if (strcasecmp(rtsp_msg_type, "PLAY") == 0 || 795*9c381f59SAmarnath Hullur Subramanyam strcasecmp(rtsp_msg_type, "TRIGGER-PLAY") == 0) { 796*9c381f59SAmarnath Hullur Subramanyam /* Call RTSP Play */; 797*9c381f59SAmarnath Hullur Subramanyam dev_send_frame(string_cmd); /* Not for secure playback */ 798*9c381f59SAmarnath Hullur Subramanyam return 1; 799*9c381f59SAmarnath Hullur Subramanyam } 800*9c381f59SAmarnath Hullur Subramanyam 801*9c381f59SAmarnath Hullur Subramanyam if (strcasecmp(rtsp_msg_type, "TEARDOWN") == 0 || 802*9c381f59SAmarnath Hullur Subramanyam strcasecmp(rtsp_msg_type, "TRIGGER-TEARDOWN") == 0) { 803*9c381f59SAmarnath Hullur Subramanyam dev_send_frame(string_cmd); /* RTSP Teardown */ 804*9c381f59SAmarnath Hullur Subramanyam return 1; 805*9c381f59SAmarnath Hullur Subramanyam } 806*9c381f59SAmarnath Hullur Subramanyam 807*9c381f59SAmarnath Hullur Subramanyam if (strcasecmp(rtsp_msg_type,"SET_PARAMETER") == 0) { 808*9c381f59SAmarnath Hullur Subramanyam const char *set_parameter = get_param(cmd, "SetParameter"); 809*9c381f59SAmarnath Hullur Subramanyam const char *transportType = get_param(cmd, "TransportType"); 810*9c381f59SAmarnath Hullur Subramanyam 811*9c381f59SAmarnath Hullur Subramanyam if (set_parameter == NULL && transportType == NULL) { 812*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 813*9c381f59SAmarnath Hullur Subramanyam "errorCode,Invalid Set Parameter value"); 814*9c381f59SAmarnath Hullur Subramanyam return 0; 815*9c381f59SAmarnath Hullur Subramanyam } 816*9c381f59SAmarnath Hullur Subramanyam 817*9c381f59SAmarnath Hullur Subramanyam if (1) /* (strcasecmp(set_parameter, "Standby") == 0) */ { 818*9c381f59SAmarnath Hullur Subramanyam dev_send_frame(string_cmd); 819*9c381f59SAmarnath Hullur Subramanyam return 1; 820*9c381f59SAmarnath Hullur Subramanyam } 821*9c381f59SAmarnath Hullur Subramanyam /* TODO More needs to be implemented when the spec is clearer */ 822*9c381f59SAmarnath Hullur Subramanyam return 1; 823*9c381f59SAmarnath Hullur Subramanyam } 824*9c381f59SAmarnath Hullur Subramanyam 825*9c381f59SAmarnath Hullur Subramanyam if (strcasecmp(rtsp_msg_type, "SETUP") == 0) { 826*9c381f59SAmarnath Hullur Subramanyam dev_send_frame(string_cmd); 827*9c381f59SAmarnath Hullur Subramanyam /* TODO More needs to be implemented when the spec is clearer */ 828*9c381f59SAmarnath Hullur Subramanyam return 1; 829*9c381f59SAmarnath Hullur Subramanyam } 830*9c381f59SAmarnath Hullur Subramanyam 831*9c381f59SAmarnath Hullur Subramanyam if (strcasecmp(frame_name, "WFD_ProbeReq") == 0) { 832*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 833*9c381f59SAmarnath Hullur Subramanyam "errorCode,Unsupported WFD Probe Request"); 834*9c381f59SAmarnath Hullur Subramanyam return 0; 835*9c381f59SAmarnath Hullur Subramanyam } 836*9c381f59SAmarnath Hullur Subramanyam 837*9c381f59SAmarnath Hullur Subramanyam if (strcasecmp(frame_name, "WFD_ServiceDiscReq") == 0) { 838*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 839*9c381f59SAmarnath Hullur Subramanyam "errorCode,Unsupported WFD Service Discovery"); 840*9c381f59SAmarnath Hullur Subramanyam return 0; 841*9c381f59SAmarnath Hullur Subramanyam } 842*9c381f59SAmarnath Hullur Subramanyam 843*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 844*9c381f59SAmarnath Hullur Subramanyam "errorCode,Unsupported dev_send_frame"); 845*9c381f59SAmarnath Hullur Subramanyam return 0; 846*9c381f59SAmarnath Hullur Subramanyam } 847*9c381f59SAmarnath Hullur Subramanyam 848*9c381f59SAmarnath Hullur Subramanyam 849*9c381f59SAmarnath Hullur Subramanyam int miracast_dev_exec_action(struct sigma_dut *dut, struct sigma_conn *conn, 850*9c381f59SAmarnath Hullur Subramanyam struct sigma_cmd *cmd) 851*9c381f59SAmarnath Hullur Subramanyam { 852*9c381f59SAmarnath Hullur Subramanyam const char *service_type = get_param(cmd,"ServiceType"); 853*9c381f59SAmarnath Hullur Subramanyam int (*dev_exec_action)(const char *); 854*9c381f59SAmarnath Hullur Subramanyam char string_cmd[MIRACAST_CMD_LEN] = { 0 }; 855*9c381f59SAmarnath Hullur Subramanyam 856*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "miracast_dev_exec_frame"); 857*9c381f59SAmarnath Hullur Subramanyam 858*9c381f59SAmarnath Hullur Subramanyam if (service_type) { 859*9c381f59SAmarnath Hullur Subramanyam char resp_buf[128]; 860*9c381f59SAmarnath Hullur Subramanyam 861*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "MDNS Instance Name = %s", 862*9c381f59SAmarnath Hullur Subramanyam dut->mdns_instance_name); 863*9c381f59SAmarnath Hullur Subramanyam strlcpy(resp_buf, "InstanceName,", sizeof(resp_buf)); 864*9c381f59SAmarnath Hullur Subramanyam strlcat(resp_buf + strlen(resp_buf), dut->mdns_instance_name, 865*9c381f59SAmarnath Hullur Subramanyam sizeof(resp_buf) - strlen(resp_buf)); 866*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_COMPLETE, resp_buf); 867*9c381f59SAmarnath Hullur Subramanyam return 0; 868*9c381f59SAmarnath Hullur Subramanyam } 869*9c381f59SAmarnath Hullur Subramanyam 870*9c381f59SAmarnath Hullur Subramanyam miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd)); 871*9c381f59SAmarnath Hullur Subramanyam dev_exec_action = dlsym(dut->miracast_lib, "dev_exec_action"); 872*9c381f59SAmarnath Hullur Subramanyam if (!dev_exec_action) 873*9c381f59SAmarnath Hullur Subramanyam return -2; 874*9c381f59SAmarnath Hullur Subramanyam return dev_exec_action(string_cmd); 875*9c381f59SAmarnath Hullur Subramanyam } 876*9c381f59SAmarnath Hullur Subramanyam 877*9c381f59SAmarnath Hullur Subramanyam 878*9c381f59SAmarnath Hullur Subramanyam int miracast_preset_testparameters(struct sigma_dut *dut, 879*9c381f59SAmarnath Hullur Subramanyam struct sigma_conn *conn, 880*9c381f59SAmarnath Hullur Subramanyam struct sigma_cmd *cmd) 881*9c381f59SAmarnath Hullur Subramanyam { 882*9c381f59SAmarnath Hullur Subramanyam const char *mdns_disc = get_param(cmd, "mdns_disc"); 883*9c381f59SAmarnath Hullur Subramanyam const char *mdns_role = get_param(cmd, "mdns_role"); 884*9c381f59SAmarnath Hullur Subramanyam char string_cmd[MIRACAST_CMD_LEN]; 885*9c381f59SAmarnath Hullur Subramanyam int ret = 0; 886*9c381f59SAmarnath Hullur Subramanyam char string_resp[64] = { 0 }; 887*9c381f59SAmarnath Hullur Subramanyam int (*extn_sta_preset_test_parameter)(const char *, char *, int); 888*9c381f59SAmarnath Hullur Subramanyam 889*9c381f59SAmarnath Hullur Subramanyam miracast_load(dut); 890*9c381f59SAmarnath Hullur Subramanyam miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd)); 891*9c381f59SAmarnath Hullur Subramanyam extn_sta_preset_test_parameter = 892*9c381f59SAmarnath Hullur Subramanyam dlsym(dut->miracast_lib, "sta_preset_testparameters"); 893*9c381f59SAmarnath Hullur Subramanyam if (!extn_sta_preset_test_parameter) 894*9c381f59SAmarnath Hullur Subramanyam return -1; 895*9c381f59SAmarnath Hullur Subramanyam ret = extn_sta_preset_test_parameter(string_cmd, string_resp, 896*9c381f59SAmarnath Hullur Subramanyam sizeof(string_resp)); 897*9c381f59SAmarnath Hullur Subramanyam if (ret == SIGMA_ERROR) { 898*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 899*9c381f59SAmarnath Hullur Subramanyam "Miracast extension reported error in the command sta_preset_testparameters"); 900*9c381f59SAmarnath Hullur Subramanyam return 0; 901*9c381f59SAmarnath Hullur Subramanyam } 902*9c381f59SAmarnath Hullur Subramanyam 903*9c381f59SAmarnath Hullur Subramanyam if (mdns_disc && mdns_role) { 904*9c381f59SAmarnath Hullur Subramanyam if (strlen(string_resp)) 905*9c381f59SAmarnath Hullur Subramanyam strlcpy(dut->mdns_instance_name, string_resp, 906*9c381f59SAmarnath Hullur Subramanyam sizeof(dut->mdns_instance_name)); 907*9c381f59SAmarnath Hullur Subramanyam else 908*9c381f59SAmarnath Hullur Subramanyam dut->mdns_instance_name[0] = '\0'; 909*9c381f59SAmarnath Hullur Subramanyam } 910*9c381f59SAmarnath Hullur Subramanyam 911*9c381f59SAmarnath Hullur Subramanyam return 1; 912*9c381f59SAmarnath Hullur Subramanyam } 913*9c381f59SAmarnath Hullur Subramanyam 914*9c381f59SAmarnath Hullur Subramanyam 915*9c381f59SAmarnath Hullur Subramanyam static int get_p2p_peers(char *respbuf, size_t bufsize) 916*9c381f59SAmarnath Hullur Subramanyam { 917*9c381f59SAmarnath Hullur Subramanyam char addr[1024], cmd[64]; 918*9c381f59SAmarnath Hullur Subramanyam char *intf = get_main_ifname(); 919*9c381f59SAmarnath Hullur Subramanyam int ret; 920*9c381f59SAmarnath Hullur Subramanyam char *pos, *end; 921*9c381f59SAmarnath Hullur Subramanyam 922*9c381f59SAmarnath Hullur Subramanyam pos = respbuf; 923*9c381f59SAmarnath Hullur Subramanyam end = respbuf + bufsize; 924*9c381f59SAmarnath Hullur Subramanyam 925*9c381f59SAmarnath Hullur Subramanyam if (wpa_command_resp(intf, "P2P_PEER FIRST", addr, 128) >= 0) { 926*9c381f59SAmarnath Hullur Subramanyam strlcpy(respbuf, addr, bufsize); 927*9c381f59SAmarnath Hullur Subramanyam respbuf[17] = '\0'; 928*9c381f59SAmarnath Hullur Subramanyam addr[17] = '\0'; 929*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr); 930*9c381f59SAmarnath Hullur Subramanyam memset(addr, 0, sizeof(addr)); 931*9c381f59SAmarnath Hullur Subramanyam while (wpa_command_resp(intf, cmd, addr, sizeof(addr)) >= 0) { 932*9c381f59SAmarnath Hullur Subramanyam if (memcmp(addr, "FAIL", 4) == 0) 933*9c381f59SAmarnath Hullur Subramanyam break; 934*9c381f59SAmarnath Hullur Subramanyam addr[17] = '\0'; 935*9c381f59SAmarnath Hullur Subramanyam ret = snprintf(pos, end - pos, " %s", addr); 936*9c381f59SAmarnath Hullur Subramanyam if (ret < 0 || ret >= end - pos) 937*9c381f59SAmarnath Hullur Subramanyam break; 938*9c381f59SAmarnath Hullur Subramanyam pos += ret; 939*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr); 940*9c381f59SAmarnath Hullur Subramanyam memset(addr, 0, sizeof(addr)); 941*9c381f59SAmarnath Hullur Subramanyam } 942*9c381f59SAmarnath Hullur Subramanyam } 943*9c381f59SAmarnath Hullur Subramanyam 944*9c381f59SAmarnath Hullur Subramanyam return 0; 945*9c381f59SAmarnath Hullur Subramanyam } 946*9c381f59SAmarnath Hullur Subramanyam 947*9c381f59SAmarnath Hullur Subramanyam 948*9c381f59SAmarnath Hullur Subramanyam int miracast_cmd_sta_get_parameter(struct sigma_dut *dut, 949*9c381f59SAmarnath Hullur Subramanyam struct sigma_conn *conn, 950*9c381f59SAmarnath Hullur Subramanyam struct sigma_cmd *cmd) 951*9c381f59SAmarnath Hullur Subramanyam { 952*9c381f59SAmarnath Hullur Subramanyam /* const char *intf = get_param(cmd, "Interface"); */ 953*9c381f59SAmarnath Hullur Subramanyam /* const char *program = get_param(cmd, "Program"); */ 954*9c381f59SAmarnath Hullur Subramanyam const char *parameter = get_param(cmd, "Parameter"); 955*9c381f59SAmarnath Hullur Subramanyam char resp_buf[1024]; /* may need to change depending on number of peer 956*9c381f59SAmarnath Hullur Subramanyam devices found */ 957*9c381f59SAmarnath Hullur Subramanyam 958*9c381f59SAmarnath Hullur Subramanyam if (!parameter) { 959*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 960*9c381f59SAmarnath Hullur Subramanyam return 0; 961*9c381f59SAmarnath Hullur Subramanyam } 962*9c381f59SAmarnath Hullur Subramanyam 963*9c381f59SAmarnath Hullur Subramanyam if (strcasecmp(parameter, "DiscoveredDevList") == 0) { 964*9c381f59SAmarnath Hullur Subramanyam int len = strlen("DeviceList,"); 965*9c381f59SAmarnath Hullur Subramanyam 966*9c381f59SAmarnath Hullur Subramanyam snprintf(resp_buf, sizeof(resp_buf), "DeviceList,"); 967*9c381f59SAmarnath Hullur Subramanyam get_p2p_peers(resp_buf + len, 1024 - len); 968*9c381f59SAmarnath Hullur Subramanyam } else { 969*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter"); 970*9c381f59SAmarnath Hullur Subramanyam return 0; 971*9c381f59SAmarnath Hullur Subramanyam } 972*9c381f59SAmarnath Hullur Subramanyam 973*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_COMPLETE, resp_buf); 974*9c381f59SAmarnath Hullur Subramanyam return 0; 975*9c381f59SAmarnath Hullur Subramanyam } 976*9c381f59SAmarnath Hullur Subramanyam 977*9c381f59SAmarnath Hullur Subramanyam 978*9c381f59SAmarnath Hullur Subramanyam int miracast_mdns_start_wfd_connection(struct sigma_dut *dut, 979*9c381f59SAmarnath Hullur Subramanyam struct sigma_conn *conn, 980*9c381f59SAmarnath Hullur Subramanyam struct sigma_cmd *cmd) 981*9c381f59SAmarnath Hullur Subramanyam { 982*9c381f59SAmarnath Hullur Subramanyam const char *init_wfd = get_param(cmd, "init_wfd"); 983*9c381f59SAmarnath Hullur Subramanyam int int_init_wfd = -1; 984*9c381f59SAmarnath Hullur Subramanyam char rtsp_session_id[12]; 985*9c381f59SAmarnath Hullur Subramanyam int (*extn_start_wfd_connection)(const char *, 986*9c381f59SAmarnath Hullur Subramanyam const char *, /* Peer IP */ 987*9c381f59SAmarnath Hullur Subramanyam int, /* RTSP port number */ 988*9c381f59SAmarnath Hullur Subramanyam int, /* WFD Device Type; 0-Source, 989*9c381f59SAmarnath Hullur Subramanyam 1-P-Sink, 2-Secondary Sink */ 990*9c381f59SAmarnath Hullur Subramanyam char *); /* for returning session ID */ 991*9c381f59SAmarnath Hullur Subramanyam int count = 0; 992*9c381f59SAmarnath Hullur Subramanyam char *sig_resp = NULL; 993*9c381f59SAmarnath Hullur Subramanyam 994*9c381f59SAmarnath Hullur Subramanyam if (init_wfd) 995*9c381f59SAmarnath Hullur Subramanyam int_init_wfd = atoi(init_wfd); 996*9c381f59SAmarnath Hullur Subramanyam 997*9c381f59SAmarnath Hullur Subramanyam extn_start_wfd_connection = dlsym(dut->miracast_lib, 998*9c381f59SAmarnath Hullur Subramanyam "start_wfd_connection"); 999*9c381f59SAmarnath Hullur Subramanyam if (!extn_start_wfd_connection) 1000*9c381f59SAmarnath Hullur Subramanyam return -1; 1001*9c381f59SAmarnath Hullur Subramanyam rtsp_session_id[0] = '\0'; 1002*9c381f59SAmarnath Hullur Subramanyam if (int_init_wfd != 0) { 1003*9c381f59SAmarnath Hullur Subramanyam extn_start_wfd_connection(NULL, NULL, -100, 1004*9c381f59SAmarnath Hullur Subramanyam 1 - dut->wfd_device_type, 1005*9c381f59SAmarnath Hullur Subramanyam rtsp_session_id); 1006*9c381f59SAmarnath Hullur Subramanyam while (strlen(rtsp_session_id) == 0 && count < 60) { 1007*9c381f59SAmarnath Hullur Subramanyam count++; 1008*9c381f59SAmarnath Hullur Subramanyam sleep(1); 1009*9c381f59SAmarnath Hullur Subramanyam } 1010*9c381f59SAmarnath Hullur Subramanyam if (count == 60) 1011*9c381f59SAmarnath Hullur Subramanyam strlcpy(rtsp_session_id, "-1", 12); 1012*9c381f59SAmarnath Hullur Subramanyam sig_resp = rtsp_session_id; 1013*9c381f59SAmarnath Hullur Subramanyam } else { 1014*9c381f59SAmarnath Hullur Subramanyam extn_start_wfd_connection(NULL, NULL, -100, 1015*9c381f59SAmarnath Hullur Subramanyam 1 - dut->wfd_device_type, NULL); 1016*9c381f59SAmarnath Hullur Subramanyam sig_resp = "result,NULL,GroupID,NULL,WFDSessionID,NULL"; 1017*9c381f59SAmarnath Hullur Subramanyam } 1018*9c381f59SAmarnath Hullur Subramanyam 1019*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_COMPLETE, sig_resp); 1020*9c381f59SAmarnath Hullur Subramanyam return 0; 1021*9c381f59SAmarnath Hullur Subramanyam } 1022*9c381f59SAmarnath Hullur Subramanyam 1023*9c381f59SAmarnath Hullur Subramanyam 1024*9c381f59SAmarnath Hullur Subramanyam static int cmd_start_wfd_connection(struct sigma_dut *dut, 1025*9c381f59SAmarnath Hullur Subramanyam struct sigma_conn *conn, 1026*9c381f59SAmarnath Hullur Subramanyam struct sigma_cmd *cmd) 1027*9c381f59SAmarnath Hullur Subramanyam { 1028*9c381f59SAmarnath Hullur Subramanyam const char *intf = get_param(cmd, "Interface"); 1029*9c381f59SAmarnath Hullur Subramanyam const char *peer_address = get_param(cmd, "PeerAddress"); 1030*9c381f59SAmarnath Hullur Subramanyam const char *init_wfd = get_param(cmd, "init_wfd"); 1031*9c381f59SAmarnath Hullur Subramanyam const char *intent_val = get_param(cmd, "intent_val"); 1032*9c381f59SAmarnath Hullur Subramanyam const char *oper_chan = get_param(cmd, "oper_chn"); 1033*9c381f59SAmarnath Hullur Subramanyam const char *coupled_session = get_param(cmd, "coupledSession"); 1034*9c381f59SAmarnath Hullur Subramanyam const char *tdls = get_param(cmd, "TDLS"); 1035*9c381f59SAmarnath Hullur Subramanyam const char *r2_connection = get_param(cmd, "R2ConnectionType"); 1036*9c381f59SAmarnath Hullur Subramanyam char ssid[128]; 1037*9c381f59SAmarnath Hullur Subramanyam char p2p_dev_address[18]; 1038*9c381f59SAmarnath Hullur Subramanyam char output_intf[16]; 1039*9c381f59SAmarnath Hullur Subramanyam char sig_resp_buf[1024]; 1040*9c381f59SAmarnath Hullur Subramanyam char cmd_buf[256]; /* Command buffer */ 1041*9c381f59SAmarnath Hullur Subramanyam char resp_buf[256]; /* Response buffer to UCC */ 1042*9c381f59SAmarnath Hullur Subramanyam int go_intent = 0; 1043*9c381f59SAmarnath Hullur Subramanyam int freq; 1044*9c381f59SAmarnath Hullur Subramanyam int res = 0; 1045*9c381f59SAmarnath Hullur Subramanyam char buf_peer[4096]; 1046*9c381f59SAmarnath Hullur Subramanyam char *availability = NULL; 1047*9c381f59SAmarnath Hullur Subramanyam char command[64]; 1048*9c381f59SAmarnath Hullur Subramanyam int avail_bit; 1049*9c381f59SAmarnath Hullur Subramanyam char ctemp[2]; 1050*9c381f59SAmarnath Hullur Subramanyam char rtspport[5] = { '7', '2', '3', '6', '\0' }; 1051*9c381f59SAmarnath Hullur Subramanyam int is_group_owner = 0; 1052*9c381f59SAmarnath Hullur Subramanyam char peer_ip_address[32]; 1053*9c381f59SAmarnath Hullur Subramanyam int sm_control_port = 7236; 1054*9c381f59SAmarnath Hullur Subramanyam char rtsp_session_id[12] = { '\0' }; 1055*9c381f59SAmarnath Hullur Subramanyam int (*extn_start_wfd_connection)(const char *, 1056*9c381f59SAmarnath Hullur Subramanyam const char *, /* Peer IP */ 1057*9c381f59SAmarnath Hullur Subramanyam int, /* RTSP port number */ 1058*9c381f59SAmarnath Hullur Subramanyam int, /* WFD Device Type; 0-Source, 1059*9c381f59SAmarnath Hullur Subramanyam 1-P-Sink, 2-Secondary Sink */ 1060*9c381f59SAmarnath Hullur Subramanyam char *); /* for returning session ID */ 1061*9c381f59SAmarnath Hullur Subramanyam int count = 0; 1062*9c381f59SAmarnath Hullur Subramanyam 1063*9c381f59SAmarnath Hullur Subramanyam if (r2_connection) { 1064*9c381f59SAmarnath Hullur Subramanyam if (strcasecmp(r2_connection, "Infrastructure") == 0) 1065*9c381f59SAmarnath Hullur Subramanyam return miracast_mdns_start_wfd_connection(dut, conn, 1066*9c381f59SAmarnath Hullur Subramanyam cmd); 1067*9c381f59SAmarnath Hullur Subramanyam } 1068*9c381f59SAmarnath Hullur Subramanyam 1069*9c381f59SAmarnath Hullur Subramanyam if (coupled_session && atoi(coupled_session) == 1) { 1070*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 1071*9c381f59SAmarnath Hullur Subramanyam "errorCode,Coupled Session is unsupported"); 1072*9c381f59SAmarnath Hullur Subramanyam return 0; 1073*9c381f59SAmarnath Hullur Subramanyam } 1074*9c381f59SAmarnath Hullur Subramanyam 1075*9c381f59SAmarnath Hullur Subramanyam if (tdls && atoi(tdls) == 1) { 1076*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 1077*9c381f59SAmarnath Hullur Subramanyam "errorCode,TDLS is unsupported"); 1078*9c381f59SAmarnath Hullur Subramanyam return 0; 1079*9c381f59SAmarnath Hullur Subramanyam } 1080*9c381f59SAmarnath Hullur Subramanyam 1081*9c381f59SAmarnath Hullur Subramanyam if (intent_val) { 1082*9c381f59SAmarnath Hullur Subramanyam go_intent = atoi(intent_val); 1083*9c381f59SAmarnath Hullur Subramanyam if (go_intent > 15) 1084*9c381f59SAmarnath Hullur Subramanyam go_intent = 1; 1085*9c381f59SAmarnath Hullur Subramanyam } 1086*9c381f59SAmarnath Hullur Subramanyam 1087*9c381f59SAmarnath Hullur Subramanyam if (p2p_discover_peer(dut, intf, peer_address, 1) < 0) { 1088*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 1089*9c381f59SAmarnath Hullur Subramanyam "errorCode,Could not find peer"); 1090*9c381f59SAmarnath Hullur Subramanyam return 0; 1091*9c381f59SAmarnath Hullur Subramanyam } 1092*9c381f59SAmarnath Hullur Subramanyam 1093*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf, sizeof(cmd_buf), "P2P_CONNECT %s", peer_address); 1094*9c381f59SAmarnath Hullur Subramanyam 1095*9c381f59SAmarnath Hullur Subramanyam switch (dut->wps_method) { 1096*9c381f59SAmarnath Hullur Subramanyam case WFA_CS_WPS_PIN_DISPLAY: 1097*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf + strlen(cmd_buf), 1098*9c381f59SAmarnath Hullur Subramanyam sizeof(cmd_buf) - strlen(cmd_buf), " pin display"); 1099*9c381f59SAmarnath Hullur Subramanyam break; 1100*9c381f59SAmarnath Hullur Subramanyam case WFA_CS_WPS_PIN_LABEL: 1101*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf + strlen(cmd_buf), 1102*9c381f59SAmarnath Hullur Subramanyam sizeof(cmd_buf) - strlen(cmd_buf), " pin label"); 1103*9c381f59SAmarnath Hullur Subramanyam break; 1104*9c381f59SAmarnath Hullur Subramanyam case WFA_CS_WPS_PIN_KEYPAD: 1105*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf + strlen(cmd_buf), 1106*9c381f59SAmarnath Hullur Subramanyam sizeof(cmd_buf) - strlen(cmd_buf), " %s keypad", 1107*9c381f59SAmarnath Hullur Subramanyam dut->wps_pin); 1108*9c381f59SAmarnath Hullur Subramanyam break; 1109*9c381f59SAmarnath Hullur Subramanyam case WFA_CS_WPS_PBC: 1110*9c381f59SAmarnath Hullur Subramanyam default: /* Configuring default to PBC */ 1111*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf + strlen(cmd_buf), 1112*9c381f59SAmarnath Hullur Subramanyam sizeof(cmd_buf) - strlen(cmd_buf), " pbc"); 1113*9c381f59SAmarnath Hullur Subramanyam break; 1114*9c381f59SAmarnath Hullur Subramanyam } 1115*9c381f59SAmarnath Hullur Subramanyam 1116*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf + strlen(cmd_buf), sizeof(cmd_buf) - strlen(cmd_buf), 1117*9c381f59SAmarnath Hullur Subramanyam " go_intent=%d", go_intent); 1118*9c381f59SAmarnath Hullur Subramanyam 1119*9c381f59SAmarnath Hullur Subramanyam if (init_wfd && atoi(init_wfd) == 0) { 1120*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf + strlen(cmd_buf), 1121*9c381f59SAmarnath Hullur Subramanyam sizeof(cmd_buf) - strlen(cmd_buf), " auth"); 1122*9c381f59SAmarnath Hullur Subramanyam } 1123*9c381f59SAmarnath Hullur Subramanyam 1124*9c381f59SAmarnath Hullur Subramanyam if (oper_chan) { 1125*9c381f59SAmarnath Hullur Subramanyam int chan; 1126*9c381f59SAmarnath Hullur Subramanyam 1127*9c381f59SAmarnath Hullur Subramanyam chan = atoi(oper_chan); 1128*9c381f59SAmarnath Hullur Subramanyam if (chan >= 1 && chan <= 13) 1129*9c381f59SAmarnath Hullur Subramanyam freq = 2407 + chan * 5; 1130*9c381f59SAmarnath Hullur Subramanyam else if (chan == 14) 1131*9c381f59SAmarnath Hullur Subramanyam freq = 2484; 1132*9c381f59SAmarnath Hullur Subramanyam else 1133*9c381f59SAmarnath Hullur Subramanyam freq = 5000 + chan * 5; 1134*9c381f59SAmarnath Hullur Subramanyam 1135*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf + strlen(cmd_buf), 1136*9c381f59SAmarnath Hullur Subramanyam sizeof(cmd_buf) - strlen(cmd_buf), " freq=%d", freq); 1137*9c381f59SAmarnath Hullur Subramanyam } 1138*9c381f59SAmarnath Hullur Subramanyam 1139*9c381f59SAmarnath Hullur Subramanyam /* WFD SESSION AVAILABILITY CHECK */ 1140*9c381f59SAmarnath Hullur Subramanyam 1141*9c381f59SAmarnath Hullur Subramanyam memset(buf_peer, 0, sizeof(buf_peer)); 1142*9c381f59SAmarnath Hullur Subramanyam snprintf(command, sizeof(command), "P2P_PEER %s", peer_address); 1143*9c381f59SAmarnath Hullur Subramanyam strlcpy(dut->peer_mac_address, peer_address, 1144*9c381f59SAmarnath Hullur Subramanyam sizeof(dut->peer_mac_address)); 1145*9c381f59SAmarnath Hullur Subramanyam wpa_command_resp(intf, command, buf_peer, sizeof(buf_peer)); 1146*9c381f59SAmarnath Hullur Subramanyam 1147*9c381f59SAmarnath Hullur Subramanyam if (strlen(buf_peer) != 0) 1148*9c381f59SAmarnath Hullur Subramanyam availability = strstr(buf_peer, "wfd_subelems="); 1149*9c381f59SAmarnath Hullur Subramanyam 1150*9c381f59SAmarnath Hullur Subramanyam if (!availability || strlen(availability) < 21) { 1151*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "Did not get WFD SUBELEMS"); 1152*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_COMPLETE, 1153*9c381f59SAmarnath Hullur Subramanyam "result,NULL,GroupID,NULL,WFDSessionID,NULL"); 1154*9c381f59SAmarnath Hullur Subramanyam return 0; 1155*9c381f59SAmarnath Hullur Subramanyam } 1156*9c381f59SAmarnath Hullur Subramanyam 1157*9c381f59SAmarnath Hullur Subramanyam /* Extracting Availability Bit */ 1158*9c381f59SAmarnath Hullur Subramanyam ctemp[0] = availability[21]; 1159*9c381f59SAmarnath Hullur Subramanyam ctemp[1] = '\0'; 1160*9c381f59SAmarnath Hullur Subramanyam avail_bit = (int) strtol(ctemp, NULL, 16); 1161*9c381f59SAmarnath Hullur Subramanyam 1162*9c381f59SAmarnath Hullur Subramanyam if ((avail_bit & 0x3) == 0) { 1163*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_COMPLETE, 1164*9c381f59SAmarnath Hullur Subramanyam "result,NULL,GroupID,NULL,WFDSessionID,NULL"); 1165*9c381f59SAmarnath Hullur Subramanyam return 0; 1166*9c381f59SAmarnath Hullur Subramanyam } 1167*9c381f59SAmarnath Hullur Subramanyam 1168*9c381f59SAmarnath Hullur Subramanyam /* Extract RTSP Port for Sink */ 1169*9c381f59SAmarnath Hullur Subramanyam 1170*9c381f59SAmarnath Hullur Subramanyam if (dut->wfd_device_type != 0) { 1171*9c381f59SAmarnath Hullur Subramanyam if (strlen(availability) >= 23) { 1172*9c381f59SAmarnath Hullur Subramanyam availability += 23; 1173*9c381f59SAmarnath Hullur Subramanyam if (availability[0]) 1174*9c381f59SAmarnath Hullur Subramanyam snprintf(rtspport, 5, "%s", availability); 1175*9c381f59SAmarnath Hullur Subramanyam } 1176*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 1177*9c381f59SAmarnath Hullur Subramanyam "rtsp_port = %s, availability = %s ", 1178*9c381f59SAmarnath Hullur Subramanyam rtspport, availability); 1179*9c381f59SAmarnath Hullur Subramanyam session_management_control_port = (int) strtol(rtspport, NULL, 1180*9c381f59SAmarnath Hullur Subramanyam 16); 1181*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 1182*9c381f59SAmarnath Hullur Subramanyam "SessionManagementControlPort = %d", 1183*9c381f59SAmarnath Hullur Subramanyam session_management_control_port); 1184*9c381f59SAmarnath Hullur Subramanyam } 1185*9c381f59SAmarnath Hullur Subramanyam 1186*9c381f59SAmarnath Hullur Subramanyam memset(resp_buf, 0, sizeof(resp_buf)); 1187*9c381f59SAmarnath Hullur Subramanyam res = wpa_command_resp(intf, cmd_buf, resp_buf, sizeof(resp_buf)); 1188*9c381f59SAmarnath Hullur Subramanyam if (strncmp(resp_buf, "FAIL", 4) == 0) { 1189*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 1190*9c381f59SAmarnath Hullur Subramanyam "wpa_command: Command failed (FAIL received)"); 1191*9c381f59SAmarnath Hullur Subramanyam return 1; 1192*9c381f59SAmarnath Hullur Subramanyam } 1193*9c381f59SAmarnath Hullur Subramanyam 1194*9c381f59SAmarnath Hullur Subramanyam if (init_wfd && atoi(init_wfd) == 0) { 1195*9c381f59SAmarnath Hullur Subramanyam /* Start thread to wait for P2P connection */ 1196*9c381f59SAmarnath Hullur Subramanyam miracast_rtsp_thread_create(dut, conn, cmd); 1197*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_COMPLETE, 1198*9c381f59SAmarnath Hullur Subramanyam "result,NULL,GroupID,NULL,WFDSessionID,NULL"); 1199*9c381f59SAmarnath Hullur Subramanyam return 0; 1200*9c381f59SAmarnath Hullur Subramanyam } 1201*9c381f59SAmarnath Hullur Subramanyam 1202*9c381f59SAmarnath Hullur Subramanyam res = get_p2p_connection_event(dut, intf, output_intf, 1203*9c381f59SAmarnath Hullur Subramanyam sizeof(output_intf), &is_group_owner); 1204*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "p2p connection done %d", 1205*9c381f59SAmarnath Hullur Subramanyam is_group_owner); 1206*9c381f59SAmarnath Hullur Subramanyam if (res < 0) { 1207*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_ERROR, 1208*9c381f59SAmarnath Hullur Subramanyam "Group Formation did not complete"); 1209*9c381f59SAmarnath Hullur Subramanyam return 1; 1210*9c381f59SAmarnath Hullur Subramanyam } 1211*9c381f59SAmarnath Hullur Subramanyam 1212*9c381f59SAmarnath Hullur Subramanyam snprintf(sig_resp_buf, sizeof(sig_resp_buf), "result"); 1213*9c381f59SAmarnath Hullur Subramanyam 1214*9c381f59SAmarnath Hullur Subramanyam if (is_group_owner) { 1215*9c381f59SAmarnath Hullur Subramanyam stop_dhcp(dut, output_intf,1); 1216*9c381f59SAmarnath Hullur Subramanyam snprintf(sig_resp_buf + strlen(sig_resp_buf), 1217*9c381f59SAmarnath Hullur Subramanyam sizeof(sig_resp_buf) - strlen(sig_resp_buf), ",GO"); 1218*9c381f59SAmarnath Hullur Subramanyam start_dhcp(dut, output_intf,1); 1219*9c381f59SAmarnath Hullur Subramanyam sleep(5); 1220*9c381f59SAmarnath Hullur Subramanyam } else { 1221*9c381f59SAmarnath Hullur Subramanyam snprintf(sig_resp_buf + strlen(sig_resp_buf), 1222*9c381f59SAmarnath Hullur Subramanyam sizeof(sig_resp_buf) - strlen(sig_resp_buf), 1223*9c381f59SAmarnath Hullur Subramanyam ",CLIENT"); 1224*9c381f59SAmarnath Hullur Subramanyam miracast_start_dhcp_client(dut, output_intf); 1225*9c381f59SAmarnath Hullur Subramanyam sleep(5); 1226*9c381f59SAmarnath Hullur Subramanyam } 1227*9c381f59SAmarnath Hullur Subramanyam 1228*9c381f59SAmarnath Hullur Subramanyam snprintf(sig_resp_buf + strlen(sig_resp_buf), 1229*9c381f59SAmarnath Hullur Subramanyam sizeof(sig_resp_buf) - strlen(sig_resp_buf), ",GroupID,"); 1230*9c381f59SAmarnath Hullur Subramanyam 1231*9c381f59SAmarnath Hullur Subramanyam res = get_wpa_status(output_intf, "p2p_device_address", 1232*9c381f59SAmarnath Hullur Subramanyam p2p_dev_address, sizeof(p2p_dev_address)); 1233*9c381f59SAmarnath Hullur Subramanyam if (res < 0) 1234*9c381f59SAmarnath Hullur Subramanyam return -1; 1235*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "p2p_dev_address %s", 1236*9c381f59SAmarnath Hullur Subramanyam p2p_dev_address); 1237*9c381f59SAmarnath Hullur Subramanyam strlcpy(sig_resp_buf + strlen(sig_resp_buf), p2p_dev_address, 1238*9c381f59SAmarnath Hullur Subramanyam sizeof(sig_resp_buf) - strlen(sig_resp_buf)); 1239*9c381f59SAmarnath Hullur Subramanyam 1240*9c381f59SAmarnath Hullur Subramanyam res = get_wpa_status(output_intf, "ssid", ssid, sizeof(ssid)); 1241*9c381f59SAmarnath Hullur Subramanyam if (res < 0) { 1242*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, 1243*9c381f59SAmarnath Hullur Subramanyam "get_wpa_status failed to get ssid"); 1244*9c381f59SAmarnath Hullur Subramanyam return -1; 1245*9c381f59SAmarnath Hullur Subramanyam } 1246*9c381f59SAmarnath Hullur Subramanyam 1247*9c381f59SAmarnath Hullur Subramanyam snprintf(sig_resp_buf + strlen(sig_resp_buf), 1248*9c381f59SAmarnath Hullur Subramanyam sizeof(sig_resp_buf) - strlen(sig_resp_buf), 1249*9c381f59SAmarnath Hullur Subramanyam " %s,WFDSessionId,", ssid); 1250*9c381f59SAmarnath Hullur Subramanyam 1251*9c381f59SAmarnath Hullur Subramanyam if (!is_group_owner) { 1252*9c381f59SAmarnath Hullur Subramanyam if (get_peer_ip_p2p_client(dut, peer_ip_address, output_intf, 1253*9c381f59SAmarnath Hullur Subramanyam 60) < 0) { 1254*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 1255*9c381f59SAmarnath Hullur Subramanyam "Could not get remote IP"); 1256*9c381f59SAmarnath Hullur Subramanyam return 0; 1257*9c381f59SAmarnath Hullur Subramanyam } 1258*9c381f59SAmarnath Hullur Subramanyam } else { 1259*9c381f59SAmarnath Hullur Subramanyam if (get_peer_ip_p2p_go(dut, peer_ip_address, peer_address, 1260*9c381f59SAmarnath Hullur Subramanyam 30) < 0) { 1261*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 1262*9c381f59SAmarnath Hullur Subramanyam "Could not get remote IP"); 1263*9c381f59SAmarnath Hullur Subramanyam return 0; 1264*9c381f59SAmarnath Hullur Subramanyam } 1265*9c381f59SAmarnath Hullur Subramanyam } 1266*9c381f59SAmarnath Hullur Subramanyam 1267*9c381f59SAmarnath Hullur Subramanyam if (dut->wfd_device_type != 0) 1268*9c381f59SAmarnath Hullur Subramanyam sm_control_port = (int) strtol(rtspport, NULL, 16); 1269*9c381f59SAmarnath Hullur Subramanyam else 1270*9c381f59SAmarnath Hullur Subramanyam sm_control_port = 7236; 1271*9c381f59SAmarnath Hullur Subramanyam 1272*9c381f59SAmarnath Hullur Subramanyam extn_start_wfd_connection = dlsym(dut->miracast_lib, 1273*9c381f59SAmarnath Hullur Subramanyam "start_wfd_connection"); 1274*9c381f59SAmarnath Hullur Subramanyam if (!extn_start_wfd_connection) 1275*9c381f59SAmarnath Hullur Subramanyam return -1; 1276*9c381f59SAmarnath Hullur Subramanyam extn_start_wfd_connection(NULL, peer_ip_address, sm_control_port, 1277*9c381f59SAmarnath Hullur Subramanyam 1 - dut->wfd_device_type, rtsp_session_id); 1278*9c381f59SAmarnath Hullur Subramanyam 1279*9c381f59SAmarnath Hullur Subramanyam while (strlen(rtsp_session_id) == 0 && count < 60) { 1280*9c381f59SAmarnath Hullur Subramanyam count++; 1281*9c381f59SAmarnath Hullur Subramanyam sleep(1); 1282*9c381f59SAmarnath Hullur Subramanyam } 1283*9c381f59SAmarnath Hullur Subramanyam 1284*9c381f59SAmarnath Hullur Subramanyam if (count == 60) 1285*9c381f59SAmarnath Hullur Subramanyam strlcpy(rtsp_session_id, "00000000", sizeof(rtsp_session_id)); 1286*9c381f59SAmarnath Hullur Subramanyam 1287*9c381f59SAmarnath Hullur Subramanyam strlcat(sig_resp_buf, rtsp_session_id, 1288*9c381f59SAmarnath Hullur Subramanyam sizeof(sig_resp_buf) - strlen(sig_resp_buf)); 1289*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_COMPLETE, sig_resp_buf); 1290*9c381f59SAmarnath Hullur Subramanyam return 0; 1291*9c381f59SAmarnath Hullur Subramanyam } 1292*9c381f59SAmarnath Hullur Subramanyam 1293*9c381f59SAmarnath Hullur Subramanyam 1294*9c381f59SAmarnath Hullur Subramanyam static int cmd_connect_go_start_wfd(struct sigma_dut *dut, 1295*9c381f59SAmarnath Hullur Subramanyam struct sigma_conn *conn, 1296*9c381f59SAmarnath Hullur Subramanyam struct sigma_cmd *cmd) 1297*9c381f59SAmarnath Hullur Subramanyam { 1298*9c381f59SAmarnath Hullur Subramanyam const char *intf = get_param(cmd, "Interface"); 1299*9c381f59SAmarnath Hullur Subramanyam const char *p2p_dev_id = get_param(cmd, "P2PdevID"); 1300*9c381f59SAmarnath Hullur Subramanyam /* const char *p2p_group_id = get_param(cmd, "GroupID"); */ 1301*9c381f59SAmarnath Hullur Subramanyam char sig_resp_buf[1024]; 1302*9c381f59SAmarnath Hullur Subramanyam char method[12]; 1303*9c381f59SAmarnath Hullur Subramanyam char cmd_buf[256]; 1304*9c381f59SAmarnath Hullur Subramanyam char buf[256]; 1305*9c381f59SAmarnath Hullur Subramanyam char resp_buf[256]; 1306*9c381f59SAmarnath Hullur Subramanyam int go = 0; 1307*9c381f59SAmarnath Hullur Subramanyam int res = 0; 1308*9c381f59SAmarnath Hullur Subramanyam char output_ifname[32]; 1309*9c381f59SAmarnath Hullur Subramanyam char peer_ip_address[32]; 1310*9c381f59SAmarnath Hullur Subramanyam char rtsp_session_id[12]; 1311*9c381f59SAmarnath Hullur Subramanyam int (*extn_connect_go_start_wfd)(const char *, 1312*9c381f59SAmarnath Hullur Subramanyam const char * /* Peer IP */, 1313*9c381f59SAmarnath Hullur Subramanyam int /* RTSP port number */, 1314*9c381f59SAmarnath Hullur Subramanyam int /* WFD Device Type; 0-Source, 1315*9c381f59SAmarnath Hullur Subramanyam 1-P-Sink, 2-Secondary Sink */, 1316*9c381f59SAmarnath Hullur Subramanyam char *); /* for returning session ID */ 1317*9c381f59SAmarnath Hullur Subramanyam 1318*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf, sizeof(cmd_buf), "P2P_CONNECT %s", p2p_dev_id); 1319*9c381f59SAmarnath Hullur Subramanyam 1320*9c381f59SAmarnath Hullur Subramanyam switch (dut->wps_method) { 1321*9c381f59SAmarnath Hullur Subramanyam case WFA_CS_WPS_PBC: 1322*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf + strlen(cmd_buf), 1323*9c381f59SAmarnath Hullur Subramanyam sizeof(cmd_buf) - strlen(cmd_buf), " pbc"); 1324*9c381f59SAmarnath Hullur Subramanyam strlcpy(method, "pbc", sizeof(method)); 1325*9c381f59SAmarnath Hullur Subramanyam break; 1326*9c381f59SAmarnath Hullur Subramanyam case WFA_CS_WPS_PIN_DISPLAY: 1327*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf + strlen(cmd_buf), 1328*9c381f59SAmarnath Hullur Subramanyam sizeof(cmd_buf) - strlen(cmd_buf), " pin display"); 1329*9c381f59SAmarnath Hullur Subramanyam strlcpy(method, "display", sizeof(method)); 1330*9c381f59SAmarnath Hullur Subramanyam break; 1331*9c381f59SAmarnath Hullur Subramanyam case WFA_CS_WPS_PIN_LABEL: 1332*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf + strlen(cmd_buf), 1333*9c381f59SAmarnath Hullur Subramanyam sizeof(cmd_buf) - strlen(cmd_buf), " pin label"); 1334*9c381f59SAmarnath Hullur Subramanyam strlcpy(method, "label", sizeof(method)); 1335*9c381f59SAmarnath Hullur Subramanyam break; 1336*9c381f59SAmarnath Hullur Subramanyam case WFA_CS_WPS_PIN_KEYPAD: 1337*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf + strlen(cmd_buf), 1338*9c381f59SAmarnath Hullur Subramanyam sizeof(cmd_buf) - strlen(cmd_buf), " %s keypad", 1339*9c381f59SAmarnath Hullur Subramanyam dut->wps_pin); 1340*9c381f59SAmarnath Hullur Subramanyam strlcpy(method, "keypad", sizeof(method)); 1341*9c381f59SAmarnath Hullur Subramanyam break; 1342*9c381f59SAmarnath Hullur Subramanyam default: /* Configuring to PBC */ 1343*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf + strlen(cmd_buf), 1344*9c381f59SAmarnath Hullur Subramanyam sizeof(cmd_buf) - strlen(cmd_buf), " pbc"); 1345*9c381f59SAmarnath Hullur Subramanyam strlcpy(method, "pbc", sizeof(method)); 1346*9c381f59SAmarnath Hullur Subramanyam break; 1347*9c381f59SAmarnath Hullur Subramanyam } 1348*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buf + strlen(cmd_buf), 1349*9c381f59SAmarnath Hullur Subramanyam sizeof(cmd_buf) - strlen(cmd_buf), " join"); 1350*9c381f59SAmarnath Hullur Subramanyam 1351*9c381f59SAmarnath Hullur Subramanyam /* run provisional discovery */ 1352*9c381f59SAmarnath Hullur Subramanyam if (p2p_discover_peer(dut, intf, p2p_dev_id, 0) < 0) { 1353*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 1354*9c381f59SAmarnath Hullur Subramanyam "ErrorCode,Could not discover the requested peer"); 1355*9c381f59SAmarnath Hullur Subramanyam return 0; 1356*9c381f59SAmarnath Hullur Subramanyam } 1357*9c381f59SAmarnath Hullur Subramanyam 1358*9c381f59SAmarnath Hullur Subramanyam snprintf(buf, sizeof(buf), "P2P_PROV_DISC %s %s", p2p_dev_id, method); 1359*9c381f59SAmarnath Hullur Subramanyam if (wpa_command(intf, buf) < 0) { 1360*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 1361*9c381f59SAmarnath Hullur Subramanyam "Failed to send provision discovery request"); 1362*9c381f59SAmarnath Hullur Subramanyam return -2; 1363*9c381f59SAmarnath Hullur Subramanyam } 1364*9c381f59SAmarnath Hullur Subramanyam 1365*9c381f59SAmarnath Hullur Subramanyam res = wpa_command_resp(intf, cmd_buf, resp_buf, sizeof(resp_buf)); 1366*9c381f59SAmarnath Hullur Subramanyam if (strncmp(resp_buf, "FAIL", 4) == 0) { 1367*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 1368*9c381f59SAmarnath Hullur Subramanyam "errorCode,failed P2P connection"); 1369*9c381f59SAmarnath Hullur Subramanyam return 0; 1370*9c381f59SAmarnath Hullur Subramanyam } 1371*9c381f59SAmarnath Hullur Subramanyam 1372*9c381f59SAmarnath Hullur Subramanyam res = get_p2p_connection_event(dut, intf, output_ifname, 1373*9c381f59SAmarnath Hullur Subramanyam sizeof(output_ifname), &go); 1374*9c381f59SAmarnath Hullur Subramanyam if (res < 0) { 1375*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 1376*9c381f59SAmarnath Hullur Subramanyam "errorCode,failed P2P connection"); 1377*9c381f59SAmarnath Hullur Subramanyam return 0; 1378*9c381f59SAmarnath Hullur Subramanyam } 1379*9c381f59SAmarnath Hullur Subramanyam 1380*9c381f59SAmarnath Hullur Subramanyam snprintf(sig_resp_buf + strlen(sig_resp_buf), 1381*9c381f59SAmarnath Hullur Subramanyam sizeof(sig_resp_buf) - strlen(sig_resp_buf), "WFDSessionId,"); 1382*9c381f59SAmarnath Hullur Subramanyam 1383*9c381f59SAmarnath Hullur Subramanyam miracast_start_dhcp_client(dut, output_ifname); 1384*9c381f59SAmarnath Hullur Subramanyam 1385*9c381f59SAmarnath Hullur Subramanyam if (get_peer_ip_p2p_client(dut, peer_ip_address, output_ifname, 1386*9c381f59SAmarnath Hullur Subramanyam 30) < 0) { 1387*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, "Could not get remote IP"); 1388*9c381f59SAmarnath Hullur Subramanyam return 0; 1389*9c381f59SAmarnath Hullur Subramanyam } 1390*9c381f59SAmarnath Hullur Subramanyam 1391*9c381f59SAmarnath Hullur Subramanyam if (dut->wfd_device_type != 0) { 1392*9c381f59SAmarnath Hullur Subramanyam char rtsp_buff[1000], cmd_buff[32]; 1393*9c381f59SAmarnath Hullur Subramanyam char *sub_elem = NULL; 1394*9c381f59SAmarnath Hullur Subramanyam char rtspport[5] = { '7', '2', '3', '6', '\0' }; 1395*9c381f59SAmarnath Hullur Subramanyam 1396*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, 1397*9c381f59SAmarnath Hullur Subramanyam "Log --- p2p address = %s", p2p_dev_id); 1398*9c381f59SAmarnath Hullur Subramanyam snprintf(cmd_buff, sizeof(cmd_buff), "P2P_PEER %s", p2p_dev_id); 1399*9c381f59SAmarnath Hullur Subramanyam wpa_command_resp(output_ifname, cmd_buff, rtsp_buff, 1400*9c381f59SAmarnath Hullur Subramanyam sizeof(rtsp_buff)); 1401*9c381f59SAmarnath Hullur Subramanyam 1402*9c381f59SAmarnath Hullur Subramanyam if (strlen(rtsp_buff) != 0) 1403*9c381f59SAmarnath Hullur Subramanyam sub_elem = strstr(rtsp_buff, "wfd_subelems="); 1404*9c381f59SAmarnath Hullur Subramanyam 1405*9c381f59SAmarnath Hullur Subramanyam /* Extract RTSP Port for Sink */ 1406*9c381f59SAmarnath Hullur Subramanyam if (sub_elem && strlen(sub_elem) >= 23) { 1407*9c381f59SAmarnath Hullur Subramanyam sub_elem += 23; 1408*9c381f59SAmarnath Hullur Subramanyam snprintf(rtspport, 5, "%s", sub_elem); 1409*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, 1410*9c381f59SAmarnath Hullur Subramanyam "rtsp_port = %s, subElem = %s", 1411*9c381f59SAmarnath Hullur Subramanyam rtspport, sub_elem); 1412*9c381f59SAmarnath Hullur Subramanyam } 1413*9c381f59SAmarnath Hullur Subramanyam session_management_control_port = (int) strtol(rtspport, NULL, 1414*9c381f59SAmarnath Hullur Subramanyam 16); 1415*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, 1416*9c381f59SAmarnath Hullur Subramanyam "SessionManagementControlPort = %d", 1417*9c381f59SAmarnath Hullur Subramanyam session_management_control_port); 1418*9c381f59SAmarnath Hullur Subramanyam 1419*9c381f59SAmarnath Hullur Subramanyam } else { 1420*9c381f59SAmarnath Hullur Subramanyam session_management_control_port = 7236; 1421*9c381f59SAmarnath Hullur Subramanyam } 1422*9c381f59SAmarnath Hullur Subramanyam 1423*9c381f59SAmarnath Hullur Subramanyam extn_connect_go_start_wfd = dlsym(dut->miracast_lib, 1424*9c381f59SAmarnath Hullur Subramanyam "connect_go_start_wfd"); 1425*9c381f59SAmarnath Hullur Subramanyam if (!extn_connect_go_start_wfd) 1426*9c381f59SAmarnath Hullur Subramanyam return -1; 1427*9c381f59SAmarnath Hullur Subramanyam extn_connect_go_start_wfd(NULL, peer_ip_address, 1428*9c381f59SAmarnath Hullur Subramanyam session_management_control_port, 1429*9c381f59SAmarnath Hullur Subramanyam 1 - dut->wfd_device_type, rtsp_session_id); 1430*9c381f59SAmarnath Hullur Subramanyam strlcat(sig_resp_buf, rtsp_session_id, 1431*9c381f59SAmarnath Hullur Subramanyam sizeof(sig_resp_buf) - strlen(sig_resp_buf)); 1432*9c381f59SAmarnath Hullur Subramanyam 1433*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_COMPLETE, sig_resp_buf); 1434*9c381f59SAmarnath Hullur Subramanyam return 0; 1435*9c381f59SAmarnath Hullur Subramanyam } 1436*9c381f59SAmarnath Hullur Subramanyam 1437*9c381f59SAmarnath Hullur Subramanyam 1438*9c381f59SAmarnath Hullur Subramanyam static int cmd_sta_generate_event(struct sigma_dut *dut, 1439*9c381f59SAmarnath Hullur Subramanyam struct sigma_conn *conn, 1440*9c381f59SAmarnath Hullur Subramanyam struct sigma_cmd *cmd) 1441*9c381f59SAmarnath Hullur Subramanyam { 1442*9c381f59SAmarnath Hullur Subramanyam 1443*9c381f59SAmarnath Hullur Subramanyam /* const char *intf = get_param(cmd, "Interface"); */ 1444*9c381f59SAmarnath Hullur Subramanyam /* const char *program = get_param(cmd, "Program"); */ 1445*9c381f59SAmarnath Hullur Subramanyam const char *type = get_param(cmd, "Type"); 1446*9c381f59SAmarnath Hullur Subramanyam char string_cmd[MIRACAST_CMD_LEN]; 1447*9c381f59SAmarnath Hullur Subramanyam int (*extn_sta_generate_event)(const char *); 1448*9c381f59SAmarnath Hullur Subramanyam 1449*9c381f59SAmarnath Hullur Subramanyam if (!type) { 1450*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_INVALID, 1451*9c381f59SAmarnath Hullur Subramanyam "errorCode, Invalid Type for Generate Event"); 1452*9c381f59SAmarnath Hullur Subramanyam return 0; 1453*9c381f59SAmarnath Hullur Subramanyam } 1454*9c381f59SAmarnath Hullur Subramanyam miracast_generate_string_cmd(cmd, string_cmd, sizeof(string_cmd)); 1455*9c381f59SAmarnath Hullur Subramanyam extn_sta_generate_event = dlsym(dut->miracast_lib, 1456*9c381f59SAmarnath Hullur Subramanyam "sta_generate_event"); 1457*9c381f59SAmarnath Hullur Subramanyam if (!extn_sta_generate_event) 1458*9c381f59SAmarnath Hullur Subramanyam return -1; 1459*9c381f59SAmarnath Hullur Subramanyam if (strcasecmp(type, "UIBC_Gen") == 0 || 1460*9c381f59SAmarnath Hullur Subramanyam strcasecmp(type, "UIBC_HID") == 0) { 1461*9c381f59SAmarnath Hullur Subramanyam extn_sta_generate_event(string_cmd); 1462*9c381f59SAmarnath Hullur Subramanyam } else if (strcasecmp(type, "FrameSkip") == 0) { 1463*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 1464*9c381f59SAmarnath Hullur Subramanyam "errorCode,Unsupported Type for Generate Event"); 1465*9c381f59SAmarnath Hullur Subramanyam return 0; 1466*9c381f59SAmarnath Hullur Subramanyam } else if (strcasecmp(type, "InputContent") == 0) { 1467*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_COMPLETE, NULL); 1468*9c381f59SAmarnath Hullur Subramanyam return 0; 1469*9c381f59SAmarnath Hullur Subramanyam } else if (strcasecmp(type, "I2cRead") == 0) { 1470*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 1471*9c381f59SAmarnath Hullur Subramanyam "errorCode,Unsupported Type for Generate Event"); 1472*9c381f59SAmarnath Hullur Subramanyam return 0; 1473*9c381f59SAmarnath Hullur Subramanyam } else if (strcasecmp(type, "I2cWrite") == 0) { 1474*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 1475*9c381f59SAmarnath Hullur Subramanyam "errorCode, Unsupported Type for Generate Event"); 1476*9c381f59SAmarnath Hullur Subramanyam return 0; 1477*9c381f59SAmarnath Hullur Subramanyam } else if (strcasecmp(type, "IdrReq") == 0) { 1478*9c381f59SAmarnath Hullur Subramanyam if (dut->wfd_device_type == 0) { /* Source */ 1479*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 1480*9c381f59SAmarnath Hullur Subramanyam "errorCode, Unsupported Type for Generate Event"); 1481*9c381f59SAmarnath Hullur Subramanyam } else { 1482*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_COMPLETE, NULL); 1483*9c381f59SAmarnath Hullur Subramanyam extn_sta_generate_event(string_cmd); 1484*9c381f59SAmarnath Hullur Subramanyam } 1485*9c381f59SAmarnath Hullur Subramanyam return 0; 1486*9c381f59SAmarnath Hullur Subramanyam } 1487*9c381f59SAmarnath Hullur Subramanyam return 1; 1488*9c381f59SAmarnath Hullur Subramanyam } 1489*9c381f59SAmarnath Hullur Subramanyam 1490*9c381f59SAmarnath Hullur Subramanyam 1491*9c381f59SAmarnath Hullur Subramanyam static int cmd_reinvoke_wfd_session(struct sigma_dut *dut, 1492*9c381f59SAmarnath Hullur Subramanyam struct sigma_conn *conn, 1493*9c381f59SAmarnath Hullur Subramanyam struct sigma_cmd *cmd) 1494*9c381f59SAmarnath Hullur Subramanyam { 1495*9c381f59SAmarnath Hullur Subramanyam const char *intf = get_param(cmd, "Interface"); 1496*9c381f59SAmarnath Hullur Subramanyam const char *grp_id = get_param(cmd, "GroupID"); 1497*9c381f59SAmarnath Hullur Subramanyam const char *peer_address = get_param(cmd, "peeraddress"); 1498*9c381f59SAmarnath Hullur Subramanyam const char *invitation_action = get_param(cmd, "InvitationAction"); 1499*9c381f59SAmarnath Hullur Subramanyam char buf[256]; 1500*9c381f59SAmarnath Hullur Subramanyam 1501*9c381f59SAmarnath Hullur Subramanyam /* All are compulsory parameters */ 1502*9c381f59SAmarnath Hullur Subramanyam if (!intf || !grp_id || !invitation_action || !peer_address) { 1503*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_INVALID, 1504*9c381f59SAmarnath Hullur Subramanyam "errorCode,Invalid parameters for Reinvoke WFD Session"); 1505*9c381f59SAmarnath Hullur Subramanyam return 0; 1506*9c381f59SAmarnath Hullur Subramanyam } 1507*9c381f59SAmarnath Hullur Subramanyam 1508*9c381f59SAmarnath Hullur Subramanyam if (strcmp(invitation_action, "accept") == 0) { 1509*9c381f59SAmarnath Hullur Subramanyam /* 1510*9c381f59SAmarnath Hullur Subramanyam * In a client-joining-a-running-group case, we need to 1511*9c381f59SAmarnath Hullur Subramanyam * separately authorize the invitation. 1512*9c381f59SAmarnath Hullur Subramanyam */ 1513*9c381f59SAmarnath Hullur Subramanyam miracast_stop_dhcp_client(dut, NULL); 1514*9c381f59SAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_DEBUG, "Trying to discover GO %s", 1515*9c381f59SAmarnath Hullur Subramanyam peer_address); 1516*9c381f59SAmarnath Hullur Subramanyam if (p2p_discover_peer(dut, intf, peer_address, 1) < 0) { 1517*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_ERROR, 1518*9c381f59SAmarnath Hullur Subramanyam "ErrorCode,Could not discover the requested peer"); 1519*9c381f59SAmarnath Hullur Subramanyam return 0; 1520*9c381f59SAmarnath Hullur Subramanyam } 1521*9c381f59SAmarnath Hullur Subramanyam 1522*9c381f59SAmarnath Hullur Subramanyam snprintf(buf, sizeof(buf), "P2P_CONNECT %s %s join auth", 1523*9c381f59SAmarnath Hullur Subramanyam peer_address, dut->wps_method == WFA_CS_WPS_PBC ? 1524*9c381f59SAmarnath Hullur Subramanyam "pbc" : dut->wps_pin); 1525*9c381f59SAmarnath Hullur Subramanyam if (wpa_command(intf, buf) < 0) 1526*9c381f59SAmarnath Hullur Subramanyam return -2; 1527*9c381f59SAmarnath Hullur Subramanyam 1528*9c381f59SAmarnath Hullur Subramanyam miracast_rtsp_thread_create(dut, conn, cmd); 1529*9c381f59SAmarnath Hullur Subramanyam return 1; 1530*9c381f59SAmarnath Hullur Subramanyam } 1531*9c381f59SAmarnath Hullur Subramanyam 1532*9c381f59SAmarnath Hullur Subramanyam send_resp(dut, conn, SIGMA_INVALID, 1533*9c381f59SAmarnath Hullur Subramanyam "errorCode,Unsupported Invitation Action"); 1534*9c381f59SAmarnath Hullur Subramanyam return 0; 1535*9c381f59SAmarnath Hullur Subramanyam } 1536*9c381f59SAmarnath Hullur Subramanyam 1537*9c381f59SAmarnath Hullur Subramanyam 1538*9c381f59SAmarnath Hullur Subramanyam static int req_intf_peer(struct sigma_cmd *cmd) 1539*9c381f59SAmarnath Hullur Subramanyam { 1540*9c381f59SAmarnath Hullur Subramanyam if (!get_param(cmd, "interface") || 1541*9c381f59SAmarnath Hullur Subramanyam !get_param(cmd, "PeerAddress")) 1542*9c381f59SAmarnath Hullur Subramanyam return -1; 1543*9c381f59SAmarnath Hullur Subramanyam return 0; 1544*9c381f59SAmarnath Hullur Subramanyam } 1545*9c381f59SAmarnath Hullur Subramanyam 1546*9c381f59SAmarnath Hullur Subramanyam 1547*9c381f59SAmarnath Hullur Subramanyam static int req_intf_p2pdev_grpid(struct sigma_cmd *cmd) 1548*9c381f59SAmarnath Hullur Subramanyam { 1549*9c381f59SAmarnath Hullur Subramanyam if (!get_param(cmd, "interface") || 1550*9c381f59SAmarnath Hullur Subramanyam !get_param(cmd, "P2pdevID") || 1551*9c381f59SAmarnath Hullur Subramanyam !get_param(cmd, "GroupID")) 1552*9c381f59SAmarnath Hullur Subramanyam return -1; 1553*9c381f59SAmarnath Hullur Subramanyam return 0; 1554*9c381f59SAmarnath Hullur Subramanyam } 1555*9c381f59SAmarnath Hullur Subramanyam 1556*9c381f59SAmarnath Hullur Subramanyam 1557*9c381f59SAmarnath Hullur Subramanyam static int req_intf_prog_type(struct sigma_cmd *cmd) 1558*9c381f59SAmarnath Hullur Subramanyam { 1559*9c381f59SAmarnath Hullur Subramanyam const char *prog = get_param(cmd, "Program"); 1560*9c381f59SAmarnath Hullur Subramanyam 1561*9c381f59SAmarnath Hullur Subramanyam if (!get_param(cmd, "interface") || 1562*9c381f59SAmarnath Hullur Subramanyam !get_param(cmd, "Type") || 1563*9c381f59SAmarnath Hullur Subramanyam !prog || strcmp(prog, "WFD") != 0) 1564*9c381f59SAmarnath Hullur Subramanyam return -1; 1565*9c381f59SAmarnath Hullur Subramanyam return 0; 1566*9c381f59SAmarnath Hullur Subramanyam } 1567*9c381f59SAmarnath Hullur Subramanyam 1568*9c381f59SAmarnath Hullur Subramanyam 1569*9c381f59SAmarnath Hullur Subramanyam static int req_intf_peeradd_inv(struct sigma_cmd *cmd) 1570*9c381f59SAmarnath Hullur Subramanyam { 1571*9c381f59SAmarnath Hullur Subramanyam if (!get_param(cmd, "interface") || 1572*9c381f59SAmarnath Hullur Subramanyam !get_param(cmd, "peerAddress") || 1573*9c381f59SAmarnath Hullur Subramanyam !get_param(cmd, "InvitationAction")) 1574*9c381f59SAmarnath Hullur Subramanyam return -1; 1575*9c381f59SAmarnath Hullur Subramanyam return 0; 1576*9c381f59SAmarnath Hullur Subramanyam } 1577*9c381f59SAmarnath Hullur Subramanyam 1578*9c381f59SAmarnath Hullur Subramanyam 1579*9c381f59SAmarnath Hullur Subramanyam void miracast_register_cmds(void) 1580*9c381f59SAmarnath Hullur Subramanyam { 1581*9c381f59SAmarnath Hullur Subramanyam sigma_dut_reg_cmd("start_wfd_connection", req_intf_peer, 1582*9c381f59SAmarnath Hullur Subramanyam cmd_start_wfd_connection); 1583*9c381f59SAmarnath Hullur Subramanyam sigma_dut_reg_cmd("connect_go_start_wfd", req_intf_p2pdev_grpid, 1584*9c381f59SAmarnath Hullur Subramanyam cmd_connect_go_start_wfd); 1585*9c381f59SAmarnath Hullur Subramanyam sigma_dut_reg_cmd("sta_generate_event", req_intf_prog_type, 1586*9c381f59SAmarnath Hullur Subramanyam cmd_sta_generate_event); 1587*9c381f59SAmarnath Hullur Subramanyam sigma_dut_reg_cmd("reinvoke_wfd_session", req_intf_peeradd_inv, 1588*9c381f59SAmarnath Hullur Subramanyam cmd_reinvoke_wfd_session); 1589*9c381f59SAmarnath Hullur Subramanyam } 1590