1cd4e3c3eSJouni Malinen /* 2cd4e3c3eSJouni Malinen * Sigma Control API DUT (NAN functionality) 3cd4e3c3eSJouni Malinen * Copyright (c) 2014-2015, Qualcomm Atheros, Inc. 4cd4e3c3eSJouni Malinen * All Rights Reserved. 5cd4e3c3eSJouni Malinen * Licensed under the Clear BSD license. See README for more details. 6cd4e3c3eSJouni Malinen */ 7cd4e3c3eSJouni Malinen 8cd4e3c3eSJouni Malinen #include "sigma_dut.h" 9cd4e3c3eSJouni Malinen #include <sys/stat.h> 10cd4e3c3eSJouni Malinen #include "wpa_ctrl.h" 11cd4e3c3eSJouni Malinen #include "wpa_helpers.h" 12cd4e3c3eSJouni Malinen #include "wifi_hal.h" 13*1854ec6fSAmarnath Hullur Subramanyam #include "nan_cert.h" 14cd4e3c3eSJouni Malinen 15cd4e3c3eSJouni Malinen pthread_cond_t gCondition; 16cd4e3c3eSJouni Malinen pthread_mutex_t gMutex; 17*1854ec6fSAmarnath Hullur Subramanyam wifi_handle global_wifi_handle; 18*1854ec6fSAmarnath Hullur Subramanyam wifi_interface_handle global_interface_handle; 19cd4e3c3eSJouni Malinen static int nan_state = 0; 20cd4e3c3eSJouni Malinen static int event_anyresponse = 0; 21cd4e3c3eSJouni Malinen static int is_fam = 0; 22cd4e3c3eSJouni Malinen 23cd4e3c3eSJouni Malinen uint16_t global_header_handle = 0; 24cd4e3c3eSJouni Malinen uint32_t global_match_handle = 0; 25cd4e3c3eSJouni Malinen 26cd4e3c3eSJouni Malinen #define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] 27cd4e3c3eSJouni Malinen #define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" 28cd4e3c3eSJouni Malinen #ifndef ETH_ALEN 29cd4e3c3eSJouni Malinen #define ETH_ALEN 6 30cd4e3c3eSJouni Malinen #endif 31cd4e3c3eSJouni Malinen 32cd4e3c3eSJouni Malinen struct sigma_dut *global_dut = NULL; 33cd4e3c3eSJouni Malinen static char global_nan_mac_addr[ETH_ALEN]; 34cd4e3c3eSJouni Malinen static char global_event_resp_buf[1024]; 35cd4e3c3eSJouni Malinen 36cd4e3c3eSJouni Malinen static int nan_further_availability_tx(struct sigma_dut *dut, 37cd4e3c3eSJouni Malinen struct sigma_conn *conn, 38cd4e3c3eSJouni Malinen struct sigma_cmd *cmd); 39cd4e3c3eSJouni Malinen static int nan_further_availability_rx(struct sigma_dut *dut, 40cd4e3c3eSJouni Malinen struct sigma_conn *conn, 41cd4e3c3eSJouni Malinen struct sigma_cmd *cmd); 42cd4e3c3eSJouni Malinen 43cd4e3c3eSJouni Malinen 44cd4e3c3eSJouni Malinen void nan_hex_dump(struct sigma_dut *dut, uint8_t *data, size_t len) 45cd4e3c3eSJouni Malinen { 46cd4e3c3eSJouni Malinen char buf[512]; 47cd4e3c3eSJouni Malinen uint16_t index; 48cd4e3c3eSJouni Malinen uint8_t *ptr; 49cd4e3c3eSJouni Malinen int pos; 50cd4e3c3eSJouni Malinen 51cd4e3c3eSJouni Malinen memset(buf, 0, sizeof(buf)); 52cd4e3c3eSJouni Malinen ptr = data; 53cd4e3c3eSJouni Malinen pos = 0; 54cd4e3c3eSJouni Malinen for (index = 0; index < len; index++) { 55cd4e3c3eSJouni Malinen pos += sprintf(&(buf[pos]), "%02x ", *ptr++); 56cd4e3c3eSJouni Malinen if (pos > 508) 57cd4e3c3eSJouni Malinen break; 58cd4e3c3eSJouni Malinen } 59cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "HEXDUMP len=[%d]", (int) len); 60cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "buf:%s", buf); 61cd4e3c3eSJouni Malinen } 62cd4e3c3eSJouni Malinen 63cd4e3c3eSJouni Malinen 64cd4e3c3eSJouni Malinen int nan_parse_hex(unsigned char c) 65cd4e3c3eSJouni Malinen { 66cd4e3c3eSJouni Malinen if (c >= '0' && c <= '9') 67cd4e3c3eSJouni Malinen return c - '0'; 68cd4e3c3eSJouni Malinen if (c >= 'a' && c <= 'f') 69cd4e3c3eSJouni Malinen return c - 'a' + 10; 70cd4e3c3eSJouni Malinen if (c >= 'A' && c <= 'F') 71cd4e3c3eSJouni Malinen return c - 'A' + 10; 72cd4e3c3eSJouni Malinen return 0; 73cd4e3c3eSJouni Malinen } 74cd4e3c3eSJouni Malinen 75cd4e3c3eSJouni Malinen 76cd4e3c3eSJouni Malinen int nan_parse_token(const char *tokenIn, u8 *tokenOut, int *filterLen) 77cd4e3c3eSJouni Malinen { 78cd4e3c3eSJouni Malinen int total_len = 0, len = 0; 79cd4e3c3eSJouni Malinen char *saveptr = NULL; 80cd4e3c3eSJouni Malinen 81cd4e3c3eSJouni Malinen tokenIn = strtok_r((char *) tokenIn, ":", &saveptr); 82cd4e3c3eSJouni Malinen while (tokenIn != NULL) { 83cd4e3c3eSJouni Malinen len = strlen(tokenIn); 84cd4e3c3eSJouni Malinen if (len == 1 && *tokenIn == '*') 85cd4e3c3eSJouni Malinen len = 0; 86cd4e3c3eSJouni Malinen tokenOut[total_len++] = (u8) len; 87cd4e3c3eSJouni Malinen if (len != 0) 88cd4e3c3eSJouni Malinen memcpy((u8 *) tokenOut + total_len, tokenIn, len); 89cd4e3c3eSJouni Malinen total_len += len; 90cd4e3c3eSJouni Malinen tokenIn = strtok_r(NULL, ":", &saveptr); 91cd4e3c3eSJouni Malinen } 92cd4e3c3eSJouni Malinen *filterLen = total_len; 93cd4e3c3eSJouni Malinen return 0; 94cd4e3c3eSJouni Malinen } 95cd4e3c3eSJouni Malinen 96cd4e3c3eSJouni Malinen 97cd4e3c3eSJouni Malinen int nan_parse_mac_address(struct sigma_dut *dut, const char *arg, u8 *addr) 98cd4e3c3eSJouni Malinen { 99cd4e3c3eSJouni Malinen if (strlen(arg) != 17) { 100cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid mac address %s", 101cd4e3c3eSJouni Malinen arg); 102cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, 103cd4e3c3eSJouni Malinen "expected format xx:xx:xx:xx:xx:xx"); 104cd4e3c3eSJouni Malinen return -1; 105cd4e3c3eSJouni Malinen } 106cd4e3c3eSJouni Malinen 107cd4e3c3eSJouni Malinen addr[0] = nan_parse_hex(arg[0]) << 4 | nan_parse_hex(arg[1]); 108cd4e3c3eSJouni Malinen addr[1] = nan_parse_hex(arg[3]) << 4 | nan_parse_hex(arg[4]); 109cd4e3c3eSJouni Malinen addr[2] = nan_parse_hex(arg[6]) << 4 | nan_parse_hex(arg[7]); 110cd4e3c3eSJouni Malinen addr[3] = nan_parse_hex(arg[9]) << 4 | nan_parse_hex(arg[10]); 111cd4e3c3eSJouni Malinen addr[4] = nan_parse_hex(arg[12]) << 4 | nan_parse_hex(arg[13]); 112cd4e3c3eSJouni Malinen addr[5] = nan_parse_hex(arg[15]) << 4 | nan_parse_hex(arg[16]); 113cd4e3c3eSJouni Malinen 114cd4e3c3eSJouni Malinen return 0; 115cd4e3c3eSJouni Malinen } 116cd4e3c3eSJouni Malinen 117cd4e3c3eSJouni Malinen 118cd4e3c3eSJouni Malinen int nan_parse_mac_address_list(struct sigma_dut *dut, const char *input, 119cd4e3c3eSJouni Malinen u8 *output, u16 max_addr_allowed) 120cd4e3c3eSJouni Malinen { 121cd4e3c3eSJouni Malinen /* 122cd4e3c3eSJouni Malinen * Reads a list of mac address separated by space. Each MAC address 123cd4e3c3eSJouni Malinen * should have the format of aa:bb:cc:dd:ee:ff. 124cd4e3c3eSJouni Malinen */ 125cd4e3c3eSJouni Malinen char *saveptr; 126cd4e3c3eSJouni Malinen char *token; 127cd4e3c3eSJouni Malinen int i = 0; 128cd4e3c3eSJouni Malinen 129cd4e3c3eSJouni Malinen for (i = 0; i < max_addr_allowed; i++) { 130cd4e3c3eSJouni Malinen token = strtok_r((i == 0) ? (char *) input : NULL, 131cd4e3c3eSJouni Malinen " ", &saveptr); 132cd4e3c3eSJouni Malinen if (token) { 133cd4e3c3eSJouni Malinen nan_parse_mac_address(dut, token, output); 134cd4e3c3eSJouni Malinen output += NAN_MAC_ADDR_LEN; 135cd4e3c3eSJouni Malinen } else 136cd4e3c3eSJouni Malinen break; 137cd4e3c3eSJouni Malinen } 138cd4e3c3eSJouni Malinen 139cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "Num MacAddress:%d", i); 140cd4e3c3eSJouni Malinen 141cd4e3c3eSJouni Malinen return i; 142cd4e3c3eSJouni Malinen } 143cd4e3c3eSJouni Malinen 144cd4e3c3eSJouni Malinen 145cd4e3c3eSJouni Malinen int nan_parse_hex_string(struct sigma_dut *dut, const char *input, 146cd4e3c3eSJouni Malinen u8 *output, int *outputlen) 147cd4e3c3eSJouni Malinen { 148cd4e3c3eSJouni Malinen int i = 0; 149cd4e3c3eSJouni Malinen int j = 0; 150cd4e3c3eSJouni Malinen 151cd4e3c3eSJouni Malinen for (i = 0; i < (int) strlen(input) && j < *outputlen; i += 2) { 152cd4e3c3eSJouni Malinen output[j] = nan_parse_hex(input[i]); 153cd4e3c3eSJouni Malinen if (i + 1 < (int) strlen(input)) { 154cd4e3c3eSJouni Malinen output[j] = ((output[j] << 4) | 155cd4e3c3eSJouni Malinen nan_parse_hex(input[i + 1])); 156cd4e3c3eSJouni Malinen } 157cd4e3c3eSJouni Malinen j++; 158cd4e3c3eSJouni Malinen } 159cd4e3c3eSJouni Malinen *outputlen = j; 160cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "Input:%s inputlen:%d outputlen:%d", 161cd4e3c3eSJouni Malinen input, (int) strlen(input), (int) *outputlen); 162cd4e3c3eSJouni Malinen return 0; 163cd4e3c3eSJouni Malinen } 164cd4e3c3eSJouni Malinen 165cd4e3c3eSJouni Malinen 166cd4e3c3eSJouni Malinen int wait(struct timespec abstime) 167cd4e3c3eSJouni Malinen { 168cd4e3c3eSJouni Malinen struct timeval now; 169cd4e3c3eSJouni Malinen 170cd4e3c3eSJouni Malinen gettimeofday(&now, NULL); 171cd4e3c3eSJouni Malinen 172cd4e3c3eSJouni Malinen abstime.tv_sec += now.tv_sec; 173cd4e3c3eSJouni Malinen if (((abstime.tv_nsec + now.tv_usec * 1000) > 1000 * 1000 * 1000) || 174cd4e3c3eSJouni Malinen (abstime.tv_nsec + now.tv_usec * 1000 < 0)) { 175cd4e3c3eSJouni Malinen abstime.tv_sec += 1; 176cd4e3c3eSJouni Malinen abstime.tv_nsec += now.tv_usec * 1000; 177cd4e3c3eSJouni Malinen abstime.tv_nsec -= 1000 * 1000 * 1000; 178cd4e3c3eSJouni Malinen } else { 179cd4e3c3eSJouni Malinen abstime.tv_nsec += now.tv_usec * 1000; 180cd4e3c3eSJouni Malinen } 181cd4e3c3eSJouni Malinen 182cd4e3c3eSJouni Malinen return pthread_cond_timedwait(&gCondition, &gMutex, &abstime); 183cd4e3c3eSJouni Malinen } 184cd4e3c3eSJouni Malinen 185cd4e3c3eSJouni Malinen 186cd4e3c3eSJouni Malinen int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut, 187cd4e3c3eSJouni Malinen struct sigma_conn *conn, 188cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 189cd4e3c3eSJouni Malinen { 190cd4e3c3eSJouni Malinen const char *oper_chan = get_param(cmd, "oper_chan"); 191cd4e3c3eSJouni Malinen int channel = 0; 192cd4e3c3eSJouni Malinen 193cd4e3c3eSJouni Malinen channel = atoi(oper_chan); 194cd4e3c3eSJouni Malinen dut->sta_channel = channel; 195cd4e3c3eSJouni Malinen 196cd4e3c3eSJouni Malinen return 0; 197cd4e3c3eSJouni Malinen } 198cd4e3c3eSJouni Malinen 199cd4e3c3eSJouni Malinen 200*1854ec6fSAmarnath Hullur Subramanyam void nan_print_further_availability_chan(struct sigma_dut *dut, 201*1854ec6fSAmarnath Hullur Subramanyam u8 num_chans, 202*1854ec6fSAmarnath Hullur Subramanyam NanFurtherAvailabilityChannel *fachan) 203*1854ec6fSAmarnath Hullur Subramanyam { 204*1854ec6fSAmarnath Hullur Subramanyam int idx; 205*1854ec6fSAmarnath Hullur Subramanyam 206*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 207*1854ec6fSAmarnath Hullur Subramanyam "********Printing FurtherAvailabilityChan Info******"); 208*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "Numchans:%d", num_chans); 209*1854ec6fSAmarnath Hullur Subramanyam for (idx = 0; idx < num_chans; idx++) { 210*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 211*1854ec6fSAmarnath Hullur Subramanyam "[%d]: NanAvailDuration:%d class_val:%02x channel:%d", 212*1854ec6fSAmarnath Hullur Subramanyam idx, fachan->entry_control, 213*1854ec6fSAmarnath Hullur Subramanyam fachan->class_val, fachan->channel); 214*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 215*1854ec6fSAmarnath Hullur Subramanyam "[%d]: mapid:%d Availability bitmap:%08x", 216*1854ec6fSAmarnath Hullur Subramanyam idx, fachan->mapid, 217*1854ec6fSAmarnath Hullur Subramanyam fachan->avail_interval_bitmap); 218*1854ec6fSAmarnath Hullur Subramanyam } 219*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 220*1854ec6fSAmarnath Hullur Subramanyam "*********************Done**********************"); 221*1854ec6fSAmarnath Hullur Subramanyam } 222*1854ec6fSAmarnath Hullur Subramanyam 223*1854ec6fSAmarnath Hullur Subramanyam 224cd4e3c3eSJouni Malinen int sigma_nan_enable(struct sigma_dut *dut, struct sigma_conn *conn, 225cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 226cd4e3c3eSJouni Malinen { 227cd4e3c3eSJouni Malinen const char *master_pref = get_param(cmd, "MasterPref"); 228cd4e3c3eSJouni Malinen const char *rand_fac = get_param(cmd, "RandFactor"); 229cd4e3c3eSJouni Malinen const char *hop_count = get_param(cmd, "HopCount"); 230cd4e3c3eSJouni Malinen const char *high_tsf = get_param(cmd, "HighTSF"); 231cd4e3c3eSJouni Malinen const char *sdftx_band = get_param(cmd, "SDFTxBand"); 232cd4e3c3eSJouni Malinen const char *oper_chan = get_param(cmd, "oper_chn"); 233cd4e3c3eSJouni Malinen const char *further_avail_ind = get_param(cmd, "FurtherAvailInd"); 234cd4e3c3eSJouni Malinen const char *band = get_param(cmd, "Band"); 235cd4e3c3eSJouni Malinen const char *only_5g = get_param(cmd, "5GOnly"); 236cd4e3c3eSJouni Malinen struct timespec abstime; 237cd4e3c3eSJouni Malinen NanEnableRequest req; 238cd4e3c3eSJouni Malinen 239cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanEnableRequest)); 240cd4e3c3eSJouni Malinen req.cluster_low = 0; 241cd4e3c3eSJouni Malinen req.cluster_high = 0xFFFF; 242*1854ec6fSAmarnath Hullur Subramanyam req.master_pref = 100; 243cd4e3c3eSJouni Malinen 244*1854ec6fSAmarnath Hullur Subramanyam /* This is a debug hack to beacon in channel 11 */ 245cd4e3c3eSJouni Malinen if (oper_chan) { 246cd4e3c3eSJouni Malinen req.config_2dot4g_support = 1; 247cd4e3c3eSJouni Malinen req.support_2dot4g_val = 111; 248cd4e3c3eSJouni Malinen } 249cd4e3c3eSJouni Malinen 250cd4e3c3eSJouni Malinen if (master_pref) { 251cd4e3c3eSJouni Malinen int master_pref_val = strtoul(master_pref, NULL, 0); 252cd4e3c3eSJouni Malinen 253cd4e3c3eSJouni Malinen req.master_pref = master_pref_val; 254cd4e3c3eSJouni Malinen } 255cd4e3c3eSJouni Malinen 256cd4e3c3eSJouni Malinen if (rand_fac) { 257cd4e3c3eSJouni Malinen int rand_fac_val = strtoul(rand_fac, NULL, 0); 258cd4e3c3eSJouni Malinen 259cd4e3c3eSJouni Malinen req.config_random_factor_force = 1; 260cd4e3c3eSJouni Malinen req.random_factor_force_val = rand_fac_val; 261cd4e3c3eSJouni Malinen } 262cd4e3c3eSJouni Malinen 263cd4e3c3eSJouni Malinen if (hop_count) { 264cd4e3c3eSJouni Malinen int hop_count_val = strtoul(hop_count, NULL, 0); 265cd4e3c3eSJouni Malinen 266cd4e3c3eSJouni Malinen req.config_hop_count_force = 1; 267cd4e3c3eSJouni Malinen req.hop_count_force_val = hop_count_val; 268cd4e3c3eSJouni Malinen } 269cd4e3c3eSJouni Malinen 270cd4e3c3eSJouni Malinen if (sdftx_band) { 271cd4e3c3eSJouni Malinen if (strcasecmp(sdftx_band, "5G") == 0) { 272cd4e3c3eSJouni Malinen req.config_2dot4g_support = 1; 273cd4e3c3eSJouni Malinen req.support_2dot4g_val = 0; 274cd4e3c3eSJouni Malinen } 275cd4e3c3eSJouni Malinen } 276cd4e3c3eSJouni Malinen 277cd4e3c3eSJouni Malinen if (band) { 278cd4e3c3eSJouni Malinen if (strcasecmp(band, "24G") == 0) { 279cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, 280cd4e3c3eSJouni Malinen "Band 2.4GHz selected"); 281cd4e3c3eSJouni Malinen /* Enable 2.4G support */ 282cd4e3c3eSJouni Malinen req.config_2dot4g_support = 1; 283cd4e3c3eSJouni Malinen req.support_2dot4g_val = 1; 284cd4e3c3eSJouni Malinen req.config_2dot4g_beacons = 1; 285cd4e3c3eSJouni Malinen req.beacon_2dot4g_val = 1; 286*1854ec6fSAmarnath Hullur Subramanyam req.config_2dot4g_sdf = 1; 287*1854ec6fSAmarnath Hullur Subramanyam req.sdf_2dot4g_val = 1; 288cd4e3c3eSJouni Malinen 289cd4e3c3eSJouni Malinen /* Disable 5G support */ 290*1854ec6fSAmarnath Hullur Subramanyam req.config_support_5g = 1; 291*1854ec6fSAmarnath Hullur Subramanyam req.support_5g_val = 0; 292cd4e3c3eSJouni Malinen req.config_5g_beacons = 1; 293cd4e3c3eSJouni Malinen req.beacon_5g_val = 0; 294*1854ec6fSAmarnath Hullur Subramanyam req.config_5g_sdf = 1; 295*1854ec6fSAmarnath Hullur Subramanyam req.sdf_5g_val = 0; 296cd4e3c3eSJouni Malinen } 297cd4e3c3eSJouni Malinen } 298cd4e3c3eSJouni Malinen 299cd4e3c3eSJouni Malinen if (further_avail_ind) { 300cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled"); 301cd4e3c3eSJouni Malinen if (strcasecmp(further_avail_ind, "tx") == 0) { 302cd4e3c3eSJouni Malinen is_fam = 1; 303cd4e3c3eSJouni Malinen nan_further_availability_tx(dut, conn, cmd); 304cd4e3c3eSJouni Malinen return 0; 305cd4e3c3eSJouni Malinen } else if (strcasecmp(further_avail_ind, "rx") == 0) { 306cd4e3c3eSJouni Malinen nan_further_availability_rx(dut, conn, cmd); 307cd4e3c3eSJouni Malinen return 0; 308cd4e3c3eSJouni Malinen } 309cd4e3c3eSJouni Malinen } 310cd4e3c3eSJouni Malinen 311cd4e3c3eSJouni Malinen if (only_5g && atoi(only_5g)) { 312cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled"); 313cd4e3c3eSJouni Malinen req.config_2dot4g_support = 1; 314cd4e3c3eSJouni Malinen req.support_2dot4g_val = 1; 315cd4e3c3eSJouni Malinen req.config_2dot4g_beacons = 1; 316cd4e3c3eSJouni Malinen req.beacon_2dot4g_val = 0; 317*1854ec6fSAmarnath Hullur Subramanyam req.config_2dot4g_sdf = 1; 318*1854ec6fSAmarnath Hullur Subramanyam req.sdf_2dot4g_val = 1; 319cd4e3c3eSJouni Malinen } 320cd4e3c3eSJouni Malinen 321*1854ec6fSAmarnath Hullur Subramanyam nan_enable_request(0, global_interface_handle, &req); 322cd4e3c3eSJouni Malinen abstime.tv_sec = 4; 323cd4e3c3eSJouni Malinen abstime.tv_nsec = 0; 324cd4e3c3eSJouni Malinen return wait(abstime); 325cd4e3c3eSJouni Malinen } 326cd4e3c3eSJouni Malinen 327cd4e3c3eSJouni Malinen 328cd4e3c3eSJouni Malinen int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn, 329cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 330cd4e3c3eSJouni Malinen { 331cd4e3c3eSJouni Malinen struct timespec abstime; 332cd4e3c3eSJouni Malinen 333*1854ec6fSAmarnath Hullur Subramanyam nan_disable_request(0, global_interface_handle); 334cd4e3c3eSJouni Malinen 335cd4e3c3eSJouni Malinen abstime.tv_sec = 4; 336cd4e3c3eSJouni Malinen abstime.tv_nsec = 0; 337cd4e3c3eSJouni Malinen return wait(abstime); 338cd4e3c3eSJouni Malinen } 339cd4e3c3eSJouni Malinen 340cd4e3c3eSJouni Malinen 341cd4e3c3eSJouni Malinen int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn, 342cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 343cd4e3c3eSJouni Malinen { 344cd4e3c3eSJouni Malinen const char *master_pref = get_param(cmd, "MasterPref"); 345cd4e3c3eSJouni Malinen const char *rand_fac = get_param(cmd, "RandFactor"); 346cd4e3c3eSJouni Malinen const char *hop_count = get_param(cmd, "HopCount"); 347cd4e3c3eSJouni Malinen struct timespec abstime; 348cd4e3c3eSJouni Malinen NanConfigRequest req; 349cd4e3c3eSJouni Malinen 350cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanConfigRequest)); 351cd4e3c3eSJouni Malinen req.config_rssi_proximity = 1; 352cd4e3c3eSJouni Malinen req.rssi_proximity = 70; 353cd4e3c3eSJouni Malinen 354cd4e3c3eSJouni Malinen if (master_pref) { 355cd4e3c3eSJouni Malinen int master_pref_val = strtoul(master_pref, NULL, 0); 356cd4e3c3eSJouni Malinen 357cd4e3c3eSJouni Malinen req.config_master_pref = 1; 358cd4e3c3eSJouni Malinen req.master_pref = master_pref_val; 359cd4e3c3eSJouni Malinen } 360cd4e3c3eSJouni Malinen 361cd4e3c3eSJouni Malinen if (rand_fac) { 362cd4e3c3eSJouni Malinen int rand_fac_val = strtoul(rand_fac, NULL, 0); 363cd4e3c3eSJouni Malinen 364cd4e3c3eSJouni Malinen req.config_random_factor_force = 1; 365cd4e3c3eSJouni Malinen req.random_factor_force_val = rand_fac_val; 366cd4e3c3eSJouni Malinen } 367cd4e3c3eSJouni Malinen 368cd4e3c3eSJouni Malinen if (hop_count) { 369cd4e3c3eSJouni Malinen int hop_count_val = strtoul(hop_count, NULL, 0); 370cd4e3c3eSJouni Malinen 371cd4e3c3eSJouni Malinen req.config_hop_count_force = 1; 372cd4e3c3eSJouni Malinen req.hop_count_force_val = hop_count_val; 373cd4e3c3eSJouni Malinen } 374cd4e3c3eSJouni Malinen 375*1854ec6fSAmarnath Hullur Subramanyam nan_config_request(0, global_interface_handle, &req); 376cd4e3c3eSJouni Malinen 377cd4e3c3eSJouni Malinen abstime.tv_sec = 4; 378cd4e3c3eSJouni Malinen abstime.tv_nsec = 0; 379cd4e3c3eSJouni Malinen 380cd4e3c3eSJouni Malinen return wait(abstime); 381cd4e3c3eSJouni Malinen } 382cd4e3c3eSJouni Malinen 383cd4e3c3eSJouni Malinen 384cd4e3c3eSJouni Malinen static int sigma_nan_subscribe_request(struct sigma_dut *dut, 385cd4e3c3eSJouni Malinen struct sigma_conn *conn, 386cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 387cd4e3c3eSJouni Malinen { 388cd4e3c3eSJouni Malinen const char *subscribe_type = get_param(cmd, "SubscribeType"); 389cd4e3c3eSJouni Malinen const char *service_name = get_param(cmd, "ServiceName"); 390cd4e3c3eSJouni Malinen const char *disc_range = get_param(cmd, "DiscoveryRange"); 391cd4e3c3eSJouni Malinen const char *rx_match_filter = get_param(cmd, "rxMatchFilter"); 392cd4e3c3eSJouni Malinen const char *tx_match_filter = get_param(cmd, "txMatchFilter"); 393cd4e3c3eSJouni Malinen const char *sdftx_dw = get_param(cmd, "SDFTxDW"); 394cd4e3c3eSJouni Malinen const char *discrange_ltd = get_param(cmd, "DiscRangeLtd"); 395cd4e3c3eSJouni Malinen const char *include_bit = get_param(cmd, "IncludeBit"); 396cd4e3c3eSJouni Malinen const char *mac = get_param(cmd, "MAC"); 397cd4e3c3eSJouni Malinen const char *srf_type = get_param(cmd, "SRFType"); 398cd4e3c3eSJouni Malinen NanSubscribeRequest req; 399cd4e3c3eSJouni Malinen int filter_len_rx = 0, filter_len_tx = 0; 400cd4e3c3eSJouni Malinen u8 input_rx[NAN_MAX_MATCH_FILTER_LEN]; 401cd4e3c3eSJouni Malinen u8 input_tx[NAN_MAX_MATCH_FILTER_LEN]; 402cd4e3c3eSJouni Malinen 403cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanSubscribeRequest)); 404cd4e3c3eSJouni Malinen req.ttl = 0; 405cd4e3c3eSJouni Malinen req.period = 1000; 406cd4e3c3eSJouni Malinen req.subscribe_type = 1; 407cd4e3c3eSJouni Malinen req.serviceResponseFilter = 1; /* MAC */ 408cd4e3c3eSJouni Malinen req.serviceResponseInclude = 0; 409cd4e3c3eSJouni Malinen req.ssiRequiredForMatchIndication = 0; 410*1854ec6fSAmarnath Hullur Subramanyam req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS; 411cd4e3c3eSJouni Malinen req.subscribe_count = 0; 412cd4e3c3eSJouni Malinen 413cd4e3c3eSJouni Malinen if (subscribe_type) { 414cd4e3c3eSJouni Malinen if (strcasecmp(subscribe_type, "Active") == 0) { 415cd4e3c3eSJouni Malinen req.subscribe_type = 1; 416cd4e3c3eSJouni Malinen } else if (strcasecmp(subscribe_type, "Passive") == 0) { 417cd4e3c3eSJouni Malinen req.subscribe_type = 0; 418cd4e3c3eSJouni Malinen } else if (strcasecmp(subscribe_type, "Cancel") == 0) { 419cd4e3c3eSJouni Malinen NanSubscribeCancelRequest req; 420cd4e3c3eSJouni Malinen 421cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanSubscribeCancelRequest)); 422*1854ec6fSAmarnath Hullur Subramanyam nan_subscribe_cancel_request(0, global_interface_handle, 423*1854ec6fSAmarnath Hullur Subramanyam &req); 424cd4e3c3eSJouni Malinen return 0; 425cd4e3c3eSJouni Malinen } 426cd4e3c3eSJouni Malinen } 427cd4e3c3eSJouni Malinen 428cd4e3c3eSJouni Malinen if (disc_range) 429cd4e3c3eSJouni Malinen req.rssi_threshold_flag = atoi(disc_range); 430cd4e3c3eSJouni Malinen 431cd4e3c3eSJouni Malinen if (sdftx_dw) 432cd4e3c3eSJouni Malinen req.subscribe_count = atoi(sdftx_dw); 433cd4e3c3eSJouni Malinen 434cd4e3c3eSJouni Malinen /* Check this once again if config can be called here (TBD) */ 435cd4e3c3eSJouni Malinen if (discrange_ltd) 436cd4e3c3eSJouni Malinen req.rssi_threshold_flag = atoi(discrange_ltd); 437cd4e3c3eSJouni Malinen 438cd4e3c3eSJouni Malinen if (include_bit) { 439cd4e3c3eSJouni Malinen int include_bit_val = atoi(include_bit); 440cd4e3c3eSJouni Malinen 441cd4e3c3eSJouni Malinen req.serviceResponseInclude = include_bit_val; 442cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d", 443cd4e3c3eSJouni Malinen req.serviceResponseInclude); 444cd4e3c3eSJouni Malinen } 445cd4e3c3eSJouni Malinen 446cd4e3c3eSJouni Malinen if (srf_type) { 447cd4e3c3eSJouni Malinen int srf_type_val = atoi(srf_type); 448cd4e3c3eSJouni Malinen 449cd4e3c3eSJouni Malinen if (srf_type_val == 1) 450cd4e3c3eSJouni Malinen req.serviceResponseFilter = 0; /* Bloom */ 451cd4e3c3eSJouni Malinen else 452cd4e3c3eSJouni Malinen req.serviceResponseFilter = 1; /* MAC */ 453cd4e3c3eSJouni Malinen req.useServiceResponseFilter = 1; 454cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d", 455cd4e3c3eSJouni Malinen req.serviceResponseFilter); 456cd4e3c3eSJouni Malinen } 457cd4e3c3eSJouni Malinen 458cd4e3c3eSJouni Malinen if (mac) { 459cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac); 460cd4e3c3eSJouni Malinen req.num_intf_addr_present = nan_parse_mac_address_list( 461cd4e3c3eSJouni Malinen dut, mac, &req.intf_addr[0][0], 462cd4e3c3eSJouni Malinen NAN_MAX_SUBSCRIBE_MAX_ADDRESS); 463cd4e3c3eSJouni Malinen } 464cd4e3c3eSJouni Malinen 465cd4e3c3eSJouni Malinen memset(input_rx, 0, sizeof(input_rx)); 466cd4e3c3eSJouni Malinen memset(input_tx, 0, sizeof(input_tx)); 467cd4e3c3eSJouni Malinen if (rx_match_filter) { 468cd4e3c3eSJouni Malinen nan_parse_token(rx_match_filter, input_rx, &filter_len_rx); 469cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d", 470cd4e3c3eSJouni Malinen filter_len_rx); 471cd4e3c3eSJouni Malinen } 472cd4e3c3eSJouni Malinen if (tx_match_filter) { 473cd4e3c3eSJouni Malinen nan_parse_token(tx_match_filter, input_tx, &filter_len_tx); 474cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d", 475cd4e3c3eSJouni Malinen filter_len_tx); 476cd4e3c3eSJouni Malinen } 477cd4e3c3eSJouni Malinen 478cd4e3c3eSJouni Malinen if (tx_match_filter) { 479cd4e3c3eSJouni Malinen req.tx_match_filter_len = filter_len_tx; 480cd4e3c3eSJouni Malinen memcpy(req.tx_match_filter, input_tx, filter_len_tx); 481cd4e3c3eSJouni Malinen nan_hex_dump(dut, req.tx_match_filter, filter_len_tx); 482cd4e3c3eSJouni Malinen } 483cd4e3c3eSJouni Malinen if (rx_match_filter) { 484cd4e3c3eSJouni Malinen req.rx_match_filter_len = filter_len_rx; 485cd4e3c3eSJouni Malinen memcpy(req.rx_match_filter, input_rx, filter_len_rx); 486cd4e3c3eSJouni Malinen nan_hex_dump(dut, req.rx_match_filter, filter_len_rx); 487cd4e3c3eSJouni Malinen } 488cd4e3c3eSJouni Malinen 489cd4e3c3eSJouni Malinen strlcpy((char *) req.service_name, service_name, 490cd4e3c3eSJouni Malinen strlen(service_name) + 1); 491cd4e3c3eSJouni Malinen req.service_name_len = strlen(service_name); 492cd4e3c3eSJouni Malinen 493*1854ec6fSAmarnath Hullur Subramanyam nan_subscribe_request(0, global_interface_handle, &req); 494cd4e3c3eSJouni Malinen return 0; 495cd4e3c3eSJouni Malinen } 496cd4e3c3eSJouni Malinen 497cd4e3c3eSJouni Malinen 498cd4e3c3eSJouni Malinen int config_post_disc_attr(void) 499cd4e3c3eSJouni Malinen { 500cd4e3c3eSJouni Malinen NanConfigRequest configReq; 501cd4e3c3eSJouni Malinen 502cd4e3c3eSJouni Malinen memset(&configReq, 0, sizeof(NanConfigRequest)); 503cd4e3c3eSJouni Malinen 504cd4e3c3eSJouni Malinen /* Configure Post disc attr */ 505cd4e3c3eSJouni Malinen /* Make these defines and use correct enum */ 506*1854ec6fSAmarnath Hullur Subramanyam configReq.num_config_discovery_attr = 1; 507*1854ec6fSAmarnath Hullur Subramanyam configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */ 508*1854ec6fSAmarnath Hullur Subramanyam configReq.discovery_attr_val[0].role = 0; 509*1854ec6fSAmarnath Hullur Subramanyam configReq.discovery_attr_val[0].transmit_freq = 1; 510*1854ec6fSAmarnath Hullur Subramanyam configReq.discovery_attr_val[0].duration = 0; 511*1854ec6fSAmarnath Hullur Subramanyam configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008; 512cd4e3c3eSJouni Malinen 513*1854ec6fSAmarnath Hullur Subramanyam nan_config_request(0, global_interface_handle, &configReq); 514cd4e3c3eSJouni Malinen return 0; 515cd4e3c3eSJouni Malinen } 516cd4e3c3eSJouni Malinen 517cd4e3c3eSJouni Malinen 518cd4e3c3eSJouni Malinen int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn, 519cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 520cd4e3c3eSJouni Malinen { 521cd4e3c3eSJouni Malinen const char *publish_type = get_param(cmd, "PublishType"); 522cd4e3c3eSJouni Malinen const char *service_name = get_param(cmd, "ServiceName"); 523cd4e3c3eSJouni Malinen const char *disc_range = get_param(cmd, "DiscoveryRange"); 524cd4e3c3eSJouni Malinen const char *rx_match_filter = get_param(cmd, "rxMatchFilter"); 525cd4e3c3eSJouni Malinen const char *tx_match_filter = get_param(cmd, "txMatchFilter"); 526cd4e3c3eSJouni Malinen const char *sdftx_dw = get_param(cmd, "SDFTxDW"); 527cd4e3c3eSJouni Malinen const char *discrange_ltd = get_param(cmd, "DiscRangeLtd"); 528cd4e3c3eSJouni Malinen NanPublishRequest req; 529cd4e3c3eSJouni Malinen int filter_len_rx = 0, filter_len_tx = 0; 530cd4e3c3eSJouni Malinen u8 input_rx[NAN_MAX_MATCH_FILTER_LEN]; 531cd4e3c3eSJouni Malinen u8 input_tx[NAN_MAX_MATCH_FILTER_LEN]; 532cd4e3c3eSJouni Malinen 533cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanPublishRequest)); 534cd4e3c3eSJouni Malinen req.ttl = 0; 535cd4e3c3eSJouni Malinen req.period = 500; 536*1854ec6fSAmarnath Hullur Subramanyam req.publish_match_indicator = 1; 537cd4e3c3eSJouni Malinen req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED; 538cd4e3c3eSJouni Malinen req.tx_type = NAN_TX_TYPE_BROADCAST; 539cd4e3c3eSJouni Malinen req.publish_count = 0; 540cd4e3c3eSJouni Malinen strlcpy((char *) req.service_name, service_name, 541cd4e3c3eSJouni Malinen strlen(service_name) + 1); 542cd4e3c3eSJouni Malinen req.service_name_len = strlen(service_name); 543cd4e3c3eSJouni Malinen 544cd4e3c3eSJouni Malinen if (publish_type) { 545cd4e3c3eSJouni Malinen if (strcasecmp(publish_type, "Solicited") == 0) { 546cd4e3c3eSJouni Malinen req.publish_type = NAN_PUBLISH_TYPE_SOLICITED; 547cd4e3c3eSJouni Malinen } else if (strcasecmp(publish_type, "Cancel") == 0) { 548cd4e3c3eSJouni Malinen NanPublishCancelRequest req; 549cd4e3c3eSJouni Malinen 550cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanPublishCancelRequest)); 551*1854ec6fSAmarnath Hullur Subramanyam nan_publish_cancel_request(0, global_interface_handle, 552*1854ec6fSAmarnath Hullur Subramanyam &req); 553cd4e3c3eSJouni Malinen return 0; 554cd4e3c3eSJouni Malinen } 555cd4e3c3eSJouni Malinen } 556cd4e3c3eSJouni Malinen 557cd4e3c3eSJouni Malinen if (disc_range) 558cd4e3c3eSJouni Malinen req.rssi_threshold_flag = atoi(disc_range); 559cd4e3c3eSJouni Malinen 560cd4e3c3eSJouni Malinen if (sdftx_dw) 561cd4e3c3eSJouni Malinen req.publish_count = atoi(sdftx_dw); 562cd4e3c3eSJouni Malinen 563cd4e3c3eSJouni Malinen if (discrange_ltd) 564cd4e3c3eSJouni Malinen req.rssi_threshold_flag = atoi(discrange_ltd); 565cd4e3c3eSJouni Malinen 566cd4e3c3eSJouni Malinen memset(input_rx, 0, sizeof(input_rx)); 567cd4e3c3eSJouni Malinen memset(input_tx, 0, sizeof(input_tx)); 568cd4e3c3eSJouni Malinen if (rx_match_filter) { 569cd4e3c3eSJouni Malinen nan_parse_token(rx_match_filter, input_rx, &filter_len_rx); 570cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d", 571cd4e3c3eSJouni Malinen filter_len_rx); 572cd4e3c3eSJouni Malinen } 573cd4e3c3eSJouni Malinen if (tx_match_filter) { 574cd4e3c3eSJouni Malinen nan_parse_token(tx_match_filter, input_tx, &filter_len_tx); 575cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d", 576cd4e3c3eSJouni Malinen filter_len_tx); 577cd4e3c3eSJouni Malinen } 578cd4e3c3eSJouni Malinen 579cd4e3c3eSJouni Malinen if (is_fam == 1) { 580cd4e3c3eSJouni Malinen config_post_disc_attr(); 581cd4e3c3eSJouni Malinen /* TODO: Add comments regarding this step */ 582cd4e3c3eSJouni Malinen req.connmap = 0x10; 583cd4e3c3eSJouni Malinen } 584cd4e3c3eSJouni Malinen 585cd4e3c3eSJouni Malinen if (tx_match_filter) { 586cd4e3c3eSJouni Malinen req.tx_match_filter_len = filter_len_tx; 587cd4e3c3eSJouni Malinen memcpy(req.tx_match_filter, input_tx, filter_len_tx); 588cd4e3c3eSJouni Malinen nan_hex_dump(dut, req.tx_match_filter, filter_len_tx); 589cd4e3c3eSJouni Malinen } 590cd4e3c3eSJouni Malinen 591cd4e3c3eSJouni Malinen if (rx_match_filter) { 592cd4e3c3eSJouni Malinen req.rx_match_filter_len = filter_len_rx; 593cd4e3c3eSJouni Malinen memcpy(req.rx_match_filter, input_rx, filter_len_rx); 594cd4e3c3eSJouni Malinen nan_hex_dump(dut, req.rx_match_filter, filter_len_rx); 595cd4e3c3eSJouni Malinen } 596cd4e3c3eSJouni Malinen strlcpy((char *) req.service_name, service_name, 597cd4e3c3eSJouni Malinen strlen(service_name) + 1); 598cd4e3c3eSJouni Malinen req.service_name_len = strlen(service_name); 599cd4e3c3eSJouni Malinen 600*1854ec6fSAmarnath Hullur Subramanyam nan_publish_request(0, global_interface_handle, &req); 601cd4e3c3eSJouni Malinen 602cd4e3c3eSJouni Malinen return 0; 603cd4e3c3eSJouni Malinen } 604cd4e3c3eSJouni Malinen 605cd4e3c3eSJouni Malinen 606cd4e3c3eSJouni Malinen static int nan_further_availability_rx(struct sigma_dut *dut, 607cd4e3c3eSJouni Malinen struct sigma_conn *conn, 608cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 609cd4e3c3eSJouni Malinen { 610cd4e3c3eSJouni Malinen const char *master_pref = get_param(cmd, "MasterPref"); 611cd4e3c3eSJouni Malinen const char *rand_fac = get_param(cmd, "RandFactor"); 612cd4e3c3eSJouni Malinen const char *hop_count = get_param(cmd, "HopCount"); 613cd4e3c3eSJouni Malinen struct timespec abstime; 614cd4e3c3eSJouni Malinen 615cd4e3c3eSJouni Malinen NanEnableRequest req; 616cd4e3c3eSJouni Malinen 617cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanEnableRequest)); 618cd4e3c3eSJouni Malinen req.cluster_low = 0; 619cd4e3c3eSJouni Malinen req.cluster_high = 0xFFFF; 620cd4e3c3eSJouni Malinen req.master_pref = 30; 621cd4e3c3eSJouni Malinen 622cd4e3c3eSJouni Malinen if (master_pref) 623cd4e3c3eSJouni Malinen req.master_pref = strtoul(master_pref, NULL, 0); 624cd4e3c3eSJouni Malinen 625cd4e3c3eSJouni Malinen if (rand_fac) { 626cd4e3c3eSJouni Malinen int rand_fac_val = strtoul(rand_fac, NULL, 0); 627cd4e3c3eSJouni Malinen 628cd4e3c3eSJouni Malinen req.config_random_factor_force = 1; 629cd4e3c3eSJouni Malinen req.random_factor_force_val = rand_fac_val; 630cd4e3c3eSJouni Malinen } 631cd4e3c3eSJouni Malinen 632cd4e3c3eSJouni Malinen if (hop_count) { 633cd4e3c3eSJouni Malinen int hop_count_val = strtoul(hop_count, NULL, 0); 634cd4e3c3eSJouni Malinen 635cd4e3c3eSJouni Malinen req.config_hop_count_force = 1; 636cd4e3c3eSJouni Malinen req.hop_count_force_val = hop_count_val; 637cd4e3c3eSJouni Malinen } 638cd4e3c3eSJouni Malinen 639*1854ec6fSAmarnath Hullur Subramanyam nan_enable_request(0, global_interface_handle, &req); 640cd4e3c3eSJouni Malinen abstime.tv_sec = 4; 641cd4e3c3eSJouni Malinen abstime.tv_nsec = 0; 642cd4e3c3eSJouni Malinen 643cd4e3c3eSJouni Malinen wait(abstime); 644cd4e3c3eSJouni Malinen return 0; 645cd4e3c3eSJouni Malinen } 646cd4e3c3eSJouni Malinen 647cd4e3c3eSJouni Malinen 648cd4e3c3eSJouni Malinen static int nan_further_availability_tx(struct sigma_dut *dut, 649cd4e3c3eSJouni Malinen struct sigma_conn *conn, 650cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 651cd4e3c3eSJouni Malinen { 652cd4e3c3eSJouni Malinen const char *master_pref = get_param(cmd, "MasterPref"); 653cd4e3c3eSJouni Malinen const char *rand_fac = get_param(cmd, "RandFactor"); 654cd4e3c3eSJouni Malinen const char *hop_count = get_param(cmd, "HopCount"); 655cd4e3c3eSJouni Malinen NanEnableRequest req; 656cd4e3c3eSJouni Malinen NanConfigRequest configReq; 657cd4e3c3eSJouni Malinen 658cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanEnableRequest)); 659cd4e3c3eSJouni Malinen req.cluster_low = 0; 660cd4e3c3eSJouni Malinen req.cluster_high = 0xFFFF; 661cd4e3c3eSJouni Malinen req.master_pref = 30; 662cd4e3c3eSJouni Malinen 663cd4e3c3eSJouni Malinen if (master_pref) 664cd4e3c3eSJouni Malinen req.master_pref = strtoul(master_pref, NULL, 0); 665cd4e3c3eSJouni Malinen 666cd4e3c3eSJouni Malinen if (rand_fac) { 667cd4e3c3eSJouni Malinen int rand_fac_val = strtoul(rand_fac, NULL, 0); 668cd4e3c3eSJouni Malinen 669cd4e3c3eSJouni Malinen req.config_random_factor_force = 1; 670cd4e3c3eSJouni Malinen req.random_factor_force_val = rand_fac_val; 671cd4e3c3eSJouni Malinen } 672cd4e3c3eSJouni Malinen 673cd4e3c3eSJouni Malinen if (hop_count) { 674cd4e3c3eSJouni Malinen int hop_count_val = strtoul(hop_count, NULL, 0); 675cd4e3c3eSJouni Malinen 676cd4e3c3eSJouni Malinen req.config_hop_count_force = 1; 677cd4e3c3eSJouni Malinen req.hop_count_force_val = hop_count_val; 678cd4e3c3eSJouni Malinen } 679cd4e3c3eSJouni Malinen 680*1854ec6fSAmarnath Hullur Subramanyam nan_enable_request(0, global_interface_handle, &req); 681cd4e3c3eSJouni Malinen 682cd4e3c3eSJouni Malinen /* Start the config of fam */ 683cd4e3c3eSJouni Malinen 684cd4e3c3eSJouni Malinen memset(&configReq, 0, sizeof(NanConfigRequest)); 685cd4e3c3eSJouni Malinen 686cd4e3c3eSJouni Malinen configReq.config_fam = 1; 687cd4e3c3eSJouni Malinen configReq.fam_val.numchans = 1; 688*1854ec6fSAmarnath Hullur Subramanyam configReq.fam_val.famchan[0].entry_control = 0; 689*1854ec6fSAmarnath Hullur Subramanyam configReq.fam_val.famchan[0].class_val = 81; 690*1854ec6fSAmarnath Hullur Subramanyam configReq.fam_val.famchan[0].channel = 6; 691*1854ec6fSAmarnath Hullur Subramanyam configReq.fam_val.famchan[0].mapid = 0; 692*1854ec6fSAmarnath Hullur Subramanyam configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe; 693*1854ec6fSAmarnath Hullur Subramanyam 694*1854ec6fSAmarnath Hullur Subramanyam nan_config_request(0, global_interface_handle, &configReq); 695cd4e3c3eSJouni Malinen 696cd4e3c3eSJouni Malinen return 0; 697cd4e3c3eSJouni Malinen } 698cd4e3c3eSJouni Malinen 699cd4e3c3eSJouni Malinen 700cd4e3c3eSJouni Malinen int sigma_nan_transmit_followup(struct sigma_dut *dut, 701cd4e3c3eSJouni Malinen struct sigma_conn *conn, 702cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 703cd4e3c3eSJouni Malinen { 704cd4e3c3eSJouni Malinen const char *mac = get_param(cmd, "mac"); 705cd4e3c3eSJouni Malinen const char *requestor_id = get_param(cmd, "RemoteInstanceId"); 706cd4e3c3eSJouni Malinen const char *local_id = get_param(cmd, "LocalInstanceId"); 707cd4e3c3eSJouni Malinen const char *service_name = get_param(cmd, "servicename"); 708cd4e3c3eSJouni Malinen NanTransmitFollowupRequest req; 709cd4e3c3eSJouni Malinen 710cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanTransmitFollowupRequest)); 711*1854ec6fSAmarnath Hullur Subramanyam req.requestor_instance_id = global_match_handle; 712cd4e3c3eSJouni Malinen req.addr[0] = 0xFF; 713cd4e3c3eSJouni Malinen req.addr[1] = 0xFF; 714cd4e3c3eSJouni Malinen req.addr[2] = 0xFF; 715cd4e3c3eSJouni Malinen req.addr[3] = 0xFF; 716cd4e3c3eSJouni Malinen req.addr[4] = 0xFF; 717cd4e3c3eSJouni Malinen req.addr[5] = 0xFF; 718cd4e3c3eSJouni Malinen req.priority = NAN_TX_PRIORITY_NORMAL; 719cd4e3c3eSJouni Malinen req.dw_or_faw = 0; 720cd4e3c3eSJouni Malinen req.service_specific_info_len = strlen(service_name); 721cd4e3c3eSJouni Malinen 722cd4e3c3eSJouni Malinen if (requestor_id) { 723cd4e3c3eSJouni Malinen /* int requestor_id_val = atoi(requestor_id); */ 724*1854ec6fSAmarnath Hullur Subramanyam req.requestor_instance_id = global_match_handle; 725cd4e3c3eSJouni Malinen } 726cd4e3c3eSJouni Malinen if (local_id) { 727cd4e3c3eSJouni Malinen /* int local_id_val = atoi(local_id); */ 728*1854ec6fSAmarnath Hullur Subramanyam req.publish_subscribe_id = global_header_handle; 729cd4e3c3eSJouni Malinen } 730cd4e3c3eSJouni Malinen 731cd4e3c3eSJouni Malinen if (mac == NULL) { 732cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address"); 733cd4e3c3eSJouni Malinen return -1; 734cd4e3c3eSJouni Malinen } 735cd4e3c3eSJouni Malinen nan_parse_mac_address(dut, mac, req.addr); 736cd4e3c3eSJouni Malinen 737cd4e3c3eSJouni Malinen if (requestor_id) 738*1854ec6fSAmarnath Hullur Subramanyam req.requestor_instance_id = strtoul(requestor_id, NULL, 0); 739cd4e3c3eSJouni Malinen 740*1854ec6fSAmarnath Hullur Subramanyam 741*1854ec6fSAmarnath Hullur Subramanyam nan_transmit_followup_request(0, global_interface_handle, &req); 742cd4e3c3eSJouni Malinen return 0; 743cd4e3c3eSJouni Malinen } 744cd4e3c3eSJouni Malinen 745cd4e3c3eSJouni Malinen /* NotifyResponse invoked to notify the status of the Request */ 746*1854ec6fSAmarnath Hullur Subramanyam void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data) 747cd4e3c3eSJouni Malinen { 748cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 749*1854ec6fSAmarnath Hullur Subramanyam "%s: status %d value %d response_type %d", 750*1854ec6fSAmarnath Hullur Subramanyam __func__, 751cd4e3c3eSJouni Malinen rsp_data->status, rsp_data->value, 752cd4e3c3eSJouni Malinen rsp_data->response_type); 753cd4e3c3eSJouni Malinen if (rsp_data->response_type == NAN_RESPONSE_STATS) { 754*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: stats_type %d", 755cd4e3c3eSJouni Malinen __func__, 756*1854ec6fSAmarnath Hullur Subramanyam rsp_data->body.stats_response.stats_type); 757cd4e3c3eSJouni Malinen } 758cd4e3c3eSJouni Malinen #if 0 759cd4e3c3eSJouni Malinen if (rsp_data->response_type == NAN_RESPONSE_CONFIG && 760cd4e3c3eSJouni Malinen rsp_data->status == 0) 761cd4e3c3eSJouni Malinen pthread_cond_signal(&gCondition); 762cd4e3c3eSJouni Malinen #endif 763cd4e3c3eSJouni Malinen } 764cd4e3c3eSJouni Malinen 765cd4e3c3eSJouni Malinen 766cd4e3c3eSJouni Malinen /* Events Callback */ 767cd4e3c3eSJouni Malinen void nan_event_publish_replied(NanPublishRepliedInd *event) 768cd4e3c3eSJouni Malinen { 769cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 770cd4e3c3eSJouni Malinen "%s: handle %d " MAC_ADDR_STR " rssi:%d", 771*1854ec6fSAmarnath Hullur Subramanyam __func__, event->requestor_instance_id, 772cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(event->addr), event->rssi_value); 773cd4e3c3eSJouni Malinen event_anyresponse = 1; 774cd4e3c3eSJouni Malinen snprintf(global_event_resp_buf, sizeof(global_event_resp_buf), 775*1854ec6fSAmarnath Hullur Subramanyam "EventName,Replied,RemoteInstanceID %d,mac," MAC_ADDR_STR, 776*1854ec6fSAmarnath Hullur Subramanyam (event->requestor_instance_id >> 24), 777*1854ec6fSAmarnath Hullur Subramanyam MAC_ADDR_ARRAY(event->addr)); 778cd4e3c3eSJouni Malinen } 779cd4e3c3eSJouni Malinen 780cd4e3c3eSJouni Malinen 781cd4e3c3eSJouni Malinen /* Events Callback */ 782cd4e3c3eSJouni Malinen void nan_event_publish_terminated(NanPublishTerminatedInd *event) 783cd4e3c3eSJouni Malinen { 784*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d", 785*1854ec6fSAmarnath Hullur Subramanyam __func__, event->publish_id, event->reason); 786cd4e3c3eSJouni Malinen } 787cd4e3c3eSJouni Malinen 788cd4e3c3eSJouni Malinen 789cd4e3c3eSJouni Malinen /* Events Callback */ 790cd4e3c3eSJouni Malinen void nan_event_match(NanMatchInd *event) 791cd4e3c3eSJouni Malinen { 792cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 793*1854ec6fSAmarnath Hullur Subramanyam "%s: Pub/Sub Id %d remote_requestor_id %08x " 794*1854ec6fSAmarnath Hullur Subramanyam MAC_ADDR_STR 795cd4e3c3eSJouni Malinen " rssi:%d", 796cd4e3c3eSJouni Malinen __func__, 797*1854ec6fSAmarnath Hullur Subramanyam event->publish_subscribe_id, 798*1854ec6fSAmarnath Hullur Subramanyam event->requestor_instance_id, 799cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(event->addr), 800cd4e3c3eSJouni Malinen event->rssi_value); 801cd4e3c3eSJouni Malinen event_anyresponse = 1; 802*1854ec6fSAmarnath Hullur Subramanyam global_header_handle = event->publish_subscribe_id; 803*1854ec6fSAmarnath Hullur Subramanyam global_match_handle = event->requestor_instance_id; 804*1854ec6fSAmarnath Hullur Subramanyam 805cd4e3c3eSJouni Malinen /* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */ 806cd4e3c3eSJouni Malinen /* global_pub_sub_handle = event->header.handle; */ 807cd4e3c3eSJouni Malinen /* Print the SSI */ 808cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:"); 809*1854ec6fSAmarnath Hullur Subramanyam nan_hex_dump(global_dut, event->service_specific_info, 810cd4e3c3eSJouni Malinen event->service_specific_info_len); 811cd4e3c3eSJouni Malinen snprintf(global_event_resp_buf, sizeof(global_event_resp_buf), 812cd4e3c3eSJouni Malinen "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac," 813*1854ec6fSAmarnath Hullur Subramanyam MAC_ADDR_STR " ", (event->requestor_instance_id >> 24), 814*1854ec6fSAmarnath Hullur Subramanyam event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr)); 815cd4e3c3eSJouni Malinen 816cd4e3c3eSJouni Malinen /* Print the match filter */ 817cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:"); 818*1854ec6fSAmarnath Hullur Subramanyam nan_hex_dump(global_dut, event->sdf_match_filter, 819*1854ec6fSAmarnath Hullur Subramanyam event->sdf_match_filter_len); 820cd4e3c3eSJouni Malinen 821cd4e3c3eSJouni Malinen /* Print the conn_capability */ 822cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 823cd4e3c3eSJouni Malinen "Printing PostConnectivity Capability"); 824cd4e3c3eSJouni Malinen if (event->is_conn_capability_valid) { 825cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s", 826cd4e3c3eSJouni Malinen event->conn_capability.is_wfd_supported ? 827cd4e3c3eSJouni Malinen "yes" : "no"); 828cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s", 829cd4e3c3eSJouni Malinen (event->conn_capability.is_wfds_supported ? 830cd4e3c3eSJouni Malinen "yes" : "no")); 831cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s", 832cd4e3c3eSJouni Malinen (event->conn_capability.is_tdls_supported ? 833cd4e3c3eSJouni Malinen "yes" : "no")); 834cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s", 835cd4e3c3eSJouni Malinen (event->conn_capability.is_ibss_supported ? 836cd4e3c3eSJouni Malinen "yes" : "no")); 837cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s", 838cd4e3c3eSJouni Malinen (event->conn_capability.is_mesh_supported ? 839cd4e3c3eSJouni Malinen "yes" : "no")); 840cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d", 841cd4e3c3eSJouni Malinen event->conn_capability.wlan_infra_field); 842cd4e3c3eSJouni Malinen } else { 843cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 844cd4e3c3eSJouni Malinen "PostConnectivity Capability not present"); 845cd4e3c3eSJouni Malinen } 846cd4e3c3eSJouni Malinen 847cd4e3c3eSJouni Malinen /* Print the discovery_attr */ 848cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 849cd4e3c3eSJouni Malinen "Printing PostDiscovery Attribute"); 850*1854ec6fSAmarnath Hullur Subramanyam if (event->num_rx_discovery_attr) { 851*1854ec6fSAmarnath Hullur Subramanyam int idx; 852*1854ec6fSAmarnath Hullur Subramanyam 853*1854ec6fSAmarnath Hullur Subramanyam for (idx = 0; idx < event->num_rx_discovery_attr; idx++) { 854*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 855*1854ec6fSAmarnath Hullur Subramanyam "PostDiscovery Attribute - %d", idx); 856cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 857cd4e3c3eSJouni Malinen "Conn Type:%d Device Role:%d" 858cd4e3c3eSJouni Malinen MAC_ADDR_STR, 859*1854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].type, 860*1854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].role, 861*1854ec6fSAmarnath Hullur Subramanyam MAC_ADDR_ARRAY(event->discovery_attr[idx].addr)); 862*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 863*1854ec6fSAmarnath Hullur Subramanyam "Duration:%d MapId:%d " 864*1854ec6fSAmarnath Hullur Subramanyam "avail_interval_bitmap:%04x", 865*1854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].duration, 866*1854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].mapid, 867*1854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].avail_interval_bitmap); 868cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 869cd4e3c3eSJouni Malinen "Printing Mesh Id:"); 870*1854ec6fSAmarnath Hullur Subramanyam nan_hex_dump(global_dut, 871*1854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].mesh_id, 872*1854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].mesh_id_len); 873*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 874*1854ec6fSAmarnath Hullur Subramanyam "Printing Infrastructure Ssid:"); 875*1854ec6fSAmarnath Hullur Subramanyam nan_hex_dump(global_dut, 876*1854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].infrastructure_ssid_val, 877*1854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].infrastructure_ssid_len); 878*1854ec6fSAmarnath Hullur Subramanyam } 879cd4e3c3eSJouni Malinen } else { 880cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 881cd4e3c3eSJouni Malinen "PostDiscovery attribute not present"); 882cd4e3c3eSJouni Malinen } 883cd4e3c3eSJouni Malinen 884cd4e3c3eSJouni Malinen /* Print the fam */ 885*1854ec6fSAmarnath Hullur Subramanyam if (event->num_chans) { 886*1854ec6fSAmarnath Hullur Subramanyam nan_print_further_availability_chan(global_dut, 887*1854ec6fSAmarnath Hullur Subramanyam event->num_chans, 888*1854ec6fSAmarnath Hullur Subramanyam &event->famchan[0]); 889*1854ec6fSAmarnath Hullur Subramanyam } else { 890*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 891*1854ec6fSAmarnath Hullur Subramanyam "Further Availability Map not present"); 892*1854ec6fSAmarnath Hullur Subramanyam } 893*1854ec6fSAmarnath Hullur Subramanyam if (event->cluster_attribute_len) { 894*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 895*1854ec6fSAmarnath Hullur Subramanyam "Printing Cluster Attribute:"); 896*1854ec6fSAmarnath Hullur Subramanyam nan_hex_dump(global_dut, event->cluster_attribute, 897*1854ec6fSAmarnath Hullur Subramanyam event->cluster_attribute_len); 898*1854ec6fSAmarnath Hullur Subramanyam } else { 899*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 900*1854ec6fSAmarnath Hullur Subramanyam "Cluster Attribute not present"); 901cd4e3c3eSJouni Malinen } 902cd4e3c3eSJouni Malinen } 903cd4e3c3eSJouni Malinen 904cd4e3c3eSJouni Malinen 905cd4e3c3eSJouni Malinen /* Events Callback */ 906*1854ec6fSAmarnath Hullur Subramanyam void nan_event_match_expired(NanMatchExpiredInd *event) 907cd4e3c3eSJouni Malinen { 908cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 909*1854ec6fSAmarnath Hullur Subramanyam "%s: publish_subscribe_id %d match_handle %08x", 910*1854ec6fSAmarnath Hullur Subramanyam __func__, event->publish_subscribe_id, 911*1854ec6fSAmarnath Hullur Subramanyam event->requestor_instance_id); 912cd4e3c3eSJouni Malinen } 913cd4e3c3eSJouni Malinen 914cd4e3c3eSJouni Malinen 915cd4e3c3eSJouni Malinen /* Events Callback */ 916cd4e3c3eSJouni Malinen void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event) 917cd4e3c3eSJouni Malinen { 918*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 919*1854ec6fSAmarnath Hullur Subramanyam "%s: Subscribe Id %d reason %d", 920*1854ec6fSAmarnath Hullur Subramanyam __func__, event->subscribe_id, event->reason); 921cd4e3c3eSJouni Malinen } 922cd4e3c3eSJouni Malinen 923cd4e3c3eSJouni Malinen 924cd4e3c3eSJouni Malinen /* Events Callback */ 925cd4e3c3eSJouni Malinen void nan_event_followup(NanFollowupInd *event) 926cd4e3c3eSJouni Malinen { 927cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 928*1854ec6fSAmarnath Hullur Subramanyam "%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d " 929*1854ec6fSAmarnath Hullur Subramanyam MAC_ADDR_STR, __func__, event->publish_subscribe_id, 930*1854ec6fSAmarnath Hullur Subramanyam event->requestor_instance_id, event->dw_or_faw, 931cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(event->addr)); 932cd4e3c3eSJouni Malinen 933*1854ec6fSAmarnath Hullur Subramanyam global_match_handle = event->publish_subscribe_id; 934*1854ec6fSAmarnath Hullur Subramanyam global_header_handle = event->requestor_instance_id; 935*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__); 936*1854ec6fSAmarnath Hullur Subramanyam nan_hex_dump(global_dut, event->service_specific_info, 937cd4e3c3eSJouni Malinen event->service_specific_info_len); 938cd4e3c3eSJouni Malinen event_anyresponse = 1; 939cd4e3c3eSJouni Malinen snprintf(global_event_resp_buf, sizeof(global_event_resp_buf), 940cd4e3c3eSJouni Malinen "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac," 941*1854ec6fSAmarnath Hullur Subramanyam MAC_ADDR_STR " ", event->requestor_instance_id >> 24, 942*1854ec6fSAmarnath Hullur Subramanyam event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr)); 943cd4e3c3eSJouni Malinen } 944cd4e3c3eSJouni Malinen 945cd4e3c3eSJouni Malinen 946cd4e3c3eSJouni Malinen /* Events Callback */ 947cd4e3c3eSJouni Malinen void nan_event_disceng_event(NanDiscEngEventInd *event) 948cd4e3c3eSJouni Malinen { 949*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d", 950*1854ec6fSAmarnath Hullur Subramanyam __func__, event->event_type); 951cd4e3c3eSJouni Malinen 952*1854ec6fSAmarnath Hullur Subramanyam if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) { 953cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster " 954cd4e3c3eSJouni Malinen MAC_ADDR_STR, 955cd4e3c3eSJouni Malinen __func__, 956cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(event->data.cluster.addr)); 957cd4e3c3eSJouni Malinen } 958*1854ec6fSAmarnath Hullur Subramanyam if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) { 959cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 960cd4e3c3eSJouni Malinen "%s: Started cluster " MAC_ADDR_STR, 961cd4e3c3eSJouni Malinen __func__, 962cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(event->data.cluster.addr)); 963cd4e3c3eSJouni Malinen } 964*1854ec6fSAmarnath Hullur Subramanyam if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) { 965*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 966*1854ec6fSAmarnath Hullur Subramanyam "%s: Discovery Mac Address " 967cd4e3c3eSJouni Malinen MAC_ADDR_STR, 968cd4e3c3eSJouni Malinen __func__, 969cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(event->data.mac_addr.addr)); 970cd4e3c3eSJouni Malinen memcpy(global_nan_mac_addr, event->data.mac_addr.addr, 971cd4e3c3eSJouni Malinen sizeof(global_nan_mac_addr)); 972cd4e3c3eSJouni Malinen } 973cd4e3c3eSJouni Malinen pthread_cond_signal(&gCondition); 974cd4e3c3eSJouni Malinen } 975cd4e3c3eSJouni Malinen 976cd4e3c3eSJouni Malinen 977cd4e3c3eSJouni Malinen /* Events Callback */ 978cd4e3c3eSJouni Malinen void nan_event_disabled(NanDisabledInd *event) 979cd4e3c3eSJouni Malinen { 980*1854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d", 981*1854ec6fSAmarnath Hullur Subramanyam __func__, event->reason); 982cd4e3c3eSJouni Malinen /* pthread_cond_signal(&gCondition); */ 983cd4e3c3eSJouni Malinen } 984cd4e3c3eSJouni Malinen 985cd4e3c3eSJouni Malinen 986cd4e3c3eSJouni Malinen void * my_thread_function(void *ptr) 987cd4e3c3eSJouni Malinen { 988*1854ec6fSAmarnath Hullur Subramanyam wifi_event_loop(global_wifi_handle); 989cd4e3c3eSJouni Malinen pthread_exit(0); 990cd4e3c3eSJouni Malinen return (void *) NULL; 991cd4e3c3eSJouni Malinen } 992cd4e3c3eSJouni Malinen 993cd4e3c3eSJouni Malinen 994cd4e3c3eSJouni Malinen static NanCallbackHandler callbackHandler = { 995cd4e3c3eSJouni Malinen .NotifyResponse = nan_notify_response, 996cd4e3c3eSJouni Malinen .EventPublishReplied = nan_event_publish_replied, 997cd4e3c3eSJouni Malinen .EventPublishTerminated = nan_event_publish_terminated, 998cd4e3c3eSJouni Malinen .EventMatch = nan_event_match, 999*1854ec6fSAmarnath Hullur Subramanyam .EventMatchExpired = nan_event_match_expired, 1000cd4e3c3eSJouni Malinen .EventSubscribeTerminated = nan_event_subscribe_terminated, 1001cd4e3c3eSJouni Malinen .EventFollowup = nan_event_followup, 1002cd4e3c3eSJouni Malinen .EventDiscEngEvent = nan_event_disceng_event, 1003cd4e3c3eSJouni Malinen .EventDisabled = nan_event_disabled, 1004cd4e3c3eSJouni Malinen }; 1005cd4e3c3eSJouni Malinen 1006cd4e3c3eSJouni Malinen void nan_init(struct sigma_dut *dut) 1007cd4e3c3eSJouni Malinen { 1008cd4e3c3eSJouni Malinen pthread_t thread1; /* thread variables */ 1009*1854ec6fSAmarnath Hullur Subramanyam wifi_error err = wifi_initialize(&global_wifi_handle); 1010cd4e3c3eSJouni Malinen 1011cd4e3c3eSJouni Malinen if (err) { 1012cd4e3c3eSJouni Malinen printf("wifi hal initialize failed\n"); 1013cd4e3c3eSJouni Malinen return; 1014cd4e3c3eSJouni Malinen } 1015cd4e3c3eSJouni Malinen 1016*1854ec6fSAmarnath Hullur Subramanyam global_interface_handle = wifi_get_iface_handle(global_wifi_handle, 1017*1854ec6fSAmarnath Hullur Subramanyam (char *) "wlan0"); 1018cd4e3c3eSJouni Malinen /* create threads 1 */ 1019cd4e3c3eSJouni Malinen pthread_create(&thread1, NULL, &my_thread_function, NULL); 1020cd4e3c3eSJouni Malinen 1021cd4e3c3eSJouni Malinen pthread_mutex_init(&gMutex, NULL); 1022cd4e3c3eSJouni Malinen pthread_cond_init(&gCondition, NULL); 1023*1854ec6fSAmarnath Hullur Subramanyam nan_register_handler(global_interface_handle, callbackHandler); 1024cd4e3c3eSJouni Malinen } 1025cd4e3c3eSJouni Malinen 1026cd4e3c3eSJouni Malinen 1027cd4e3c3eSJouni Malinen void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn, 1028cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 1029cd4e3c3eSJouni Malinen { 1030cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default"); 1031cd4e3c3eSJouni Malinen 1032cd4e3c3eSJouni Malinen if (nan_state == 0) { 1033cd4e3c3eSJouni Malinen nan_init(dut); 1034cd4e3c3eSJouni Malinen nan_state = 1; 1035cd4e3c3eSJouni Malinen } 1036cd4e3c3eSJouni Malinen is_fam = 0; 1037cd4e3c3eSJouni Malinen event_anyresponse = 0; 1038cd4e3c3eSJouni Malinen global_dut = dut; 1039cd4e3c3eSJouni Malinen memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf)); 1040cd4e3c3eSJouni Malinen sigma_nan_disable(dut, conn, cmd); 1041cd4e3c3eSJouni Malinen } 1042cd4e3c3eSJouni Malinen 1043cd4e3c3eSJouni Malinen 1044cd4e3c3eSJouni Malinen int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn, 1045cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 1046cd4e3c3eSJouni Malinen { 1047cd4e3c3eSJouni Malinen const char *program = get_param(cmd, "Prog"); 1048cd4e3c3eSJouni Malinen const char *nan_op = get_param(cmd, "NANOp"); 1049cd4e3c3eSJouni Malinen const char *method_type = get_param(cmd, "MethodType"); 1050cd4e3c3eSJouni Malinen char resp_buf[100]; 1051cd4e3c3eSJouni Malinen 1052cd4e3c3eSJouni Malinen if (program == NULL) 1053cd4e3c3eSJouni Malinen return -1; 1054cd4e3c3eSJouni Malinen 1055cd4e3c3eSJouni Malinen if (strcasecmp(program, "NAN") != 0) { 1056cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 1057cd4e3c3eSJouni Malinen "ErrorCode,Unsupported program"); 1058cd4e3c3eSJouni Malinen return 0; 1059cd4e3c3eSJouni Malinen } 1060cd4e3c3eSJouni Malinen 1061cd4e3c3eSJouni Malinen if (nan_op) { 1062cd4e3c3eSJouni Malinen /* 1063cd4e3c3eSJouni Malinen * NANOp has been specified. 1064cd4e3c3eSJouni Malinen * We will build a nan_enable or nan_disable command. 1065cd4e3c3eSJouni Malinen */ 1066cd4e3c3eSJouni Malinen if (strcasecmp(nan_op, "On") == 0) { 1067cd4e3c3eSJouni Malinen if (sigma_nan_enable(dut, conn, cmd) == 0) { 1068cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "mac," 1069cd4e3c3eSJouni Malinen MAC_ADDR_STR, 1070cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(global_nan_mac_addr)); 1071cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, resp_buf); 1072cd4e3c3eSJouni Malinen } else { 1073cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 1074cd4e3c3eSJouni Malinen "NAN_ENABLE_FAILED"); 1075cd4e3c3eSJouni Malinen return -1; 1076cd4e3c3eSJouni Malinen } 1077cd4e3c3eSJouni Malinen } else if (strcasecmp(nan_op, "Off") == 0) { 1078cd4e3c3eSJouni Malinen sigma_nan_disable(dut, conn, cmd); 1079cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 1080cd4e3c3eSJouni Malinen } 1081cd4e3c3eSJouni Malinen } 1082cd4e3c3eSJouni Malinen if (nan_state && nan_op == NULL) { 1083cd4e3c3eSJouni Malinen if (method_type) { 1084cd4e3c3eSJouni Malinen if (strcasecmp(method_type, "Publish") == 0) { 1085cd4e3c3eSJouni Malinen sigma_nan_publish_request(dut, conn, cmd); 1086cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 1087cd4e3c3eSJouni Malinen } 1088cd4e3c3eSJouni Malinen if (strcasecmp(method_type, "Subscribe") == 0) { 1089cd4e3c3eSJouni Malinen sigma_nan_subscribe_request(dut, conn, cmd); 1090cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 1091cd4e3c3eSJouni Malinen } 1092cd4e3c3eSJouni Malinen if (strcasecmp(method_type, "Followup") == 0) { 1093cd4e3c3eSJouni Malinen sigma_nan_transmit_followup(dut, conn, cmd); 1094cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 1095cd4e3c3eSJouni Malinen } 1096cd4e3c3eSJouni Malinen } else { 1097cd4e3c3eSJouni Malinen sigma_nan_config_enable(dut, conn, cmd); 1098cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "mac," 1099cd4e3c3eSJouni Malinen MAC_ADDR_STR, 1100cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(global_nan_mac_addr)); 1101cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, resp_buf); 1102cd4e3c3eSJouni Malinen } 1103cd4e3c3eSJouni Malinen } 1104cd4e3c3eSJouni Malinen 1105cd4e3c3eSJouni Malinen return 0; 1106cd4e3c3eSJouni Malinen } 1107cd4e3c3eSJouni Malinen 1108cd4e3c3eSJouni Malinen 1109cd4e3c3eSJouni Malinen int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn, 1110cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 1111cd4e3c3eSJouni Malinen { 1112cd4e3c3eSJouni Malinen 1113cd4e3c3eSJouni Malinen const char *program = get_param(cmd, "Program"); 1114cd4e3c3eSJouni Malinen const char *parameter = get_param(cmd, "Parameter"); 1115cd4e3c3eSJouni Malinen char resp_buf[100]; 1116cd4e3c3eSJouni Malinen NanStaParameter rsp; 1117cd4e3c3eSJouni Malinen 1118cd4e3c3eSJouni Malinen if (program == NULL) { 1119cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name"); 1120cd4e3c3eSJouni Malinen return -1; 1121cd4e3c3eSJouni Malinen } 1122cd4e3c3eSJouni Malinen if (strcasecmp(program, "NAN") != 0) { 1123cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 1124cd4e3c3eSJouni Malinen "ErrorCode,Unsupported program"); 1125cd4e3c3eSJouni Malinen return 0; 1126cd4e3c3eSJouni Malinen } 1127cd4e3c3eSJouni Malinen 1128cd4e3c3eSJouni Malinen if (parameter == NULL) { 1129cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter"); 1130cd4e3c3eSJouni Malinen return -1; 1131cd4e3c3eSJouni Malinen } 1132cd4e3c3eSJouni Malinen memset(&rsp, 0, sizeof(NanStaParameter)); 1133cd4e3c3eSJouni Malinen 1134*1854ec6fSAmarnath Hullur Subramanyam nan_get_sta_parameter(0, global_interface_handle, &rsp); 1135cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, 1136cd4e3c3eSJouni Malinen "%s: NanStaparameter Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d", 1137cd4e3c3eSJouni Malinen __func__, rsp.master_pref, rsp.random_factor, 1138cd4e3c3eSJouni Malinen rsp.hop_count, rsp.beacon_transmit_time); 1139cd4e3c3eSJouni Malinen 1140cd4e3c3eSJouni Malinen if (strcasecmp(parameter, "MasterPref") == 0) { 1141cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x", 1142cd4e3c3eSJouni Malinen rsp.master_pref); 1143cd4e3c3eSJouni Malinen } else if (strcasecmp(parameter, "MasterRank") == 0) { 1144cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx", 1145cd4e3c3eSJouni Malinen rsp.master_rank); 1146cd4e3c3eSJouni Malinen } else if (strcasecmp(parameter, "RandFactor") == 0) { 1147cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x", 1148cd4e3c3eSJouni Malinen rsp.random_factor); 1149cd4e3c3eSJouni Malinen } else if (strcasecmp(parameter, "HopCount") == 0) { 1150cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x", 1151cd4e3c3eSJouni Malinen rsp.hop_count); 1152cd4e3c3eSJouni Malinen } else if (strcasecmp(parameter, "BeaconTransTime") == 0) { 1153cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x", 1154cd4e3c3eSJouni Malinen rsp.beacon_transmit_time); 1155cd4e3c3eSJouni Malinen } else if (strcasecmp(parameter, "NANStatus") == 0) { 1156cd4e3c3eSJouni Malinen if (nan_state == 1) 1157cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "On"); 1158cd4e3c3eSJouni Malinen else 1159cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "Off"); 1160cd4e3c3eSJouni Malinen } else { 1161cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter"); 1162cd4e3c3eSJouni Malinen return 0; 1163cd4e3c3eSJouni Malinen } 1164cd4e3c3eSJouni Malinen 1165cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, resp_buf); 1166cd4e3c3eSJouni Malinen return 0; 1167cd4e3c3eSJouni Malinen } 1168cd4e3c3eSJouni Malinen 1169cd4e3c3eSJouni Malinen 1170cd4e3c3eSJouni Malinen int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn, 1171cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 1172cd4e3c3eSJouni Malinen { 1173cd4e3c3eSJouni Malinen const char *action = get_param(cmd, "Action"); 1174cd4e3c3eSJouni Malinen 1175cd4e3c3eSJouni Malinen /* Check action for start, stop and get events. */ 1176cd4e3c3eSJouni Malinen if (strcasecmp(action, "Start") == 0) { 1177cd4e3c3eSJouni Malinen memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf)); 1178cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, NULL); 1179cd4e3c3eSJouni Malinen } else if (strcasecmp(action, "Stop") == 0) { 1180cd4e3c3eSJouni Malinen event_anyresponse = 0; 1181cd4e3c3eSJouni Malinen memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf)); 1182cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, NULL); 1183cd4e3c3eSJouni Malinen } else if (strcasecmp(action, "Get") == 0) { 1184cd4e3c3eSJouni Malinen if (event_anyresponse == 1) { 1185cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 1186cd4e3c3eSJouni Malinen global_event_resp_buf); 1187cd4e3c3eSJouni Malinen } else { 1188cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE"); 1189cd4e3c3eSJouni Malinen } 1190cd4e3c3eSJouni Malinen } 1191cd4e3c3eSJouni Malinen return 0; 1192cd4e3c3eSJouni Malinen } 1193