1cd4e3c3eSJouni Malinen /* 2cd4e3c3eSJouni Malinen * Sigma Control API DUT (NAN functionality) 34b75f96cSRakesh Sunki * Copyright (c) 2014-2017, 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" 131854ec6fSAmarnath Hullur Subramanyam #include "nan_cert.h" 14cd4e3c3eSJouni Malinen 154b75f96cSRakesh Sunki #if NAN_CERT_VERSION >= 2 164b75f96cSRakesh Sunki 17cd4e3c3eSJouni Malinen pthread_cond_t gCondition; 18cd4e3c3eSJouni Malinen pthread_mutex_t gMutex; 191854ec6fSAmarnath Hullur Subramanyam wifi_handle global_wifi_handle; 201854ec6fSAmarnath Hullur Subramanyam wifi_interface_handle global_interface_handle; 21d51e8980SRakesh Sunki static NanSyncStats global_nan_sync_stats; 22cd4e3c3eSJouni Malinen static int nan_state = 0; 23cd4e3c3eSJouni Malinen static int event_anyresponse = 0; 24cd4e3c3eSJouni Malinen static int is_fam = 0; 25cd4e3c3eSJouni Malinen 264c086678SRakesh Sunki static uint16_t global_ndp_instance_id = 0; 274d5912dfSRakesh Sunki static uint16_t global_publish_id = 0; 284d5912dfSRakesh Sunki static uint16_t global_subscribe_id = 0; 29cd4e3c3eSJouni Malinen uint16_t global_header_handle = 0; 30cd4e3c3eSJouni Malinen uint32_t global_match_handle = 0; 31cd4e3c3eSJouni Malinen 32d5e9b4d1SRakesh Sunki #define DEFAULT_SVC "QNanCluster" 33cd4e3c3eSJouni Malinen #define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] 34cd4e3c3eSJouni Malinen #define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" 35cd4e3c3eSJouni Malinen #ifndef ETH_ALEN 36cd4e3c3eSJouni Malinen #define ETH_ALEN 6 37cd4e3c3eSJouni Malinen #endif 38cd4e3c3eSJouni Malinen 39cd4e3c3eSJouni Malinen struct sigma_dut *global_dut = NULL; 40cd4e3c3eSJouni Malinen static char global_nan_mac_addr[ETH_ALEN]; 4114cfcd25SRakesh Sunki static char global_peer_mac_addr[ETH_ALEN]; 42cd4e3c3eSJouni Malinen static char global_event_resp_buf[1024]; 434236368dSRakesh Sunki static u8 global_publish_service_name[NAN_MAX_SERVICE_NAME_LEN]; 444236368dSRakesh Sunki static u32 global_publish_service_name_len = 0; 4574f4f992SRakesh Sunki static u8 global_subscribe_service_name[NAN_MAX_SERVICE_NAME_LEN]; 4674f4f992SRakesh Sunki static u32 global_subscribe_service_name_len = 0; 47cd4e3c3eSJouni Malinen 48cd4e3c3eSJouni Malinen static int nan_further_availability_tx(struct sigma_dut *dut, 49cd4e3c3eSJouni Malinen struct sigma_conn *conn, 50cd4e3c3eSJouni Malinen struct sigma_cmd *cmd); 51cd4e3c3eSJouni Malinen static int nan_further_availability_rx(struct sigma_dut *dut, 52cd4e3c3eSJouni Malinen struct sigma_conn *conn, 53cd4e3c3eSJouni Malinen struct sigma_cmd *cmd); 54cd4e3c3eSJouni Malinen 55cd4e3c3eSJouni Malinen 56cd4e3c3eSJouni Malinen void nan_hex_dump(struct sigma_dut *dut, uint8_t *data, size_t len) 57cd4e3c3eSJouni Malinen { 58cd4e3c3eSJouni Malinen char buf[512]; 59cd4e3c3eSJouni Malinen uint16_t index; 60cd4e3c3eSJouni Malinen uint8_t *ptr; 61cd4e3c3eSJouni Malinen int pos; 62cd4e3c3eSJouni Malinen 63cd4e3c3eSJouni Malinen memset(buf, 0, sizeof(buf)); 64cd4e3c3eSJouni Malinen ptr = data; 65cd4e3c3eSJouni Malinen pos = 0; 66cd4e3c3eSJouni Malinen for (index = 0; index < len; index++) { 676734e239SPeng Xu pos += snprintf(&(buf[pos]), sizeof(buf) - pos, 686734e239SPeng Xu "%02x ", *ptr++); 69cd4e3c3eSJouni Malinen if (pos > 508) 70cd4e3c3eSJouni Malinen break; 71cd4e3c3eSJouni Malinen } 72cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "HEXDUMP len=[%d]", (int) len); 73cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "buf:%s", buf); 74cd4e3c3eSJouni Malinen } 75cd4e3c3eSJouni Malinen 76cd4e3c3eSJouni Malinen 77cd4e3c3eSJouni Malinen int nan_parse_hex(unsigned char c) 78cd4e3c3eSJouni Malinen { 79cd4e3c3eSJouni Malinen if (c >= '0' && c <= '9') 80cd4e3c3eSJouni Malinen return c - '0'; 81cd4e3c3eSJouni Malinen if (c >= 'a' && c <= 'f') 82cd4e3c3eSJouni Malinen return c - 'a' + 10; 83cd4e3c3eSJouni Malinen if (c >= 'A' && c <= 'F') 84cd4e3c3eSJouni Malinen return c - 'A' + 10; 85cd4e3c3eSJouni Malinen return 0; 86cd4e3c3eSJouni Malinen } 87cd4e3c3eSJouni Malinen 88cd4e3c3eSJouni Malinen 89cd4e3c3eSJouni Malinen int nan_parse_token(const char *tokenIn, u8 *tokenOut, int *filterLen) 90cd4e3c3eSJouni Malinen { 91cd4e3c3eSJouni Malinen int total_len = 0, len = 0; 92cd4e3c3eSJouni Malinen char *saveptr = NULL; 93cd4e3c3eSJouni Malinen 94cd4e3c3eSJouni Malinen tokenIn = strtok_r((char *) tokenIn, ":", &saveptr); 95cd4e3c3eSJouni Malinen while (tokenIn != NULL) { 96cd4e3c3eSJouni Malinen len = strlen(tokenIn); 97cd4e3c3eSJouni Malinen if (len == 1 && *tokenIn == '*') 98cd4e3c3eSJouni Malinen len = 0; 99cd4e3c3eSJouni Malinen tokenOut[total_len++] = (u8) len; 100cd4e3c3eSJouni Malinen if (len != 0) 101cd4e3c3eSJouni Malinen memcpy((u8 *) tokenOut + total_len, tokenIn, len); 102cd4e3c3eSJouni Malinen total_len += len; 103cd4e3c3eSJouni Malinen tokenIn = strtok_r(NULL, ":", &saveptr); 104cd4e3c3eSJouni Malinen } 105cd4e3c3eSJouni Malinen *filterLen = total_len; 106cd4e3c3eSJouni Malinen return 0; 107cd4e3c3eSJouni Malinen } 108cd4e3c3eSJouni Malinen 109cd4e3c3eSJouni Malinen 110cd4e3c3eSJouni Malinen int nan_parse_mac_address(struct sigma_dut *dut, const char *arg, u8 *addr) 111cd4e3c3eSJouni Malinen { 112cd4e3c3eSJouni Malinen if (strlen(arg) != 17) { 113cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid mac address %s", 114cd4e3c3eSJouni Malinen arg); 115cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, 116cd4e3c3eSJouni Malinen "expected format xx:xx:xx:xx:xx:xx"); 117cd4e3c3eSJouni Malinen return -1; 118cd4e3c3eSJouni Malinen } 119cd4e3c3eSJouni Malinen 120cd4e3c3eSJouni Malinen addr[0] = nan_parse_hex(arg[0]) << 4 | nan_parse_hex(arg[1]); 121cd4e3c3eSJouni Malinen addr[1] = nan_parse_hex(arg[3]) << 4 | nan_parse_hex(arg[4]); 122cd4e3c3eSJouni Malinen addr[2] = nan_parse_hex(arg[6]) << 4 | nan_parse_hex(arg[7]); 123cd4e3c3eSJouni Malinen addr[3] = nan_parse_hex(arg[9]) << 4 | nan_parse_hex(arg[10]); 124cd4e3c3eSJouni Malinen addr[4] = nan_parse_hex(arg[12]) << 4 | nan_parse_hex(arg[13]); 125cd4e3c3eSJouni Malinen addr[5] = nan_parse_hex(arg[15]) << 4 | nan_parse_hex(arg[16]); 126cd4e3c3eSJouni Malinen 127cd4e3c3eSJouni Malinen return 0; 128cd4e3c3eSJouni Malinen } 129cd4e3c3eSJouni Malinen 130cd4e3c3eSJouni Malinen 131cd4e3c3eSJouni Malinen int nan_parse_mac_address_list(struct sigma_dut *dut, const char *input, 132cd4e3c3eSJouni Malinen u8 *output, u16 max_addr_allowed) 133cd4e3c3eSJouni Malinen { 134cd4e3c3eSJouni Malinen /* 135cd4e3c3eSJouni Malinen * Reads a list of mac address separated by space. Each MAC address 136cd4e3c3eSJouni Malinen * should have the format of aa:bb:cc:dd:ee:ff. 137cd4e3c3eSJouni Malinen */ 138cd4e3c3eSJouni Malinen char *saveptr; 139cd4e3c3eSJouni Malinen char *token; 140cd4e3c3eSJouni Malinen int i = 0; 141cd4e3c3eSJouni Malinen 142cd4e3c3eSJouni Malinen for (i = 0; i < max_addr_allowed; i++) { 143cd4e3c3eSJouni Malinen token = strtok_r((i == 0) ? (char *) input : NULL, 144cd4e3c3eSJouni Malinen " ", &saveptr); 145cd4e3c3eSJouni Malinen if (token) { 146cd4e3c3eSJouni Malinen nan_parse_mac_address(dut, token, output); 147cd4e3c3eSJouni Malinen output += NAN_MAC_ADDR_LEN; 148cd4e3c3eSJouni Malinen } else 149cd4e3c3eSJouni Malinen break; 150cd4e3c3eSJouni Malinen } 151cd4e3c3eSJouni Malinen 152cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "Num MacAddress:%d", i); 153cd4e3c3eSJouni Malinen 154cd4e3c3eSJouni Malinen return i; 155cd4e3c3eSJouni Malinen } 156cd4e3c3eSJouni Malinen 157cd4e3c3eSJouni Malinen 158cd4e3c3eSJouni Malinen int nan_parse_hex_string(struct sigma_dut *dut, const char *input, 159cd4e3c3eSJouni Malinen u8 *output, int *outputlen) 160cd4e3c3eSJouni Malinen { 161cd4e3c3eSJouni Malinen int i = 0; 162cd4e3c3eSJouni Malinen int j = 0; 163cd4e3c3eSJouni Malinen 164cd4e3c3eSJouni Malinen for (i = 0; i < (int) strlen(input) && j < *outputlen; i += 2) { 165cd4e3c3eSJouni Malinen output[j] = nan_parse_hex(input[i]); 166cd4e3c3eSJouni Malinen if (i + 1 < (int) strlen(input)) { 167cd4e3c3eSJouni Malinen output[j] = ((output[j] << 4) | 168cd4e3c3eSJouni Malinen nan_parse_hex(input[i + 1])); 169cd4e3c3eSJouni Malinen } 170cd4e3c3eSJouni Malinen j++; 171cd4e3c3eSJouni Malinen } 172cd4e3c3eSJouni Malinen *outputlen = j; 173cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "Input:%s inputlen:%d outputlen:%d", 174cd4e3c3eSJouni Malinen input, (int) strlen(input), (int) *outputlen); 175cd4e3c3eSJouni Malinen return 0; 176cd4e3c3eSJouni Malinen } 177cd4e3c3eSJouni Malinen 178cd4e3c3eSJouni Malinen 179cd4e3c3eSJouni Malinen int wait(struct timespec abstime) 180cd4e3c3eSJouni Malinen { 181cd4e3c3eSJouni Malinen struct timeval now; 182cd4e3c3eSJouni Malinen 183cd4e3c3eSJouni Malinen gettimeofday(&now, NULL); 184cd4e3c3eSJouni Malinen 185cd4e3c3eSJouni Malinen abstime.tv_sec += now.tv_sec; 186cd4e3c3eSJouni Malinen if (((abstime.tv_nsec + now.tv_usec * 1000) > 1000 * 1000 * 1000) || 187cd4e3c3eSJouni Malinen (abstime.tv_nsec + now.tv_usec * 1000 < 0)) { 188cd4e3c3eSJouni Malinen abstime.tv_sec += 1; 189cd4e3c3eSJouni Malinen abstime.tv_nsec += now.tv_usec * 1000; 190cd4e3c3eSJouni Malinen abstime.tv_nsec -= 1000 * 1000 * 1000; 191cd4e3c3eSJouni Malinen } else { 192cd4e3c3eSJouni Malinen abstime.tv_nsec += now.tv_usec * 1000; 193cd4e3c3eSJouni Malinen } 194cd4e3c3eSJouni Malinen 195cd4e3c3eSJouni Malinen return pthread_cond_timedwait(&gCondition, &gMutex, &abstime); 196cd4e3c3eSJouni Malinen } 197cd4e3c3eSJouni Malinen 198cd4e3c3eSJouni Malinen 199cd4e3c3eSJouni Malinen int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut, 200cd4e3c3eSJouni Malinen struct sigma_conn *conn, 201cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 202cd4e3c3eSJouni Malinen { 2038dd1d88dSRakesh Sunki const char *oper_chan = get_param(cmd, "oper_chn"); 2047d37f411SRakesh Sunki const char *pmk = get_param(cmd, "PMK"); 205cd4e3c3eSJouni Malinen 2068dd1d88dSRakesh Sunki if (oper_chan) { 2078dd1d88dSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, "Operating Channel: %s", 2088dd1d88dSRakesh Sunki oper_chan); 209132c6d2bSKantesh Mundaragi dut->sta_channel = atoi(oper_chan); 2108dd1d88dSRakesh Sunki } 211cd4e3c3eSJouni Malinen 2127d37f411SRakesh Sunki if (pmk) { 2137d37f411SRakesh Sunki int pmk_len; 2147d37f411SRakesh Sunki 2157d37f411SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, "%s given string pmk: %s", 2167d37f411SRakesh Sunki __func__, pmk); 2177d37f411SRakesh Sunki memset(dut->nan_pmk, 0, NAN_PMK_INFO_LEN); 2187d37f411SRakesh Sunki dut->nan_pmk_len = 0; 2197d37f411SRakesh Sunki pmk_len = NAN_PMK_INFO_LEN; 2207d37f411SRakesh Sunki nan_parse_hex_string(dut, &pmk[2], &dut->nan_pmk[0], &pmk_len); 2217d37f411SRakesh Sunki dut->nan_pmk_len = pmk_len; 2227d37f411SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d", 2237d37f411SRakesh Sunki __func__, dut->nan_pmk_len); 2247d37f411SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex pmk", __func__); 2257d37f411SRakesh Sunki nan_hex_dump(dut, &dut->nan_pmk[0], dut->nan_pmk_len); 2267d37f411SRakesh Sunki } 2277d37f411SRakesh Sunki 22814bff1dbSRakesh Sunki send_resp(dut, conn, SIGMA_COMPLETE, NULL); 229cd4e3c3eSJouni Malinen return 0; 230cd4e3c3eSJouni Malinen } 231cd4e3c3eSJouni Malinen 232cd4e3c3eSJouni Malinen 2331854ec6fSAmarnath Hullur Subramanyam void nan_print_further_availability_chan(struct sigma_dut *dut, 2341854ec6fSAmarnath Hullur Subramanyam u8 num_chans, 2351854ec6fSAmarnath Hullur Subramanyam NanFurtherAvailabilityChannel *fachan) 2361854ec6fSAmarnath Hullur Subramanyam { 2371854ec6fSAmarnath Hullur Subramanyam int idx; 2381854ec6fSAmarnath Hullur Subramanyam 2391854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 2401854ec6fSAmarnath Hullur Subramanyam "********Printing FurtherAvailabilityChan Info******"); 2411854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, "Numchans:%d", num_chans); 2421854ec6fSAmarnath Hullur Subramanyam for (idx = 0; idx < num_chans; idx++) { 2431854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 2441854ec6fSAmarnath Hullur Subramanyam "[%d]: NanAvailDuration:%d class_val:%02x channel:%d", 2451854ec6fSAmarnath Hullur Subramanyam idx, fachan->entry_control, 2461854ec6fSAmarnath Hullur Subramanyam fachan->class_val, fachan->channel); 2471854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 2481854ec6fSAmarnath Hullur Subramanyam "[%d]: mapid:%d Availability bitmap:%08x", 2491854ec6fSAmarnath Hullur Subramanyam idx, fachan->mapid, 2501854ec6fSAmarnath Hullur Subramanyam fachan->avail_interval_bitmap); 2511854ec6fSAmarnath Hullur Subramanyam } 2521854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(dut, DUT_MSG_INFO, 2531854ec6fSAmarnath Hullur Subramanyam "*********************Done**********************"); 2541854ec6fSAmarnath Hullur Subramanyam } 2551854ec6fSAmarnath Hullur Subramanyam 2561854ec6fSAmarnath Hullur Subramanyam 257cd4e3c3eSJouni Malinen int sigma_nan_enable(struct sigma_dut *dut, struct sigma_conn *conn, 258cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 259cd4e3c3eSJouni Malinen { 260cd4e3c3eSJouni Malinen const char *master_pref = get_param(cmd, "MasterPref"); 261cd4e3c3eSJouni Malinen const char *rand_fac = get_param(cmd, "RandFactor"); 262cd4e3c3eSJouni Malinen const char *hop_count = get_param(cmd, "HopCount"); 263cd4e3c3eSJouni Malinen const char *sdftx_band = get_param(cmd, "SDFTxBand"); 264cd4e3c3eSJouni Malinen const char *oper_chan = get_param(cmd, "oper_chn"); 265cd4e3c3eSJouni Malinen const char *further_avail_ind = get_param(cmd, "FurtherAvailInd"); 266cd4e3c3eSJouni Malinen const char *band = get_param(cmd, "Band"); 267cd4e3c3eSJouni Malinen const char *only_5g = get_param(cmd, "5GOnly"); 26838dd72efSRakesh Sunki const char *nan_availability = get_param(cmd, "NANAvailability"); 269cd4e3c3eSJouni Malinen struct timespec abstime; 270cd4e3c3eSJouni Malinen NanEnableRequest req; 271cd4e3c3eSJouni Malinen 272cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanEnableRequest)); 273cd4e3c3eSJouni Malinen req.cluster_low = 0; 274cd4e3c3eSJouni Malinen req.cluster_high = 0xFFFF; 2751854ec6fSAmarnath Hullur Subramanyam req.master_pref = 100; 276cd4e3c3eSJouni Malinen 2771854ec6fSAmarnath Hullur Subramanyam /* This is a debug hack to beacon in channel 11 */ 278cd4e3c3eSJouni Malinen if (oper_chan) { 279cd4e3c3eSJouni Malinen req.config_2dot4g_support = 1; 280cd4e3c3eSJouni Malinen req.support_2dot4g_val = 111; 281cd4e3c3eSJouni Malinen } 282cd4e3c3eSJouni Malinen 283cd4e3c3eSJouni Malinen if (master_pref) { 284cd4e3c3eSJouni Malinen int master_pref_val = strtoul(master_pref, NULL, 0); 285cd4e3c3eSJouni Malinen 286cd4e3c3eSJouni Malinen req.master_pref = master_pref_val; 287cd4e3c3eSJouni Malinen } 288cd4e3c3eSJouni Malinen 289cd4e3c3eSJouni Malinen if (rand_fac) { 290cd4e3c3eSJouni Malinen int rand_fac_val = strtoul(rand_fac, NULL, 0); 291cd4e3c3eSJouni Malinen 292cd4e3c3eSJouni Malinen req.config_random_factor_force = 1; 293cd4e3c3eSJouni Malinen req.random_factor_force_val = rand_fac_val; 294cd4e3c3eSJouni Malinen } 295cd4e3c3eSJouni Malinen 296cd4e3c3eSJouni Malinen if (hop_count) { 297cd4e3c3eSJouni Malinen int hop_count_val = strtoul(hop_count, NULL, 0); 298cd4e3c3eSJouni Malinen 299cd4e3c3eSJouni Malinen req.config_hop_count_force = 1; 300cd4e3c3eSJouni Malinen req.hop_count_force_val = hop_count_val; 301cd4e3c3eSJouni Malinen } 302cd4e3c3eSJouni Malinen 303cd4e3c3eSJouni Malinen if (sdftx_band) { 304cd4e3c3eSJouni Malinen if (strcasecmp(sdftx_band, "5G") == 0) { 305cd4e3c3eSJouni Malinen req.config_2dot4g_support = 1; 306cd4e3c3eSJouni Malinen req.support_2dot4g_val = 0; 307cd4e3c3eSJouni Malinen } 308cd4e3c3eSJouni Malinen } 309cd4e3c3eSJouni Malinen 310cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, 31147a276adSRakesh Sunki "%s: Setting dual band 2.4 GHz and 5 GHz by default", 31247a276adSRakesh Sunki __func__); 31347a276adSRakesh Sunki /* Enable 2.4 GHz support */ 314cd4e3c3eSJouni Malinen req.config_2dot4g_support = 1; 315cd4e3c3eSJouni Malinen req.support_2dot4g_val = 1; 316cd4e3c3eSJouni Malinen req.config_2dot4g_beacons = 1; 317cd4e3c3eSJouni Malinen req.beacon_2dot4g_val = 1; 3181854ec6fSAmarnath Hullur Subramanyam req.config_2dot4g_sdf = 1; 3191854ec6fSAmarnath Hullur Subramanyam req.sdf_2dot4g_val = 1; 320cd4e3c3eSJouni Malinen 32147a276adSRakesh Sunki /* Enable 5 GHz support */ 32247a276adSRakesh Sunki req.config_support_5g = 1; 32347a276adSRakesh Sunki req.support_5g_val = 1; 32447a276adSRakesh Sunki req.config_5g_beacons = 1; 32547a276adSRakesh Sunki req.beacon_5g_val = 1; 32647a276adSRakesh Sunki req.config_5g_sdf = 1; 32747a276adSRakesh Sunki req.sdf_5g_val = 1; 32847a276adSRakesh Sunki 32947a276adSRakesh Sunki if (band) { 33047a276adSRakesh Sunki if (strcasecmp(band, "24G") == 0) { 33147a276adSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 33247a276adSRakesh Sunki "Band 2.4 GHz selected, disable 5 GHz"); 333cd4e3c3eSJouni Malinen /* Disable 5G support */ 3341854ec6fSAmarnath Hullur Subramanyam req.config_support_5g = 1; 3351854ec6fSAmarnath Hullur Subramanyam req.support_5g_val = 0; 336cd4e3c3eSJouni Malinen req.config_5g_beacons = 1; 337cd4e3c3eSJouni Malinen req.beacon_5g_val = 0; 3381854ec6fSAmarnath Hullur Subramanyam req.config_5g_sdf = 1; 3391854ec6fSAmarnath Hullur Subramanyam req.sdf_5g_val = 0; 340cd4e3c3eSJouni Malinen } 341cd4e3c3eSJouni Malinen } 342cd4e3c3eSJouni Malinen 343cd4e3c3eSJouni Malinen if (further_avail_ind) { 344cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled"); 345cd4e3c3eSJouni Malinen if (strcasecmp(further_avail_ind, "tx") == 0) { 346cd4e3c3eSJouni Malinen is_fam = 1; 347cd4e3c3eSJouni Malinen nan_further_availability_tx(dut, conn, cmd); 348cd4e3c3eSJouni Malinen return 0; 349cd4e3c3eSJouni Malinen } else if (strcasecmp(further_avail_ind, "rx") == 0) { 350cd4e3c3eSJouni Malinen nan_further_availability_rx(dut, conn, cmd); 351cd4e3c3eSJouni Malinen return 0; 352cd4e3c3eSJouni Malinen } 353cd4e3c3eSJouni Malinen } 354cd4e3c3eSJouni Malinen 355cd4e3c3eSJouni Malinen if (only_5g && atoi(only_5g)) { 356cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled"); 357cd4e3c3eSJouni Malinen req.config_2dot4g_support = 1; 358cd4e3c3eSJouni Malinen req.support_2dot4g_val = 1; 359cd4e3c3eSJouni Malinen req.config_2dot4g_beacons = 1; 360cd4e3c3eSJouni Malinen req.beacon_2dot4g_val = 0; 3611854ec6fSAmarnath Hullur Subramanyam req.config_2dot4g_sdf = 1; 3621854ec6fSAmarnath Hullur Subramanyam req.sdf_2dot4g_val = 1; 363cd4e3c3eSJouni Malinen } 364cd4e3c3eSJouni Malinen 3651854ec6fSAmarnath Hullur Subramanyam nan_enable_request(0, global_interface_handle, &req); 366116be195SKantesh Mundaragi 36738dd72efSRakesh Sunki if (nan_availability) { 36838dd72efSRakesh Sunki int cmd_len, size; 36938dd72efSRakesh Sunki NanDebugParams cfg_debug; 37038dd72efSRakesh Sunki 37138dd72efSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 37238dd72efSRakesh Sunki "%s given string nan_availability: %s", 37338dd72efSRakesh Sunki __func__, nan_availability); 37438dd72efSRakesh Sunki memset(&cfg_debug, 0, sizeof(NanDebugParams)); 37538dd72efSRakesh Sunki cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY; 37638dd72efSRakesh Sunki size = NAN_MAX_DEBUG_MESSAGE_DATA_LEN; 37738dd72efSRakesh Sunki nan_parse_hex_string(dut, &nan_availability[2], 37838dd72efSRakesh Sunki &cfg_debug.debug_cmd_data[0], &size); 37938dd72efSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex nan_availability", 38038dd72efSRakesh Sunki __func__); 38138dd72efSRakesh Sunki nan_hex_dump(dut, &cfg_debug.debug_cmd_data[0], size); 38238dd72efSRakesh Sunki cmd_len = size + sizeof(u32); 38338dd72efSRakesh Sunki nan_debug_command_config(0, global_interface_handle, 38438dd72efSRakesh Sunki cfg_debug, cmd_len); 38538dd72efSRakesh Sunki } 38638dd72efSRakesh Sunki 387116be195SKantesh Mundaragi /* To ensure sta_get_events to get the events 388116be195SKantesh Mundaragi * only after joining the NAN cluster. */ 389116be195SKantesh Mundaragi abstime.tv_sec = 30; 390cd4e3c3eSJouni Malinen abstime.tv_nsec = 0; 391116be195SKantesh Mundaragi wait(abstime); 392116be195SKantesh Mundaragi 393116be195SKantesh Mundaragi return 0; 394cd4e3c3eSJouni Malinen } 395cd4e3c3eSJouni Malinen 396cd4e3c3eSJouni Malinen 397cd4e3c3eSJouni Malinen int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn, 398cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 399cd4e3c3eSJouni Malinen { 400cd4e3c3eSJouni Malinen struct timespec abstime; 401cd4e3c3eSJouni Malinen 4021854ec6fSAmarnath Hullur Subramanyam nan_disable_request(0, global_interface_handle); 403cd4e3c3eSJouni Malinen 404cd4e3c3eSJouni Malinen abstime.tv_sec = 4; 405cd4e3c3eSJouni Malinen abstime.tv_nsec = 0; 406116be195SKantesh Mundaragi wait(abstime); 407116be195SKantesh Mundaragi 408116be195SKantesh Mundaragi return 0; 409cd4e3c3eSJouni Malinen } 410cd4e3c3eSJouni Malinen 411cd4e3c3eSJouni Malinen 412cd4e3c3eSJouni Malinen int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn, 413cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 414cd4e3c3eSJouni Malinen { 415cd4e3c3eSJouni Malinen const char *master_pref = get_param(cmd, "MasterPref"); 416cd4e3c3eSJouni Malinen const char *rand_fac = get_param(cmd, "RandFactor"); 417cd4e3c3eSJouni Malinen const char *hop_count = get_param(cmd, "HopCount"); 418107356c8SRakesh Sunki wifi_error ret; 419cd4e3c3eSJouni Malinen struct timespec abstime; 420cd4e3c3eSJouni Malinen NanConfigRequest req; 421cd4e3c3eSJouni Malinen 422cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanConfigRequest)); 423cd4e3c3eSJouni Malinen req.config_rssi_proximity = 1; 424cd4e3c3eSJouni Malinen req.rssi_proximity = 70; 425cd4e3c3eSJouni Malinen 426cd4e3c3eSJouni Malinen if (master_pref) { 427cd4e3c3eSJouni Malinen int master_pref_val = strtoul(master_pref, NULL, 0); 428cd4e3c3eSJouni Malinen 429cd4e3c3eSJouni Malinen req.config_master_pref = 1; 430cd4e3c3eSJouni Malinen req.master_pref = master_pref_val; 431cd4e3c3eSJouni Malinen } 432cd4e3c3eSJouni Malinen 433cd4e3c3eSJouni Malinen if (rand_fac) { 434cd4e3c3eSJouni Malinen int rand_fac_val = strtoul(rand_fac, NULL, 0); 435cd4e3c3eSJouni Malinen 436cd4e3c3eSJouni Malinen req.config_random_factor_force = 1; 437cd4e3c3eSJouni Malinen req.random_factor_force_val = rand_fac_val; 438cd4e3c3eSJouni Malinen } 439cd4e3c3eSJouni Malinen 440cd4e3c3eSJouni Malinen if (hop_count) { 441cd4e3c3eSJouni Malinen int hop_count_val = strtoul(hop_count, NULL, 0); 442cd4e3c3eSJouni Malinen 443cd4e3c3eSJouni Malinen req.config_hop_count_force = 1; 444cd4e3c3eSJouni Malinen req.hop_count_force_val = hop_count_val; 445cd4e3c3eSJouni Malinen } 446cd4e3c3eSJouni Malinen 447107356c8SRakesh Sunki ret = nan_config_request(0, global_interface_handle, &req); 448107356c8SRakesh Sunki if (ret != WIFI_SUCCESS) 449107356c8SRakesh Sunki send_resp(dut, conn, SIGMA_ERROR, "NAN config request failed"); 450cd4e3c3eSJouni Malinen 451cd4e3c3eSJouni Malinen abstime.tv_sec = 4; 452cd4e3c3eSJouni Malinen abstime.tv_nsec = 0; 453116be195SKantesh Mundaragi wait(abstime); 454cd4e3c3eSJouni Malinen 455116be195SKantesh Mundaragi return 0; 456cd4e3c3eSJouni Malinen } 457cd4e3c3eSJouni Malinen 458cd4e3c3eSJouni Malinen 459cd4e3c3eSJouni Malinen static int sigma_nan_subscribe_request(struct sigma_dut *dut, 460cd4e3c3eSJouni Malinen struct sigma_conn *conn, 461cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 462cd4e3c3eSJouni Malinen { 463cd4e3c3eSJouni Malinen const char *subscribe_type = get_param(cmd, "SubscribeType"); 464cd4e3c3eSJouni Malinen const char *service_name = get_param(cmd, "ServiceName"); 465cd4e3c3eSJouni Malinen const char *disc_range = get_param(cmd, "DiscoveryRange"); 466cd4e3c3eSJouni Malinen const char *rx_match_filter = get_param(cmd, "rxMatchFilter"); 467cd4e3c3eSJouni Malinen const char *tx_match_filter = get_param(cmd, "txMatchFilter"); 468cd4e3c3eSJouni Malinen const char *sdftx_dw = get_param(cmd, "SDFTxDW"); 469cd4e3c3eSJouni Malinen const char *discrange_ltd = get_param(cmd, "DiscRangeLtd"); 470cd4e3c3eSJouni Malinen const char *include_bit = get_param(cmd, "IncludeBit"); 471cd4e3c3eSJouni Malinen const char *mac = get_param(cmd, "MAC"); 472cd4e3c3eSJouni Malinen const char *srf_type = get_param(cmd, "SRFType"); 473ff76d8cbSRakesh Sunki #if NAN_CERT_VERSION >= 3 474e6f6683bSRakesh Sunki const char *awake_dw_interval = get_param(cmd, "awakeDWint"); 475ff76d8cbSRakesh Sunki #endif 476cd4e3c3eSJouni Malinen NanSubscribeRequest req; 477e6f6683bSRakesh Sunki NanConfigRequest config_req; 478cd4e3c3eSJouni Malinen int filter_len_rx = 0, filter_len_tx = 0; 479cd4e3c3eSJouni Malinen u8 input_rx[NAN_MAX_MATCH_FILTER_LEN]; 480cd4e3c3eSJouni Malinen u8 input_tx[NAN_MAX_MATCH_FILTER_LEN]; 481107356c8SRakesh Sunki wifi_error ret; 482cd4e3c3eSJouni Malinen 483cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanSubscribeRequest)); 484e6f6683bSRakesh Sunki memset(&config_req, 0, sizeof(NanConfigRequest)); 485cd4e3c3eSJouni Malinen req.ttl = 0; 4864625de76SRakesh Sunki req.period = 1; 487cd4e3c3eSJouni Malinen req.subscribe_type = 1; 488cd4e3c3eSJouni Malinen req.serviceResponseFilter = 1; /* MAC */ 489cd4e3c3eSJouni Malinen req.serviceResponseInclude = 0; 490cd4e3c3eSJouni Malinen req.ssiRequiredForMatchIndication = 0; 4911854ec6fSAmarnath Hullur Subramanyam req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS; 492cd4e3c3eSJouni Malinen req.subscribe_count = 0; 493cd4e3c3eSJouni Malinen 49474f4f992SRakesh Sunki if (global_subscribe_service_name_len && 49574f4f992SRakesh Sunki service_name && 49674f4f992SRakesh Sunki strcasecmp((char *) global_subscribe_service_name, 49774f4f992SRakesh Sunki service_name) == 0 && 49874f4f992SRakesh Sunki global_subscribe_id) { 49974f4f992SRakesh Sunki req.subscribe_id = global_subscribe_id; 50074f4f992SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 50174f4f992SRakesh Sunki "%s: updating subscribe_id = %d in subscribe request", 50274f4f992SRakesh Sunki __func__, req.subscribe_id); 50374f4f992SRakesh Sunki } 50474f4f992SRakesh Sunki 505cd4e3c3eSJouni Malinen if (subscribe_type) { 506cd4e3c3eSJouni Malinen if (strcasecmp(subscribe_type, "Active") == 0) { 507cd4e3c3eSJouni Malinen req.subscribe_type = 1; 508cd4e3c3eSJouni Malinen } else if (strcasecmp(subscribe_type, "Passive") == 0) { 509cd4e3c3eSJouni Malinen req.subscribe_type = 0; 510cd4e3c3eSJouni Malinen } else if (strcasecmp(subscribe_type, "Cancel") == 0) { 511cd4e3c3eSJouni Malinen NanSubscribeCancelRequest req; 512cd4e3c3eSJouni Malinen 513cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanSubscribeCancelRequest)); 514107356c8SRakesh Sunki ret = nan_subscribe_cancel_request( 515107356c8SRakesh Sunki 0, global_interface_handle, &req); 516107356c8SRakesh Sunki if (ret != WIFI_SUCCESS) { 517107356c8SRakesh Sunki send_resp(dut, conn, SIGMA_ERROR, 518107356c8SRakesh Sunki "NAN subscribe cancel request failed"); 519107356c8SRakesh Sunki } 520cd4e3c3eSJouni Malinen return 0; 521cd4e3c3eSJouni Malinen } 522cd4e3c3eSJouni Malinen } 523cd4e3c3eSJouni Malinen 524cd4e3c3eSJouni Malinen if (disc_range) 525cd4e3c3eSJouni Malinen req.rssi_threshold_flag = atoi(disc_range); 526cd4e3c3eSJouni Malinen 527cd4e3c3eSJouni Malinen if (sdftx_dw) 528cd4e3c3eSJouni Malinen req.subscribe_count = atoi(sdftx_dw); 529cd4e3c3eSJouni Malinen 530cd4e3c3eSJouni Malinen /* Check this once again if config can be called here (TBD) */ 531cd4e3c3eSJouni Malinen if (discrange_ltd) 532cd4e3c3eSJouni Malinen req.rssi_threshold_flag = atoi(discrange_ltd); 533cd4e3c3eSJouni Malinen 534cd4e3c3eSJouni Malinen if (include_bit) { 535cd4e3c3eSJouni Malinen int include_bit_val = atoi(include_bit); 536cd4e3c3eSJouni Malinen 537cd4e3c3eSJouni Malinen req.serviceResponseInclude = include_bit_val; 538cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d", 539cd4e3c3eSJouni Malinen req.serviceResponseInclude); 540cd4e3c3eSJouni Malinen } 541cd4e3c3eSJouni Malinen 542cd4e3c3eSJouni Malinen if (srf_type) { 543cd4e3c3eSJouni Malinen int srf_type_val = atoi(srf_type); 544cd4e3c3eSJouni Malinen 545cd4e3c3eSJouni Malinen if (srf_type_val == 1) 546cd4e3c3eSJouni Malinen req.serviceResponseFilter = 0; /* Bloom */ 547cd4e3c3eSJouni Malinen else 548cd4e3c3eSJouni Malinen req.serviceResponseFilter = 1; /* MAC */ 549cd4e3c3eSJouni Malinen req.useServiceResponseFilter = 1; 550cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d", 551cd4e3c3eSJouni Malinen req.serviceResponseFilter); 552cd4e3c3eSJouni Malinen } 553cd4e3c3eSJouni Malinen 554cd4e3c3eSJouni Malinen if (mac) { 555cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac); 556cd4e3c3eSJouni Malinen req.num_intf_addr_present = nan_parse_mac_address_list( 557cd4e3c3eSJouni Malinen dut, mac, &req.intf_addr[0][0], 558cd4e3c3eSJouni Malinen NAN_MAX_SUBSCRIBE_MAX_ADDRESS); 559cd4e3c3eSJouni Malinen } 560cd4e3c3eSJouni Malinen 561cd4e3c3eSJouni Malinen memset(input_rx, 0, sizeof(input_rx)); 562cd4e3c3eSJouni Malinen memset(input_tx, 0, sizeof(input_tx)); 563cd4e3c3eSJouni Malinen if (rx_match_filter) { 564cd4e3c3eSJouni Malinen nan_parse_token(rx_match_filter, input_rx, &filter_len_rx); 565cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d", 566cd4e3c3eSJouni Malinen filter_len_rx); 567cd4e3c3eSJouni Malinen } 568cd4e3c3eSJouni Malinen if (tx_match_filter) { 569cd4e3c3eSJouni Malinen nan_parse_token(tx_match_filter, input_tx, &filter_len_tx); 570cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d", 571cd4e3c3eSJouni Malinen filter_len_tx); 572cd4e3c3eSJouni Malinen } 573cd4e3c3eSJouni Malinen 574cd4e3c3eSJouni Malinen if (tx_match_filter) { 575cd4e3c3eSJouni Malinen req.tx_match_filter_len = filter_len_tx; 576cd4e3c3eSJouni Malinen memcpy(req.tx_match_filter, input_tx, filter_len_tx); 577cd4e3c3eSJouni Malinen nan_hex_dump(dut, req.tx_match_filter, filter_len_tx); 578cd4e3c3eSJouni Malinen } 579cd4e3c3eSJouni Malinen if (rx_match_filter) { 580cd4e3c3eSJouni Malinen req.rx_match_filter_len = filter_len_rx; 581cd4e3c3eSJouni Malinen memcpy(req.rx_match_filter, input_rx, filter_len_rx); 582cd4e3c3eSJouni Malinen nan_hex_dump(dut, req.rx_match_filter, filter_len_rx); 583cd4e3c3eSJouni Malinen } 584cd4e3c3eSJouni Malinen 585132c6d2bSKantesh Mundaragi if (service_name) { 586cd4e3c3eSJouni Malinen strlcpy((char *) req.service_name, service_name, 587cd4e3c3eSJouni Malinen strlen(service_name) + 1); 588cd4e3c3eSJouni Malinen req.service_name_len = strlen(service_name); 58974f4f992SRakesh Sunki strlcpy((char *) global_subscribe_service_name, service_name, 59074f4f992SRakesh Sunki sizeof(global_subscribe_service_name)); 59174f4f992SRakesh Sunki global_subscribe_service_name_len = 59274f4f992SRakesh Sunki strlen((char *) global_subscribe_service_name); 593132c6d2bSKantesh Mundaragi } 594cd4e3c3eSJouni Malinen 595ff76d8cbSRakesh Sunki #if NAN_CERT_VERSION >= 3 596e6f6683bSRakesh Sunki if (awake_dw_interval) { 597e6f6683bSRakesh Sunki int input_dw_interval_val = atoi(awake_dw_interval); 598e6f6683bSRakesh Sunki int awake_dw_int = 0; 599e6f6683bSRakesh Sunki 600e6f6683bSRakesh Sunki if (input_dw_interval_val > NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL) { 601e6f6683bSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 602e6f6683bSRakesh Sunki "%s: input active dw interval = %d overwritting dw interval to Max allowed dw interval 16", 603e6f6683bSRakesh Sunki __func__, input_dw_interval_val); 604e6f6683bSRakesh Sunki input_dw_interval_val = 605e6f6683bSRakesh Sunki NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL; 606e6f6683bSRakesh Sunki } 607e6f6683bSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 608e6f6683bSRakesh Sunki "%s: input active DW interval = %d", 609e6f6683bSRakesh Sunki __func__, input_dw_interval_val); 610e6f6683bSRakesh Sunki /* 611e6f6683bSRakesh Sunki * Indicates the interval for Sync beacons and SDF's in 2.4 GHz 612e6f6683bSRakesh Sunki * or 5 GHz band. Valid values of DW Interval are: 1, 2, 3, 4, 613e6f6683bSRakesh Sunki * and 5; 0 is reserved. The SDF includes in OTA when enabled. 614e6f6683bSRakesh Sunki * The publish/subscribe period values don't override the device 615e6f6683bSRakesh Sunki * level configurations. 616e6f6683bSRakesh Sunki * input_dw_interval_val is provided by the user are in the 617e6f6683bSRakesh Sunki * format 2^n-1 = 1/2/4/8/16. Internal implementation expects n 618e6f6683bSRakesh Sunki * to be passed to indicate the awake_dw_interval. 619e6f6683bSRakesh Sunki */ 620e6f6683bSRakesh Sunki if (input_dw_interval_val == 1 || 621e6f6683bSRakesh Sunki input_dw_interval_val % 2 == 0) { 622e6f6683bSRakesh Sunki while (input_dw_interval_val > 0) { 623e6f6683bSRakesh Sunki input_dw_interval_val >>= 1; 624e6f6683bSRakesh Sunki awake_dw_int++; 625e6f6683bSRakesh Sunki } 626e6f6683bSRakesh Sunki } 627e6f6683bSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 628e6f6683bSRakesh Sunki "%s:converted active DW interval = %d", 629e6f6683bSRakesh Sunki __func__, awake_dw_int); 630e6f6683bSRakesh Sunki config_req.config_dw.config_2dot4g_dw_band = 1; 631e6f6683bSRakesh Sunki config_req.config_dw.dw_2dot4g_interval_val = awake_dw_int; 632e6f6683bSRakesh Sunki config_req.config_dw.config_5g_dw_band = 1; 633e6f6683bSRakesh Sunki config_req.config_dw.dw_5g_interval_val = awake_dw_int; 634e6f6683bSRakesh Sunki ret = nan_config_request(0, global_interface_handle, 635e6f6683bSRakesh Sunki &config_req); 636e6f6683bSRakesh Sunki if (ret != WIFI_SUCCESS) { 637e6f6683bSRakesh Sunki sigma_dut_print(dut, DUT_MSG_ERROR, 638e6f6683bSRakesh Sunki "%s:NAN config request failed", 639e6f6683bSRakesh Sunki __func__); 640e6f6683bSRakesh Sunki return -2; 641e6f6683bSRakesh Sunki } 642e6f6683bSRakesh Sunki } 643ff76d8cbSRakesh Sunki #endif 644e6f6683bSRakesh Sunki 645107356c8SRakesh Sunki ret = nan_subscribe_request(0, global_interface_handle, &req); 646107356c8SRakesh Sunki if (ret != WIFI_SUCCESS) { 647107356c8SRakesh Sunki send_resp(dut, conn, SIGMA_ERROR, 648107356c8SRakesh Sunki "NAN subscribe request failed"); 649107356c8SRakesh Sunki } 650107356c8SRakesh Sunki 651cd4e3c3eSJouni Malinen return 0; 652cd4e3c3eSJouni Malinen } 653cd4e3c3eSJouni Malinen 654cd4e3c3eSJouni Malinen 655d7344c02SRakesh Sunki static int sigma_ndp_configure_band(struct sigma_dut *dut, 656d7344c02SRakesh Sunki struct sigma_conn *conn, 657d7344c02SRakesh Sunki struct sigma_cmd *cmd, 658d7344c02SRakesh Sunki NdpSupportedBand band_config_val) 659d7344c02SRakesh Sunki { 660d7344c02SRakesh Sunki wifi_error ret; 661d7344c02SRakesh Sunki NanDebugParams cfg_debug; 662d7344c02SRakesh Sunki int size; 663d7344c02SRakesh Sunki 664d7344c02SRakesh Sunki memset(&cfg_debug, 0, sizeof(NanDebugParams)); 665d7344c02SRakesh Sunki cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS; 666d7344c02SRakesh Sunki memcpy(cfg_debug.debug_cmd_data, &band_config_val, sizeof(int)); 667d7344c02SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, "%s:setting debug cmd=0x%x", 668d7344c02SRakesh Sunki __func__, cfg_debug.cmd); 669d7344c02SRakesh Sunki size = sizeof(u32) + sizeof(int); 670d7344c02SRakesh Sunki ret = nan_debug_command_config(0, global_interface_handle, cfg_debug, 671d7344c02SRakesh Sunki size); 672d7344c02SRakesh Sunki if (ret != WIFI_SUCCESS) 673d7344c02SRakesh Sunki send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed"); 674d7344c02SRakesh Sunki 675d7344c02SRakesh Sunki return 0; 676d7344c02SRakesh Sunki } 677d7344c02SRakesh Sunki 678d7344c02SRakesh Sunki 67914cfcd25SRakesh Sunki static int sigma_nan_data_request(struct sigma_dut *dut, 68014cfcd25SRakesh Sunki struct sigma_conn *conn, 68114cfcd25SRakesh Sunki struct sigma_cmd *cmd) 68214cfcd25SRakesh Sunki { 68314cfcd25SRakesh Sunki const char *ndp_security = get_param(cmd, "DataPathSecurity"); 68414cfcd25SRakesh Sunki const char *ndp_resp_mac = get_param(cmd, "RespNanMac"); 68514cfcd25SRakesh Sunki const char *include_immutable = get_param(cmd, "includeimmutable"); 68614cfcd25SRakesh Sunki const char *avoid_channel = get_param(cmd, "avoidchannel"); 68714cfcd25SRakesh Sunki const char *invalid_nan_schedule = get_param(cmd, "InvalidNANSchedule"); 68814cfcd25SRakesh Sunki const char *map_order = get_param(cmd, "maporder"); 6898a4845d0SRakesh Sunki #if NAN_CERT_VERSION >= 3 6908a4845d0SRakesh Sunki const char *qos_config = get_param(cmd, "QoS"); 6918a4845d0SRakesh Sunki #endif 69214cfcd25SRakesh Sunki wifi_error ret; 69314cfcd25SRakesh Sunki NanDataPathInitiatorRequest init_req; 69414cfcd25SRakesh Sunki NanDebugParams cfg_debug; 69514cfcd25SRakesh Sunki int size; 69614cfcd25SRakesh Sunki 69714cfcd25SRakesh Sunki memset(&init_req, 0, sizeof(NanDataPathInitiatorRequest)); 69814cfcd25SRakesh Sunki 69914cfcd25SRakesh Sunki if (ndp_security) { 70014cfcd25SRakesh Sunki if (strcasecmp(ndp_security, "open") == 0) 70114cfcd25SRakesh Sunki init_req.ndp_cfg.security_cfg = 70214cfcd25SRakesh Sunki NAN_DP_CONFIG_NO_SECURITY; 70314cfcd25SRakesh Sunki else if (strcasecmp(ndp_security, "secure") == 0) 70414cfcd25SRakesh Sunki init_req.ndp_cfg.security_cfg = NAN_DP_CONFIG_SECURITY; 70514cfcd25SRakesh Sunki } 70614cfcd25SRakesh Sunki 70714cfcd25SRakesh Sunki if (include_immutable) { 70814cfcd25SRakesh Sunki int include_immutable_val = 0; 70914cfcd25SRakesh Sunki 71014cfcd25SRakesh Sunki memset(&cfg_debug, 0, sizeof(NanDebugParams)); 71114cfcd25SRakesh Sunki cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE; 71214cfcd25SRakesh Sunki include_immutable_val = atoi(include_immutable); 71314cfcd25SRakesh Sunki memcpy(cfg_debug.debug_cmd_data, &include_immutable_val, 71414cfcd25SRakesh Sunki sizeof(int)); 71514cfcd25SRakesh Sunki size = sizeof(u32) + sizeof(int); 71614cfcd25SRakesh Sunki nan_debug_command_config(0, global_interface_handle, 71714cfcd25SRakesh Sunki cfg_debug, size); 71814cfcd25SRakesh Sunki } 71914cfcd25SRakesh Sunki 72014cfcd25SRakesh Sunki if (avoid_channel) { 72114cfcd25SRakesh Sunki int avoid_channel_freq = 0; 72214cfcd25SRakesh Sunki 72314cfcd25SRakesh Sunki memset(&cfg_debug, 0, sizeof(NanDebugParams)); 72414cfcd25SRakesh Sunki avoid_channel_freq = channel_to_freq(atoi(avoid_channel)); 72514cfcd25SRakesh Sunki cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL; 72614cfcd25SRakesh Sunki memcpy(cfg_debug.debug_cmd_data, &avoid_channel_freq, 72714cfcd25SRakesh Sunki sizeof(int)); 72814cfcd25SRakesh Sunki size = sizeof(u32) + sizeof(int); 72914cfcd25SRakesh Sunki nan_debug_command_config(0, global_interface_handle, 73014cfcd25SRakesh Sunki cfg_debug, size); 73114cfcd25SRakesh Sunki } 73214cfcd25SRakesh Sunki 73314cfcd25SRakesh Sunki if (invalid_nan_schedule) { 73414cfcd25SRakesh Sunki int invalid_nan_schedule_type = 0; 73514cfcd25SRakesh Sunki 73614cfcd25SRakesh Sunki memset(&cfg_debug, 0, sizeof(NanDebugParams)); 73714cfcd25SRakesh Sunki invalid_nan_schedule_type = atoi(invalid_nan_schedule); 73814cfcd25SRakesh Sunki cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_TYPE; 73914cfcd25SRakesh Sunki memcpy(cfg_debug.debug_cmd_data, 74014cfcd25SRakesh Sunki &invalid_nan_schedule_type, sizeof(int)); 74114cfcd25SRakesh Sunki size = sizeof(u32) + sizeof(int); 74214cfcd25SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 74314cfcd25SRakesh Sunki "%s: invalid schedule type: cmd type = %d and command data = %d", 74414cfcd25SRakesh Sunki __func__, cfg_debug.cmd, 74514cfcd25SRakesh Sunki invalid_nan_schedule_type); 74614cfcd25SRakesh Sunki nan_debug_command_config(0, global_interface_handle, 74714cfcd25SRakesh Sunki cfg_debug, size); 74814cfcd25SRakesh Sunki } 74914cfcd25SRakesh Sunki 75014cfcd25SRakesh Sunki if (map_order) { 75114cfcd25SRakesh Sunki int map_order_val = 0; 75214cfcd25SRakesh Sunki 75314cfcd25SRakesh Sunki memset(&cfg_debug, 0, sizeof(NanDebugParams)); 75414cfcd25SRakesh Sunki cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER; 75514cfcd25SRakesh Sunki map_order_val = atoi(map_order); 75614cfcd25SRakesh Sunki memcpy(cfg_debug.debug_cmd_data, &map_order_val, sizeof(int)); 75714cfcd25SRakesh Sunki size = sizeof(u32) + sizeof(int); 75814cfcd25SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 75914cfcd25SRakesh Sunki "%s: map order: cmd type = %d and command data = %d", 76014cfcd25SRakesh Sunki __func__, 7619eaa677aSRakesh Sunki cfg_debug.cmd, map_order_val); 76214cfcd25SRakesh Sunki nan_debug_command_config(0, global_interface_handle, 76314cfcd25SRakesh Sunki cfg_debug, size); 76414cfcd25SRakesh Sunki } 76514cfcd25SRakesh Sunki 7668a4845d0SRakesh Sunki #if NAN_CERT_VERSION >= 3 7678a4845d0SRakesh Sunki if (qos_config) { 7688a4845d0SRakesh Sunki u32 qos_config_val = 0; 7698a4845d0SRakesh Sunki 7708a4845d0SRakesh Sunki memset(&cfg_debug, 0, sizeof(NanDebugParams)); 7718a4845d0SRakesh Sunki cfg_debug.cmd = NAN_TEST_MODE_CMD_CONFIG_QOS; 7728a4845d0SRakesh Sunki qos_config_val = atoi(qos_config); 7738a4845d0SRakesh Sunki memcpy(cfg_debug.debug_cmd_data, &qos_config_val, sizeof(u32)); 7748a4845d0SRakesh Sunki size = sizeof(u32) + sizeof(u32); 7758a4845d0SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 7768a4845d0SRakesh Sunki "%s: qos config: cmd type = %d and command data = %d", 7778a4845d0SRakesh Sunki __func__, cfg_debug.cmd, qos_config_val); 7788a4845d0SRakesh Sunki nan_debug_command_config(0, global_interface_handle, 7798a4845d0SRakesh Sunki cfg_debug, size); 7808a4845d0SRakesh Sunki } 7818a4845d0SRakesh Sunki #endif 7828a4845d0SRakesh Sunki 78314cfcd25SRakesh Sunki /* 78414cfcd25SRakesh Sunki * Setting this flag, so that interface for ping6 command 78514cfcd25SRakesh Sunki * is set appropriately in traffic_send_ping(). 78614cfcd25SRakesh Sunki */ 78714cfcd25SRakesh Sunki dut->ndp_enable = 1; 78814cfcd25SRakesh Sunki 78914cfcd25SRakesh Sunki /* 79014cfcd25SRakesh Sunki * Intended sleep after NAN data interface create 79114cfcd25SRakesh Sunki * before the NAN data request 79214cfcd25SRakesh Sunki */ 79314cfcd25SRakesh Sunki sleep(4); 79414cfcd25SRakesh Sunki 79514cfcd25SRakesh Sunki init_req.requestor_instance_id = global_match_handle; 79614cfcd25SRakesh Sunki strlcpy((char *) init_req.ndp_iface, "nan0", 79714cfcd25SRakesh Sunki sizeof(init_req.ndp_iface)); 79814cfcd25SRakesh Sunki 79914cfcd25SRakesh Sunki if (ndp_resp_mac) { 80014cfcd25SRakesh Sunki nan_parse_mac_address(dut, ndp_resp_mac, 80114cfcd25SRakesh Sunki init_req.peer_disc_mac_addr); 80214cfcd25SRakesh Sunki sigma_dut_print( 80314cfcd25SRakesh Sunki dut, DUT_MSG_INFO, "PEER MAC ADDR: " MAC_ADDR_STR, 80414cfcd25SRakesh Sunki MAC_ADDR_ARRAY(init_req.peer_disc_mac_addr)); 80514cfcd25SRakesh Sunki } else { 80614cfcd25SRakesh Sunki memcpy(init_req.peer_disc_mac_addr, global_peer_mac_addr, 80714cfcd25SRakesh Sunki sizeof(init_req.peer_disc_mac_addr)); 80814cfcd25SRakesh Sunki } 80914cfcd25SRakesh Sunki 81014cfcd25SRakesh Sunki /* Not requesting the channel and letting FW decide */ 81114cfcd25SRakesh Sunki if (dut->sta_channel == 0) { 81214cfcd25SRakesh Sunki init_req.channel_request_type = NAN_DP_CHANNEL_NOT_REQUESTED; 81314cfcd25SRakesh Sunki init_req.channel = 0; 81414cfcd25SRakesh Sunki } else { 81514cfcd25SRakesh Sunki init_req.channel_request_type = NAN_DP_FORCE_CHANNEL_SETUP; 81614cfcd25SRakesh Sunki init_req.channel = channel_to_freq(dut->sta_channel); 81714cfcd25SRakesh Sunki } 81814cfcd25SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 81914cfcd25SRakesh Sunki "%s: Initiator Request: Channel = %d Channel Request Type = %d", 82014cfcd25SRakesh Sunki __func__, init_req.channel, 82114cfcd25SRakesh Sunki init_req.channel_request_type); 82214cfcd25SRakesh Sunki 82314cfcd25SRakesh Sunki if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) { 824395b0157SRakesh Sunki init_req.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK; 82514cfcd25SRakesh Sunki memcpy(&init_req.key_info.body.pmk_info.pmk[0], 82614cfcd25SRakesh Sunki &dut->nan_pmk[0], NAN_PMK_INFO_LEN); 82714cfcd25SRakesh Sunki init_req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN; 82814cfcd25SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d", 82914cfcd25SRakesh Sunki __func__, 83014cfcd25SRakesh Sunki init_req.key_info.body.pmk_info.pmk_len); 83114cfcd25SRakesh Sunki } 83214cfcd25SRakesh Sunki 83314cfcd25SRakesh Sunki ret = nan_data_request_initiator(0, global_interface_handle, &init_req); 83414cfcd25SRakesh Sunki if (ret != WIFI_SUCCESS) { 83514cfcd25SRakesh Sunki send_resp(dut, conn, SIGMA_ERROR, 83614cfcd25SRakesh Sunki "Unable to initiate nan data request"); 83714cfcd25SRakesh Sunki return 0; 83814cfcd25SRakesh Sunki } 83914cfcd25SRakesh Sunki 84014cfcd25SRakesh Sunki return 0; 84114cfcd25SRakesh Sunki } 84214cfcd25SRakesh Sunki 84314cfcd25SRakesh Sunki 844a5cc284dSRakesh Sunki static int sigma_nan_data_response(struct sigma_dut *dut, 845a5cc284dSRakesh Sunki struct sigma_conn *conn, 846a5cc284dSRakesh Sunki struct sigma_cmd *cmd) 847a5cc284dSRakesh Sunki { 848a5cc284dSRakesh Sunki const char *ndl_response = get_param(cmd, "NDLresponse"); 849a5cc284dSRakesh Sunki const char *m4_response_type = get_param(cmd, "M4ResponseType"); 850a5cc284dSRakesh Sunki wifi_error ret; 851a5cc284dSRakesh Sunki NanDebugParams cfg_debug; 852a5cc284dSRakesh Sunki int size; 853a5cc284dSRakesh Sunki 854a5cc284dSRakesh Sunki if (ndl_response) { 855a5cc284dSRakesh Sunki int auto_responder_mode_val = 0; 856a5cc284dSRakesh Sunki 857a5cc284dSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 858a5cc284dSRakesh Sunki "%s: ndl_response = (%s) is passed", 859a5cc284dSRakesh Sunki __func__, ndl_response); 860a5cc284dSRakesh Sunki memset(&cfg_debug, 0, sizeof(NanDebugParams)); 861a5cc284dSRakesh Sunki cfg_debug.cmd = NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE; 862a5cc284dSRakesh Sunki if (strcasecmp(ndl_response, "Auto") == 0) { 863a5cc284dSRakesh Sunki auto_responder_mode_val = NAN_DATA_RESPONDER_MODE_AUTO; 864a5cc284dSRakesh Sunki } else if (strcasecmp(ndl_response, "Reject") == 0) { 865a5cc284dSRakesh Sunki auto_responder_mode_val = 866a5cc284dSRakesh Sunki NAN_DATA_RESPONDER_MODE_REJECT; 867a5cc284dSRakesh Sunki } else if (strcasecmp(ndl_response, "Accept") == 0) { 868a5cc284dSRakesh Sunki auto_responder_mode_val = 869a5cc284dSRakesh Sunki NAN_DATA_RESPONDER_MODE_ACCEPT; 870a5cc284dSRakesh Sunki } else if (strcasecmp(ndl_response, "Counter") == 0) { 871a5cc284dSRakesh Sunki auto_responder_mode_val = 872a5cc284dSRakesh Sunki NAN_DATA_RESPONDER_MODE_COUNTER; 873a5cc284dSRakesh Sunki } else { 874a5cc284dSRakesh Sunki sigma_dut_print(dut, DUT_MSG_ERROR, 875a5cc284dSRakesh Sunki "%s: Invalid ndl_response", 876a5cc284dSRakesh Sunki __func__); 877a5cc284dSRakesh Sunki return 0; 878a5cc284dSRakesh Sunki } 879a5cc284dSRakesh Sunki memcpy(cfg_debug.debug_cmd_data, &auto_responder_mode_val, 880a5cc284dSRakesh Sunki sizeof(int)); 881a5cc284dSRakesh Sunki size = sizeof(u32) + sizeof(int); 882a5cc284dSRakesh Sunki ret = nan_debug_command_config(0, global_interface_handle, 883a5cc284dSRakesh Sunki cfg_debug, size); 884a5cc284dSRakesh Sunki if (ret != WIFI_SUCCESS) { 885a5cc284dSRakesh Sunki send_resp(dut, conn, SIGMA_ERROR, 886a5cc284dSRakesh Sunki "Nan config request failed"); 887a5cc284dSRakesh Sunki } 888a5cc284dSRakesh Sunki } 889a5cc284dSRakesh Sunki 890a5cc284dSRakesh Sunki if (m4_response_type) { 891a5cc284dSRakesh Sunki int m4_response_type_val = 0; 892a5cc284dSRakesh Sunki 893a5cc284dSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 894a5cc284dSRakesh Sunki "%s: m4_response_type = (%s) is passed", 895a5cc284dSRakesh Sunki __func__, m4_response_type); 896a5cc284dSRakesh Sunki memset(&cfg_debug, 0, sizeof(NanDebugParams)); 897a5cc284dSRakesh Sunki cfg_debug.cmd = NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE; 898a5cc284dSRakesh Sunki if (strcasecmp(m4_response_type, "Accept") == 0) 899a5cc284dSRakesh Sunki m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_ACCEPT; 900a5cc284dSRakesh Sunki else if (strcasecmp(m4_response_type, "Reject") == 0) 901a5cc284dSRakesh Sunki m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_REJECT; 902a5cc284dSRakesh Sunki else if (strcasecmp(m4_response_type, "BadMic") == 0) 903a5cc284dSRakesh Sunki m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_BADMIC; 904a5cc284dSRakesh Sunki 905a5cc284dSRakesh Sunki memcpy(cfg_debug.debug_cmd_data, &m4_response_type_val, 906a5cc284dSRakesh Sunki sizeof(int)); 907a5cc284dSRakesh Sunki size = sizeof(u32) + sizeof(int); 908a5cc284dSRakesh Sunki ret = nan_debug_command_config(0, global_interface_handle, 909a5cc284dSRakesh Sunki cfg_debug, size); 910a5cc284dSRakesh Sunki if (ret != WIFI_SUCCESS) { 911a5cc284dSRakesh Sunki send_resp(dut, conn, SIGMA_ERROR, 912a5cc284dSRakesh Sunki "Nan config request failed"); 913a5cc284dSRakesh Sunki } 914a5cc284dSRakesh Sunki } 915a5cc284dSRakesh Sunki 916a5cc284dSRakesh Sunki return 0; 917a5cc284dSRakesh Sunki } 918a5cc284dSRakesh Sunki 919a5cc284dSRakesh Sunki 9208a630b8eSRakesh Sunki static int sigma_nan_data_end(struct sigma_dut *dut, struct sigma_cmd *cmd) 9218a630b8eSRakesh Sunki { 9228a630b8eSRakesh Sunki const char *nmf_security_config = get_param(cmd, "Security"); 9238a630b8eSRakesh Sunki NanDataPathEndRequest req; 9248a630b8eSRakesh Sunki NanDebugParams cfg_debug; 9258a630b8eSRakesh Sunki int size; 9268a630b8eSRakesh Sunki 9278a630b8eSRakesh Sunki memset(&req, 0, sizeof(NanDataPathEndRequest)); 9288a630b8eSRakesh Sunki memset(&cfg_debug, 0, sizeof(NanDebugParams)); 9298a630b8eSRakesh Sunki if (nmf_security_config) { 9308a630b8eSRakesh Sunki int nmf_security_config_val = 0; 9318a630b8eSRakesh Sunki 9328a630b8eSRakesh Sunki cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_NMF_CLEAR_CONFIG; 9338a630b8eSRakesh Sunki if (strcasecmp(nmf_security_config, "open") == 0) 9348a630b8eSRakesh Sunki nmf_security_config_val = NAN_NMF_CLEAR_ENABLE; 9358a630b8eSRakesh Sunki else if (strcasecmp(nmf_security_config, "secure") == 0) 9368a630b8eSRakesh Sunki nmf_security_config_val = NAN_NMF_CLEAR_DISABLE; 9378a630b8eSRakesh Sunki memcpy(cfg_debug.debug_cmd_data, 9388a630b8eSRakesh Sunki &nmf_security_config_val, sizeof(int)); 9398a630b8eSRakesh Sunki size = sizeof(u32) + sizeof(int); 9408a630b8eSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 9418a630b8eSRakesh Sunki "%s: nmf_security_config_val -- cmd type = %d and command data = %d", 9428a630b8eSRakesh Sunki __func__, cfg_debug.cmd, 9438a630b8eSRakesh Sunki nmf_security_config_val); 9448a630b8eSRakesh Sunki nan_debug_command_config(0, global_interface_handle, 9458a630b8eSRakesh Sunki cfg_debug, size); 9468a630b8eSRakesh Sunki } 9478a630b8eSRakesh Sunki 9488a630b8eSRakesh Sunki req.num_ndp_instances = 1; 9498a630b8eSRakesh Sunki req.ndp_instance_id[0] = global_ndp_instance_id; 9508a630b8eSRakesh Sunki 9518a630b8eSRakesh Sunki nan_data_end(0, global_interface_handle, &req); 9528a630b8eSRakesh Sunki return 0; 9538a630b8eSRakesh Sunki } 9548a630b8eSRakesh Sunki 9558a630b8eSRakesh Sunki 956d5e9b4d1SRakesh Sunki static int sigma_nan_range_request(struct sigma_dut *dut, 957d5e9b4d1SRakesh Sunki struct sigma_cmd *cmd) 958d5e9b4d1SRakesh Sunki { 959d5e9b4d1SRakesh Sunki const char *dest_mac = get_param(cmd, "destmac"); 960d5e9b4d1SRakesh Sunki NanSubscribeRequest req; 961d5e9b4d1SRakesh Sunki 962d5e9b4d1SRakesh Sunki memset(&req, 0, sizeof(NanSubscribeRequest)); 963d5e9b4d1SRakesh Sunki req.period = 1; 9643834be5bSRakesh Sunki req.subscribe_type = NAN_SUBSCRIBE_TYPE_PASSIVE; 965d5e9b4d1SRakesh Sunki req.serviceResponseFilter = NAN_SRF_ATTR_BLOOM_FILTER; 966d5e9b4d1SRakesh Sunki req.serviceResponseInclude = NAN_SRF_INCLUDE_RESPOND; 967d5e9b4d1SRakesh Sunki req.ssiRequiredForMatchIndication = NAN_SSI_NOT_REQUIRED_IN_MATCH_IND; 968d5e9b4d1SRakesh Sunki req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS; 969d5e9b4d1SRakesh Sunki req.subscribe_count = 0; 970d5e9b4d1SRakesh Sunki strlcpy((char *) req.service_name, DEFAULT_SVC, 971d5e9b4d1SRakesh Sunki NAN_MAX_SERVICE_NAME_LEN); 972d5e9b4d1SRakesh Sunki req.service_name_len = strlen((char *) req.service_name); 973d5e9b4d1SRakesh Sunki 974d5e9b4d1SRakesh Sunki req.subscribe_id = global_subscribe_id; 975d5e9b4d1SRakesh Sunki req.sdea_params.ranging_state = 1; 976d5e9b4d1SRakesh Sunki req.sdea_params.range_report = NAN_ENABLE_RANGE_REPORT; 977d5e9b4d1SRakesh Sunki req.range_response_cfg.requestor_instance_id = global_match_handle; 978d5e9b4d1SRakesh Sunki req.range_response_cfg.ranging_response = NAN_RANGE_REQUEST_ACCEPT; 979d5e9b4d1SRakesh Sunki req.ranging_cfg.config_ranging_indications = 980d5e9b4d1SRakesh Sunki NAN_RANGING_INDICATE_CONTINUOUS_MASK; 981d5e9b4d1SRakesh Sunki if (dest_mac) { 982d5e9b4d1SRakesh Sunki nan_parse_mac_address(dut, dest_mac, 983d5e9b4d1SRakesh Sunki req.range_response_cfg.peer_addr); 984d5e9b4d1SRakesh Sunki sigma_dut_print( 985d5e9b4d1SRakesh Sunki dut, DUT_MSG_INFO, "peer mac addr: " MAC_ADDR_STR, 986d5e9b4d1SRakesh Sunki MAC_ADDR_ARRAY(req.range_response_cfg.peer_addr)); 987d5e9b4d1SRakesh Sunki } 988d5e9b4d1SRakesh Sunki nan_subscribe_request(0, global_interface_handle, &req); 989d5e9b4d1SRakesh Sunki 990d5e9b4d1SRakesh Sunki return 0; 991d5e9b4d1SRakesh Sunki } 992d5e9b4d1SRakesh Sunki 993d5e9b4d1SRakesh Sunki 994d5e9b4d1SRakesh Sunki static int sigma_nan_cancel_range(struct sigma_dut *dut, 995d5e9b4d1SRakesh Sunki struct sigma_cmd *cmd) 996d5e9b4d1SRakesh Sunki { 997d5e9b4d1SRakesh Sunki const char *dest_mac = get_param(cmd, "destmac"); 998d5e9b4d1SRakesh Sunki NanPublishRequest req; 999d5e9b4d1SRakesh Sunki 1000d5e9b4d1SRakesh Sunki memset(&req, 0, sizeof(NanPublishRequest)); 1001d5e9b4d1SRakesh Sunki req.ttl = 0; 1002d5e9b4d1SRakesh Sunki req.period = 1; 1003d5e9b4d1SRakesh Sunki req.publish_match_indicator = 1; 1004d5e9b4d1SRakesh Sunki req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED; 1005d5e9b4d1SRakesh Sunki req.tx_type = NAN_TX_TYPE_BROADCAST; 1006d5e9b4d1SRakesh Sunki req.publish_count = 0; 1007d5e9b4d1SRakesh Sunki strlcpy((char *) req.service_name, DEFAULT_SVC, 1008d5e9b4d1SRakesh Sunki NAN_MAX_SERVICE_NAME_LEN); 1009d5e9b4d1SRakesh Sunki req.service_name_len = strlen((char *) req.service_name); 1010d5e9b4d1SRakesh Sunki req.publish_id = global_publish_id; 1011d5e9b4d1SRakesh Sunki req.range_response_cfg.ranging_response = NAN_RANGE_REQUEST_CANCEL; 1012d5e9b4d1SRakesh Sunki if (dest_mac) { 1013d5e9b4d1SRakesh Sunki nan_parse_mac_address(dut, dest_mac, 1014d5e9b4d1SRakesh Sunki req.range_response_cfg.peer_addr); 1015d5e9b4d1SRakesh Sunki sigma_dut_print( 1016d5e9b4d1SRakesh Sunki dut, DUT_MSG_INFO, "peer mac addr: " MAC_ADDR_STR, 1017d5e9b4d1SRakesh Sunki MAC_ADDR_ARRAY(req.range_response_cfg.peer_addr)); 1018d5e9b4d1SRakesh Sunki } 1019d5e9b4d1SRakesh Sunki nan_publish_request(0, global_interface_handle, &req); 1020d5e9b4d1SRakesh Sunki 1021d5e9b4d1SRakesh Sunki return 0; 1022d5e9b4d1SRakesh Sunki } 1023d5e9b4d1SRakesh Sunki 1024d5e9b4d1SRakesh Sunki 1025b2b6516cSRakesh Sunki static int sigma_nan_schedule_update(struct sigma_dut *dut, 1026b2b6516cSRakesh Sunki struct sigma_cmd *cmd) 1027b2b6516cSRakesh Sunki { 1028b2b6516cSRakesh Sunki const char *schedule_update_type = get_param(cmd, "type"); 1029b2b6516cSRakesh Sunki const char *channel_availability = get_param(cmd, 1030b2b6516cSRakesh Sunki "ChannelAvailability"); 1031b2b6516cSRakesh Sunki const char *responder_nmi_mac = get_param(cmd, "ResponderNMI"); 1032b2b6516cSRakesh Sunki NanDebugParams cfg_debug; 1033b2b6516cSRakesh Sunki int size = 0; 1034b2b6516cSRakesh Sunki 1035b2b6516cSRakesh Sunki memset(&cfg_debug, 0, sizeof(NanDebugParams)); 1036b2b6516cSRakesh Sunki 1037b2b6516cSRakesh Sunki if (!schedule_update_type) 1038b2b6516cSRakesh Sunki return 0; 1039b2b6516cSRakesh Sunki 1040b2b6516cSRakesh Sunki if (strcasecmp(schedule_update_type, "ULWnotify") == 0) { 1041b2b6516cSRakesh Sunki cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY; 1042b2b6516cSRakesh Sunki size = sizeof(u32); 1043b2b6516cSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 1044b2b6516cSRakesh Sunki "%s: Schedule Update cmd type = %d", __func__, 1045b2b6516cSRakesh Sunki cfg_debug.cmd); 1046b2b6516cSRakesh Sunki if (channel_availability) { 1047b2b6516cSRakesh Sunki int channel_availability_val; 1048b2b6516cSRakesh Sunki 1049b2b6516cSRakesh Sunki channel_availability_val = atoi(channel_availability); 1050b2b6516cSRakesh Sunki size += sizeof(int); 1051b2b6516cSRakesh Sunki memcpy(cfg_debug.debug_cmd_data, 1052b2b6516cSRakesh Sunki &channel_availability_val, sizeof(int)); 1053b2b6516cSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 1054b2b6516cSRakesh Sunki "%s: Schedule Update cmd data = %d size = %d", 1055b2b6516cSRakesh Sunki __func__, channel_availability_val, 1056b2b6516cSRakesh Sunki size); 1057b2b6516cSRakesh Sunki } 1058b2b6516cSRakesh Sunki } else if (strcasecmp(schedule_update_type, "NDLnegotiate") == 0) { 1059b2b6516cSRakesh Sunki cfg_debug.cmd = 1060b2b6516cSRakesh Sunki NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE; 1061b2b6516cSRakesh Sunki size = sizeof(u32); 1062b2b6516cSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 1063b2b6516cSRakesh Sunki "%s: Schedule Update cmd type = %d", __func__, 1064b2b6516cSRakesh Sunki cfg_debug.cmd); 1065b2b6516cSRakesh Sunki if (responder_nmi_mac) { 1066b2b6516cSRakesh Sunki u8 responder_nmi_mac_addr[NAN_MAC_ADDR_LEN]; 1067b2b6516cSRakesh Sunki 1068b2b6516cSRakesh Sunki nan_parse_mac_address(dut, responder_nmi_mac, 1069b2b6516cSRakesh Sunki responder_nmi_mac_addr); 1070b2b6516cSRakesh Sunki size += NAN_MAC_ADDR_LEN; 1071b2b6516cSRakesh Sunki memcpy(cfg_debug.debug_cmd_data, responder_nmi_mac_addr, 1072b2b6516cSRakesh Sunki NAN_MAC_ADDR_LEN); 1073b2b6516cSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 1074b2b6516cSRakesh Sunki "%s: RESPONDER NMI MAC: "MAC_ADDR_STR, 1075b2b6516cSRakesh Sunki __func__, 1076b2b6516cSRakesh Sunki MAC_ADDR_ARRAY(responder_nmi_mac_addr)); 1077b2b6516cSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 1078b2b6516cSRakesh Sunki "%s: Schedule Update: cmd size = %d", 1079b2b6516cSRakesh Sunki __func__, size); 1080b2b6516cSRakesh Sunki } 1081b2b6516cSRakesh Sunki } else if (strcasecmp(schedule_update_type, "NDLnotify") == 0) { 1082b2b6516cSRakesh Sunki cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY; 1083b2b6516cSRakesh Sunki size = sizeof(u32); 1084b2b6516cSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 1085b2b6516cSRakesh Sunki "%s: Schedule Update cmd type = %d", __func__, 1086b2b6516cSRakesh Sunki cfg_debug.cmd); 1087b2b6516cSRakesh Sunki } 1088b2b6516cSRakesh Sunki 1089b2b6516cSRakesh Sunki nan_debug_command_config(0, global_interface_handle, cfg_debug, size); 1090b2b6516cSRakesh Sunki 1091b2b6516cSRakesh Sunki return 0; 1092b2b6516cSRakesh Sunki } 1093b2b6516cSRakesh Sunki 1094b2b6516cSRakesh Sunki 1095cd4e3c3eSJouni Malinen int config_post_disc_attr(void) 1096cd4e3c3eSJouni Malinen { 1097107356c8SRakesh Sunki wifi_error ret; 1098cd4e3c3eSJouni Malinen NanConfigRequest configReq; 1099cd4e3c3eSJouni Malinen 1100cd4e3c3eSJouni Malinen memset(&configReq, 0, sizeof(NanConfigRequest)); 1101cd4e3c3eSJouni Malinen 1102cd4e3c3eSJouni Malinen /* Configure Post disc attr */ 1103cd4e3c3eSJouni Malinen /* Make these defines and use correct enum */ 11041854ec6fSAmarnath Hullur Subramanyam configReq.num_config_discovery_attr = 1; 11051854ec6fSAmarnath Hullur Subramanyam configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */ 11061854ec6fSAmarnath Hullur Subramanyam configReq.discovery_attr_val[0].role = 0; 11071854ec6fSAmarnath Hullur Subramanyam configReq.discovery_attr_val[0].transmit_freq = 1; 11081854ec6fSAmarnath Hullur Subramanyam configReq.discovery_attr_val[0].duration = 0; 11091854ec6fSAmarnath Hullur Subramanyam configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008; 1110cd4e3c3eSJouni Malinen 1111107356c8SRakesh Sunki ret = nan_config_request(0, global_interface_handle, &configReq); 1112107356c8SRakesh Sunki if (ret != WIFI_SUCCESS) { 1113107356c8SRakesh Sunki sigma_dut_print(global_dut, DUT_MSG_INFO, 1114107356c8SRakesh Sunki "NAN config request failed while configuring post discovery attribute"); 1115107356c8SRakesh Sunki } 1116107356c8SRakesh Sunki 1117cd4e3c3eSJouni Malinen return 0; 1118cd4e3c3eSJouni Malinen } 1119cd4e3c3eSJouni Malinen 1120cd4e3c3eSJouni Malinen 1121cd4e3c3eSJouni Malinen int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn, 1122cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 1123cd4e3c3eSJouni Malinen { 1124cd4e3c3eSJouni Malinen const char *publish_type = get_param(cmd, "PublishType"); 1125cd4e3c3eSJouni Malinen const char *service_name = get_param(cmd, "ServiceName"); 1126cd4e3c3eSJouni Malinen const char *disc_range = get_param(cmd, "DiscoveryRange"); 1127cd4e3c3eSJouni Malinen const char *rx_match_filter = get_param(cmd, "rxMatchFilter"); 1128cd4e3c3eSJouni Malinen const char *tx_match_filter = get_param(cmd, "txMatchFilter"); 1129cd4e3c3eSJouni Malinen const char *sdftx_dw = get_param(cmd, "SDFTxDW"); 1130cd4e3c3eSJouni Malinen const char *discrange_ltd = get_param(cmd, "DiscRangeLtd"); 11311a5afb93SRakesh Sunki const char *ndp_enable = get_param(cmd, "DataPathFlag"); 11321a5afb93SRakesh Sunki const char *ndp_type = get_param(cmd, "DataPathType"); 11331a5afb93SRakesh Sunki const char *data_path_security = get_param(cmd, "datapathsecurity"); 11344806040cSRakesh Sunki const char *range_required = get_param(cmd, "rangerequired"); 11358a4845d0SRakesh Sunki #if NAN_CERT_VERSION >= 3 1136ff76d8cbSRakesh Sunki const char *awake_dw_interval = get_param(cmd, "awakeDWint"); 11378a4845d0SRakesh Sunki const char *qos_config = get_param(cmd, "QoS"); 11388a4845d0SRakesh Sunki #endif 1139cd4e3c3eSJouni Malinen NanPublishRequest req; 1140e6f6683bSRakesh Sunki NanConfigRequest config_req; 1141cd4e3c3eSJouni Malinen int filter_len_rx = 0, filter_len_tx = 0; 1142cd4e3c3eSJouni Malinen u8 input_rx[NAN_MAX_MATCH_FILTER_LEN]; 1143cd4e3c3eSJouni Malinen u8 input_tx[NAN_MAX_MATCH_FILTER_LEN]; 1144107356c8SRakesh Sunki wifi_error ret; 1145cd4e3c3eSJouni Malinen 1146cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanPublishRequest)); 1147e6f6683bSRakesh Sunki memset(&config_req, 0, sizeof(NanConfigRequest)); 1148cd4e3c3eSJouni Malinen req.ttl = 0; 11494625de76SRakesh Sunki req.period = 1; 11501854ec6fSAmarnath Hullur Subramanyam req.publish_match_indicator = 1; 1151cd4e3c3eSJouni Malinen req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED; 1152cd4e3c3eSJouni Malinen req.tx_type = NAN_TX_TYPE_BROADCAST; 1153cd4e3c3eSJouni Malinen req.publish_count = 0; 11540a0eea88SRakesh Sunki req.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_ALL; 1155132c6d2bSKantesh Mundaragi 11564236368dSRakesh Sunki if (global_publish_service_name_len && 11574236368dSRakesh Sunki service_name && 11584236368dSRakesh Sunki strcasecmp((char *) global_publish_service_name, 11594236368dSRakesh Sunki service_name) == 0 && 11604236368dSRakesh Sunki global_publish_id) { 11614236368dSRakesh Sunki req.publish_id = global_publish_id; 11624236368dSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 11634236368dSRakesh Sunki "%s: updating publish_id = %d in publish request", 11644236368dSRakesh Sunki __func__, req.publish_id); 11654236368dSRakesh Sunki } 11664236368dSRakesh Sunki 1167132c6d2bSKantesh Mundaragi if (service_name) { 1168cd4e3c3eSJouni Malinen strlcpy((char *) req.service_name, service_name, 11694236368dSRakesh Sunki sizeof(req.service_name)); 11704236368dSRakesh Sunki req.service_name_len = strlen((char *) req.service_name); 11714236368dSRakesh Sunki strlcpy((char *) global_publish_service_name, service_name, 11724236368dSRakesh Sunki sizeof(global_publish_service_name)); 11734236368dSRakesh Sunki global_publish_service_name_len = 11744236368dSRakesh Sunki strlen((char *) global_publish_service_name); 1175132c6d2bSKantesh Mundaragi } 1176cd4e3c3eSJouni Malinen 1177cd4e3c3eSJouni Malinen if (publish_type) { 1178cd4e3c3eSJouni Malinen if (strcasecmp(publish_type, "Solicited") == 0) { 1179cd4e3c3eSJouni Malinen req.publish_type = NAN_PUBLISH_TYPE_SOLICITED; 118062644abdSRakesh Sunki } else if (strcasecmp(publish_type, "Unsolicited") == 0) { 118162644abdSRakesh Sunki req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED; 1182cd4e3c3eSJouni Malinen } else if (strcasecmp(publish_type, "Cancel") == 0) { 1183cd4e3c3eSJouni Malinen NanPublishCancelRequest req; 1184cd4e3c3eSJouni Malinen 1185cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanPublishCancelRequest)); 1186107356c8SRakesh Sunki ret = nan_publish_cancel_request( 1187107356c8SRakesh Sunki 0, global_interface_handle, &req); 1188107356c8SRakesh Sunki if (ret != WIFI_SUCCESS) { 1189107356c8SRakesh Sunki send_resp(dut, conn, SIGMA_ERROR, 1190107356c8SRakesh Sunki "Unable to cancel nan publish request"); 1191107356c8SRakesh Sunki } 1192cd4e3c3eSJouni Malinen return 0; 1193cd4e3c3eSJouni Malinen } 1194cd4e3c3eSJouni Malinen } 1195cd4e3c3eSJouni Malinen 1196cd4e3c3eSJouni Malinen if (disc_range) 1197cd4e3c3eSJouni Malinen req.rssi_threshold_flag = atoi(disc_range); 1198cd4e3c3eSJouni Malinen 1199cd4e3c3eSJouni Malinen if (sdftx_dw) 1200cd4e3c3eSJouni Malinen req.publish_count = atoi(sdftx_dw); 1201cd4e3c3eSJouni Malinen 1202cd4e3c3eSJouni Malinen if (discrange_ltd) 1203cd4e3c3eSJouni Malinen req.rssi_threshold_flag = atoi(discrange_ltd); 1204cd4e3c3eSJouni Malinen 1205cd4e3c3eSJouni Malinen memset(input_rx, 0, sizeof(input_rx)); 1206cd4e3c3eSJouni Malinen memset(input_tx, 0, sizeof(input_tx)); 1207cd4e3c3eSJouni Malinen if (rx_match_filter) { 1208cd4e3c3eSJouni Malinen nan_parse_token(rx_match_filter, input_rx, &filter_len_rx); 1209cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d", 1210cd4e3c3eSJouni Malinen filter_len_rx); 1211cd4e3c3eSJouni Malinen } 1212cd4e3c3eSJouni Malinen if (tx_match_filter) { 1213cd4e3c3eSJouni Malinen nan_parse_token(tx_match_filter, input_tx, &filter_len_tx); 1214cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d", 1215cd4e3c3eSJouni Malinen filter_len_tx); 1216cd4e3c3eSJouni Malinen } 1217cd4e3c3eSJouni Malinen 1218cd4e3c3eSJouni Malinen if (is_fam == 1) { 1219cd4e3c3eSJouni Malinen config_post_disc_attr(); 1220f680e0fcSRakesh Sunki /* 1221f680e0fcSRakesh Sunki * 8-bit bitmap which allows the Host to associate this publish 1222f680e0fcSRakesh Sunki * with a particular Post-NAN Connectivity attribute which has 1223f680e0fcSRakesh Sunki * been sent down in a NanConfigureRequest/NanEnableRequest 1224f680e0fcSRakesh Sunki * message. If the DE fails to find a configured Post-NAN 1225f680e0fcSRakesh Sunki * connectivity attributes referenced by the bitmap, the DE will 1226f680e0fcSRakesh Sunki * return an error code to the Host. If the Publish is 1227f680e0fcSRakesh Sunki * configured to use a Post-NAN Connectivity attribute and the 1228f680e0fcSRakesh Sunki * Host does not refresh the Post-NAN Connectivity attribute the 1229f680e0fcSRakesh Sunki * Publish will be canceled and the Host will be sent a 1230f680e0fcSRakesh Sunki * PublishTerminatedIndication message. 1231f680e0fcSRakesh Sunki */ 1232cd4e3c3eSJouni Malinen req.connmap = 0x10; 1233cd4e3c3eSJouni Malinen } 1234cd4e3c3eSJouni Malinen 1235cd4e3c3eSJouni Malinen if (tx_match_filter) { 1236cd4e3c3eSJouni Malinen req.tx_match_filter_len = filter_len_tx; 1237cd4e3c3eSJouni Malinen memcpy(req.tx_match_filter, input_tx, filter_len_tx); 1238cd4e3c3eSJouni Malinen nan_hex_dump(dut, req.tx_match_filter, filter_len_tx); 1239cd4e3c3eSJouni Malinen } 1240cd4e3c3eSJouni Malinen 1241cd4e3c3eSJouni Malinen if (rx_match_filter) { 1242cd4e3c3eSJouni Malinen req.rx_match_filter_len = filter_len_rx; 1243cd4e3c3eSJouni Malinen memcpy(req.rx_match_filter, input_rx, filter_len_rx); 1244cd4e3c3eSJouni Malinen nan_hex_dump(dut, req.rx_match_filter, filter_len_rx); 1245cd4e3c3eSJouni Malinen } 1246132c6d2bSKantesh Mundaragi 1247132c6d2bSKantesh Mundaragi if (service_name) { 1248cd4e3c3eSJouni Malinen strlcpy((char *) req.service_name, service_name, 1249cd4e3c3eSJouni Malinen strlen(service_name) + 1); 1250cd4e3c3eSJouni Malinen req.service_name_len = strlen(service_name); 1251132c6d2bSKantesh Mundaragi } 1252cd4e3c3eSJouni Malinen 12531a5afb93SRakesh Sunki if (ndp_enable) { 12541a5afb93SRakesh Sunki if (strcasecmp(ndp_enable, "enable") == 0) 12551a5afb93SRakesh Sunki req.sdea_params.config_nan_data_path = 1; 12561a5afb93SRakesh Sunki else 12571a5afb93SRakesh Sunki req.sdea_params.config_nan_data_path = 0; 12581a5afb93SRakesh Sunki 12591a5afb93SRakesh Sunki if (ndp_type) 12601a5afb93SRakesh Sunki req.sdea_params.ndp_type = atoi(ndp_type); 12611a5afb93SRakesh Sunki 12621a5afb93SRakesh Sunki if (data_path_security) { 12631a5afb93SRakesh Sunki if (strcasecmp(data_path_security, "secure") == 0) { 12641a5afb93SRakesh Sunki req.sdea_params.security_cfg = 12651a5afb93SRakesh Sunki NAN_DP_CONFIG_SECURITY; 12661a5afb93SRakesh Sunki } else if (strcasecmp(data_path_security, "open") == 12671a5afb93SRakesh Sunki 0) { 12681a5afb93SRakesh Sunki req.sdea_params.security_cfg = 12691a5afb93SRakesh Sunki NAN_DP_CONFIG_NO_SECURITY; 12701a5afb93SRakesh Sunki } 12711a5afb93SRakesh Sunki } 12721a5afb93SRakesh Sunki 12731a5afb93SRakesh Sunki if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) { 1274395b0157SRakesh Sunki req.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK; 12751a5afb93SRakesh Sunki memcpy(&req.key_info.body.pmk_info.pmk[0], 12761a5afb93SRakesh Sunki &dut->nan_pmk[0], NAN_PMK_INFO_LEN); 12771a5afb93SRakesh Sunki req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN; 12781a5afb93SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d", 12791a5afb93SRakesh Sunki __func__, req.key_info.body.pmk_info.pmk_len); 12801a5afb93SRakesh Sunki } 12811a5afb93SRakesh Sunki } 12824806040cSRakesh Sunki if (range_required && strcasecmp(range_required, "enable") == 0) { 12834806040cSRakesh Sunki req.sdea_params.ranging_state = NAN_RANGING_ENABLE; 12844806040cSRakesh Sunki req.sdea_params.range_report = NAN_ENABLE_RANGE_REPORT; 12854806040cSRakesh Sunki } 12861a5afb93SRakesh Sunki 1287ff76d8cbSRakesh Sunki #if NAN_CERT_VERSION >= 3 1288e6f6683bSRakesh Sunki if (awake_dw_interval) { 1289e6f6683bSRakesh Sunki int input_dw_interval_val = atoi(awake_dw_interval); 1290e6f6683bSRakesh Sunki int awake_dw_int = 0; 1291e6f6683bSRakesh Sunki 1292e6f6683bSRakesh Sunki if (input_dw_interval_val > NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL) { 1293e6f6683bSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 1294e6f6683bSRakesh Sunki "%s: input active dw interval = %d overwritting dw interval to Max allowed dw interval 16", 1295e6f6683bSRakesh Sunki __func__, input_dw_interval_val); 1296e6f6683bSRakesh Sunki input_dw_interval_val = 1297e6f6683bSRakesh Sunki NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL; 1298e6f6683bSRakesh Sunki } 1299e6f6683bSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 1300e6f6683bSRakesh Sunki "%s: input active DW interval = %d", 1301e6f6683bSRakesh Sunki __func__, input_dw_interval_val); 1302e6f6683bSRakesh Sunki /* 1303e6f6683bSRakesh Sunki * Indicates the interval for Sync beacons and SDF's in 2.4 GHz 1304e6f6683bSRakesh Sunki * or 5 GHz band. Valid values of DW Interval are: 1, 2, 3, 4, 1305e6f6683bSRakesh Sunki * and 5; 0 is reserved. The SDF includes in OTA when enabled. 1306e6f6683bSRakesh Sunki * The publish/subscribe period. values don't override the 1307e6f6683bSRakesh Sunki * device level configurations. 1308e6f6683bSRakesh Sunki * input_dw_interval_val is provided by the user are in the 1309e6f6683bSRakesh Sunki * format 2^n-1 = 1/2/4/8/16. Internal implementation expects n 1310e6f6683bSRakesh Sunki * to be passed to indicate the awake_dw_interval. 1311e6f6683bSRakesh Sunki */ 1312e6f6683bSRakesh Sunki if (input_dw_interval_val == 1 || 1313e6f6683bSRakesh Sunki input_dw_interval_val % 2 == 0) { 1314e6f6683bSRakesh Sunki while (input_dw_interval_val > 0) { 1315e6f6683bSRakesh Sunki input_dw_interval_val >>= 1; 1316e6f6683bSRakesh Sunki awake_dw_int++; 1317e6f6683bSRakesh Sunki } 1318e6f6683bSRakesh Sunki } 1319e6f6683bSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 1320e6f6683bSRakesh Sunki "%s:converted active DW interval = %d", 1321e6f6683bSRakesh Sunki __func__, awake_dw_int); 1322e6f6683bSRakesh Sunki config_req.config_dw.config_2dot4g_dw_band = 1; 1323e6f6683bSRakesh Sunki config_req.config_dw.dw_2dot4g_interval_val = awake_dw_int; 1324e6f6683bSRakesh Sunki config_req.config_dw.config_5g_dw_band = 1; 1325e6f6683bSRakesh Sunki config_req.config_dw.dw_5g_interval_val = awake_dw_int; 1326e6f6683bSRakesh Sunki ret = nan_config_request(0, global_interface_handle, 1327e6f6683bSRakesh Sunki &config_req); 1328e6f6683bSRakesh Sunki if (ret != WIFI_SUCCESS) { 1329e6f6683bSRakesh Sunki sigma_dut_print(dut, DUT_MSG_ERROR, 1330e6f6683bSRakesh Sunki "%s:NAN config request failed", 1331e6f6683bSRakesh Sunki __func__); 1332e6f6683bSRakesh Sunki return -2; 1333e6f6683bSRakesh Sunki } 1334e6f6683bSRakesh Sunki } 1335e6f6683bSRakesh Sunki 13368a4845d0SRakesh Sunki if (qos_config) 13378a4845d0SRakesh Sunki req.sdea_params.qos_cfg = (NanQosCfgStatus) atoi(qos_config); 13388a4845d0SRakesh Sunki #endif 13398a4845d0SRakesh Sunki 1340107356c8SRakesh Sunki ret = nan_publish_request(0, global_interface_handle, &req); 1341107356c8SRakesh Sunki if (ret != WIFI_SUCCESS) 1342107356c8SRakesh Sunki send_resp(dut, conn, SIGMA_ERROR, "Unable to publish"); 1343cd4e3c3eSJouni Malinen 13441a5afb93SRakesh Sunki if (ndp_enable) 13451a5afb93SRakesh Sunki dut->ndp_enable = 1; 13461a5afb93SRakesh Sunki 1347cd4e3c3eSJouni Malinen return 0; 1348cd4e3c3eSJouni Malinen } 1349cd4e3c3eSJouni Malinen 1350cd4e3c3eSJouni Malinen 1351cd4e3c3eSJouni Malinen static int nan_further_availability_rx(struct sigma_dut *dut, 1352cd4e3c3eSJouni Malinen struct sigma_conn *conn, 1353cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 1354cd4e3c3eSJouni Malinen { 1355cd4e3c3eSJouni Malinen const char *master_pref = get_param(cmd, "MasterPref"); 1356cd4e3c3eSJouni Malinen const char *rand_fac = get_param(cmd, "RandFactor"); 1357cd4e3c3eSJouni Malinen const char *hop_count = get_param(cmd, "HopCount"); 1358107356c8SRakesh Sunki wifi_error ret; 1359cd4e3c3eSJouni Malinen struct timespec abstime; 1360cd4e3c3eSJouni Malinen 1361cd4e3c3eSJouni Malinen NanEnableRequest req; 1362cd4e3c3eSJouni Malinen 1363cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanEnableRequest)); 1364cd4e3c3eSJouni Malinen req.cluster_low = 0; 1365cd4e3c3eSJouni Malinen req.cluster_high = 0xFFFF; 1366cd4e3c3eSJouni Malinen req.master_pref = 30; 1367cd4e3c3eSJouni Malinen 1368cd4e3c3eSJouni Malinen if (master_pref) 1369cd4e3c3eSJouni Malinen req.master_pref = strtoul(master_pref, NULL, 0); 1370cd4e3c3eSJouni Malinen 1371cd4e3c3eSJouni Malinen if (rand_fac) { 1372cd4e3c3eSJouni Malinen int rand_fac_val = strtoul(rand_fac, NULL, 0); 1373cd4e3c3eSJouni Malinen 1374cd4e3c3eSJouni Malinen req.config_random_factor_force = 1; 1375cd4e3c3eSJouni Malinen req.random_factor_force_val = rand_fac_val; 1376cd4e3c3eSJouni Malinen } 1377cd4e3c3eSJouni Malinen 1378cd4e3c3eSJouni Malinen if (hop_count) { 1379cd4e3c3eSJouni Malinen int hop_count_val = strtoul(hop_count, NULL, 0); 1380cd4e3c3eSJouni Malinen 1381cd4e3c3eSJouni Malinen req.config_hop_count_force = 1; 1382cd4e3c3eSJouni Malinen req.hop_count_force_val = hop_count_val; 1383cd4e3c3eSJouni Malinen } 1384cd4e3c3eSJouni Malinen 1385107356c8SRakesh Sunki ret = nan_enable_request(0, global_interface_handle, &req); 1386107356c8SRakesh Sunki if (ret != WIFI_SUCCESS) { 1387107356c8SRakesh Sunki send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan"); 1388107356c8SRakesh Sunki return 0; 1389107356c8SRakesh Sunki } 1390116be195SKantesh Mundaragi 1391cd4e3c3eSJouni Malinen abstime.tv_sec = 4; 1392cd4e3c3eSJouni Malinen abstime.tv_nsec = 0; 1393cd4e3c3eSJouni Malinen wait(abstime); 1394116be195SKantesh Mundaragi 1395cd4e3c3eSJouni Malinen return 0; 1396cd4e3c3eSJouni Malinen } 1397cd4e3c3eSJouni Malinen 1398cd4e3c3eSJouni Malinen 1399cd4e3c3eSJouni Malinen static int nan_further_availability_tx(struct sigma_dut *dut, 1400cd4e3c3eSJouni Malinen struct sigma_conn *conn, 1401cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 1402cd4e3c3eSJouni Malinen { 1403cd4e3c3eSJouni Malinen const char *master_pref = get_param(cmd, "MasterPref"); 1404cd4e3c3eSJouni Malinen const char *rand_fac = get_param(cmd, "RandFactor"); 1405cd4e3c3eSJouni Malinen const char *hop_count = get_param(cmd, "HopCount"); 1406107356c8SRakesh Sunki wifi_error ret; 1407107356c8SRakesh Sunki 1408cd4e3c3eSJouni Malinen NanEnableRequest req; 1409cd4e3c3eSJouni Malinen NanConfigRequest configReq; 1410cd4e3c3eSJouni Malinen 1411cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanEnableRequest)); 1412cd4e3c3eSJouni Malinen req.cluster_low = 0; 1413cd4e3c3eSJouni Malinen req.cluster_high = 0xFFFF; 1414cd4e3c3eSJouni Malinen req.master_pref = 30; 1415cd4e3c3eSJouni Malinen 1416cd4e3c3eSJouni Malinen if (master_pref) 1417cd4e3c3eSJouni Malinen req.master_pref = strtoul(master_pref, NULL, 0); 1418cd4e3c3eSJouni Malinen 1419cd4e3c3eSJouni Malinen if (rand_fac) { 1420cd4e3c3eSJouni Malinen int rand_fac_val = strtoul(rand_fac, NULL, 0); 1421cd4e3c3eSJouni Malinen 1422cd4e3c3eSJouni Malinen req.config_random_factor_force = 1; 1423cd4e3c3eSJouni Malinen req.random_factor_force_val = rand_fac_val; 1424cd4e3c3eSJouni Malinen } 1425cd4e3c3eSJouni Malinen 1426cd4e3c3eSJouni Malinen if (hop_count) { 1427cd4e3c3eSJouni Malinen int hop_count_val = strtoul(hop_count, NULL, 0); 1428cd4e3c3eSJouni Malinen 1429cd4e3c3eSJouni Malinen req.config_hop_count_force = 1; 1430cd4e3c3eSJouni Malinen req.hop_count_force_val = hop_count_val; 1431cd4e3c3eSJouni Malinen } 1432cd4e3c3eSJouni Malinen 1433107356c8SRakesh Sunki ret = nan_enable_request(0, global_interface_handle, &req); 1434107356c8SRakesh Sunki if (ret != WIFI_SUCCESS) { 1435107356c8SRakesh Sunki send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan"); 1436107356c8SRakesh Sunki return 0; 1437107356c8SRakesh Sunki } 1438cd4e3c3eSJouni Malinen 1439cd4e3c3eSJouni Malinen /* Start the config of fam */ 1440cd4e3c3eSJouni Malinen 1441cd4e3c3eSJouni Malinen memset(&configReq, 0, sizeof(NanConfigRequest)); 1442cd4e3c3eSJouni Malinen 1443cd4e3c3eSJouni Malinen configReq.config_fam = 1; 1444cd4e3c3eSJouni Malinen configReq.fam_val.numchans = 1; 14451854ec6fSAmarnath Hullur Subramanyam configReq.fam_val.famchan[0].entry_control = 0; 14461854ec6fSAmarnath Hullur Subramanyam configReq.fam_val.famchan[0].class_val = 81; 14471854ec6fSAmarnath Hullur Subramanyam configReq.fam_val.famchan[0].channel = 6; 14481854ec6fSAmarnath Hullur Subramanyam configReq.fam_val.famchan[0].mapid = 0; 14491854ec6fSAmarnath Hullur Subramanyam configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe; 14501854ec6fSAmarnath Hullur Subramanyam 1451107356c8SRakesh Sunki ret = nan_config_request(0, global_interface_handle, &configReq); 1452107356c8SRakesh Sunki if (ret != WIFI_SUCCESS) 1453107356c8SRakesh Sunki send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed"); 1454cd4e3c3eSJouni Malinen 1455cd4e3c3eSJouni Malinen return 0; 1456cd4e3c3eSJouni Malinen } 1457cd4e3c3eSJouni Malinen 1458cd4e3c3eSJouni Malinen 1459cd4e3c3eSJouni Malinen int sigma_nan_transmit_followup(struct sigma_dut *dut, 1460cd4e3c3eSJouni Malinen struct sigma_conn *conn, 1461cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 1462cd4e3c3eSJouni Malinen { 1463cd4e3c3eSJouni Malinen const char *mac = get_param(cmd, "mac"); 1464cd4e3c3eSJouni Malinen const char *requestor_id = get_param(cmd, "RemoteInstanceId"); 1465cd4e3c3eSJouni Malinen const char *local_id = get_param(cmd, "LocalInstanceId"); 1466cd4e3c3eSJouni Malinen const char *service_name = get_param(cmd, "servicename"); 1467107356c8SRakesh Sunki wifi_error ret; 1468cd4e3c3eSJouni Malinen NanTransmitFollowupRequest req; 1469cd4e3c3eSJouni Malinen 1470cd4e3c3eSJouni Malinen memset(&req, 0, sizeof(NanTransmitFollowupRequest)); 14711854ec6fSAmarnath Hullur Subramanyam req.requestor_instance_id = global_match_handle; 1472cd4e3c3eSJouni Malinen req.addr[0] = 0xFF; 1473cd4e3c3eSJouni Malinen req.addr[1] = 0xFF; 1474cd4e3c3eSJouni Malinen req.addr[2] = 0xFF; 1475cd4e3c3eSJouni Malinen req.addr[3] = 0xFF; 1476cd4e3c3eSJouni Malinen req.addr[4] = 0xFF; 1477cd4e3c3eSJouni Malinen req.addr[5] = 0xFF; 1478cd4e3c3eSJouni Malinen req.priority = NAN_TX_PRIORITY_NORMAL; 1479cd4e3c3eSJouni Malinen req.dw_or_faw = 0; 1480132c6d2bSKantesh Mundaragi 1481132c6d2bSKantesh Mundaragi if (service_name) 1482cd4e3c3eSJouni Malinen req.service_specific_info_len = strlen(service_name); 1483cd4e3c3eSJouni Malinen 1484cd4e3c3eSJouni Malinen if (requestor_id) { 1485cd4e3c3eSJouni Malinen /* int requestor_id_val = atoi(requestor_id); */ 1486fa417337SRakesh Sunki if (global_match_handle != 0) { 14871854ec6fSAmarnath Hullur Subramanyam req.requestor_instance_id = global_match_handle; 1488fa417337SRakesh Sunki } else { 1489fa417337SRakesh Sunki u32 requestor_id_val = atoi(requestor_id); 1490fa417337SRakesh Sunki requestor_id_val = 1491fa417337SRakesh Sunki (requestor_id_val << 24) | 0x0000FFFF; 1492fa417337SRakesh Sunki req.requestor_instance_id = requestor_id_val; 1493fa417337SRakesh Sunki } 1494cd4e3c3eSJouni Malinen } 1495cd4e3c3eSJouni Malinen if (local_id) { 1496cd4e3c3eSJouni Malinen /* int local_id_val = atoi(local_id); */ 1497fa417337SRakesh Sunki if (global_header_handle != 0) 14981854ec6fSAmarnath Hullur Subramanyam req.publish_subscribe_id = global_header_handle; 1499fa417337SRakesh Sunki else 1500fa417337SRakesh Sunki req.publish_subscribe_id = atoi(local_id); 1501cd4e3c3eSJouni Malinen } 1502cd4e3c3eSJouni Malinen 1503cd4e3c3eSJouni Malinen if (mac == NULL) { 1504cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address"); 1505cd4e3c3eSJouni Malinen return -1; 1506cd4e3c3eSJouni Malinen } 1507cd4e3c3eSJouni Malinen nan_parse_mac_address(dut, mac, req.addr); 1508cd4e3c3eSJouni Malinen 1509107356c8SRakesh Sunki ret = nan_transmit_followup_request(0, global_interface_handle, &req); 1510107356c8SRakesh Sunki if (ret != WIFI_SUCCESS) { 1511107356c8SRakesh Sunki send_resp(dut, conn, SIGMA_ERROR, 1512107356c8SRakesh Sunki "Unable to complete nan transmit followup"); 1513107356c8SRakesh Sunki } 15141854ec6fSAmarnath Hullur Subramanyam 1515cd4e3c3eSJouni Malinen return 0; 1516cd4e3c3eSJouni Malinen } 1517cd4e3c3eSJouni Malinen 1518107356c8SRakesh Sunki 1519cd4e3c3eSJouni Malinen /* NotifyResponse invoked to notify the status of the Request */ 15201854ec6fSAmarnath Hullur Subramanyam void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data) 1521cd4e3c3eSJouni Malinen { 1522cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 1523fdbd60b6SRakesh Sunki "%s: status %d response_type %d", 1524fdbd60b6SRakesh Sunki __func__, rsp_data->status, rsp_data->response_type); 1525d51e8980SRakesh Sunki if (rsp_data->response_type == NAN_RESPONSE_STATS && 1526d51e8980SRakesh Sunki rsp_data->body.stats_response.stats_type == 1527d51e8980SRakesh Sunki NAN_STATS_ID_DE_TIMING_SYNC) { 1528d51e8980SRakesh Sunki NanSyncStats *pSyncStats; 1529d51e8980SRakesh Sunki 1530d51e8980SRakesh Sunki sigma_dut_print(global_dut, DUT_MSG_INFO, 1531d51e8980SRakesh Sunki "%s: stats_type %d", __func__, 15321854ec6fSAmarnath Hullur Subramanyam rsp_data->body.stats_response.stats_type); 1533d51e8980SRakesh Sunki pSyncStats = &rsp_data->body.stats_response.data.sync_stats; 1534d51e8980SRakesh Sunki memcpy(&global_nan_sync_stats, pSyncStats, 1535d51e8980SRakesh Sunki sizeof(NanSyncStats)); 1536d51e8980SRakesh Sunki pthread_cond_signal(&gCondition); 15374d5912dfSRakesh Sunki } else if (rsp_data->response_type == NAN_RESPONSE_PUBLISH) { 15384d5912dfSRakesh Sunki sigma_dut_print(global_dut, DUT_MSG_INFO, 15394d5912dfSRakesh Sunki "%s: publish_id %d\n", 15404d5912dfSRakesh Sunki __func__, 15414d5912dfSRakesh Sunki rsp_data->body.publish_response.publish_id); 15424d5912dfSRakesh Sunki global_publish_id = rsp_data->body.publish_response.publish_id; 15434d5912dfSRakesh Sunki } else if (rsp_data->response_type == NAN_RESPONSE_SUBSCRIBE) { 15444d5912dfSRakesh Sunki sigma_dut_print(global_dut, DUT_MSG_INFO, 15454d5912dfSRakesh Sunki "%s: subscribe_id %d\n", 15464d5912dfSRakesh Sunki __func__, 15474d5912dfSRakesh Sunki rsp_data->body.subscribe_response.subscribe_id); 15484d5912dfSRakesh Sunki global_subscribe_id = 15494d5912dfSRakesh Sunki rsp_data->body.subscribe_response.subscribe_id; 1550cd4e3c3eSJouni Malinen } 1551cd4e3c3eSJouni Malinen } 1552cd4e3c3eSJouni Malinen 1553cd4e3c3eSJouni Malinen 1554cd4e3c3eSJouni Malinen /* Events Callback */ 1555cd4e3c3eSJouni Malinen void nan_event_publish_replied(NanPublishRepliedInd *event) 1556cd4e3c3eSJouni Malinen { 1557cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 1558cd4e3c3eSJouni Malinen "%s: handle %d " MAC_ADDR_STR " rssi:%d", 15591854ec6fSAmarnath Hullur Subramanyam __func__, event->requestor_instance_id, 1560cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(event->addr), event->rssi_value); 1561cd4e3c3eSJouni Malinen event_anyresponse = 1; 1562cd4e3c3eSJouni Malinen snprintf(global_event_resp_buf, sizeof(global_event_resp_buf), 1563fa417337SRakesh Sunki "EventName,Replied,RemoteInstanceID,%d,LocalInstanceID,%d,mac," MAC_ADDR_STR" ", 15641854ec6fSAmarnath Hullur Subramanyam (event->requestor_instance_id >> 24), 1565fa417337SRakesh Sunki (event->requestor_instance_id & 0xFFFF), 15661854ec6fSAmarnath Hullur Subramanyam MAC_ADDR_ARRAY(event->addr)); 1567cd4e3c3eSJouni Malinen } 1568cd4e3c3eSJouni Malinen 1569cd4e3c3eSJouni Malinen 1570cd4e3c3eSJouni Malinen /* Events Callback */ 1571cd4e3c3eSJouni Malinen void nan_event_publish_terminated(NanPublishTerminatedInd *event) 1572cd4e3c3eSJouni Malinen { 15731854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d", 15741854ec6fSAmarnath Hullur Subramanyam __func__, event->publish_id, event->reason); 1575cd4e3c3eSJouni Malinen } 1576cd4e3c3eSJouni Malinen 1577cd4e3c3eSJouni Malinen 1578cd4e3c3eSJouni Malinen /* Events Callback */ 1579cd4e3c3eSJouni Malinen void nan_event_match(NanMatchInd *event) 1580cd4e3c3eSJouni Malinen { 1581cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 15821854ec6fSAmarnath Hullur Subramanyam "%s: Pub/Sub Id %d remote_requestor_id %08x " 15831854ec6fSAmarnath Hullur Subramanyam MAC_ADDR_STR 1584cd4e3c3eSJouni Malinen " rssi:%d", 1585cd4e3c3eSJouni Malinen __func__, 15861854ec6fSAmarnath Hullur Subramanyam event->publish_subscribe_id, 15871854ec6fSAmarnath Hullur Subramanyam event->requestor_instance_id, 1588cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(event->addr), 1589cd4e3c3eSJouni Malinen event->rssi_value); 1590cd4e3c3eSJouni Malinen event_anyresponse = 1; 15911854ec6fSAmarnath Hullur Subramanyam global_header_handle = event->publish_subscribe_id; 15921854ec6fSAmarnath Hullur Subramanyam global_match_handle = event->requestor_instance_id; 159314cfcd25SRakesh Sunki memcpy(global_peer_mac_addr, event->addr, sizeof(global_peer_mac_addr)); 15941854ec6fSAmarnath Hullur Subramanyam 1595cd4e3c3eSJouni Malinen /* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */ 1596cd4e3c3eSJouni Malinen /* global_pub_sub_handle = event->header.handle; */ 1597cd4e3c3eSJouni Malinen /* Print the SSI */ 1598cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:"); 15991854ec6fSAmarnath Hullur Subramanyam nan_hex_dump(global_dut, event->service_specific_info, 1600cd4e3c3eSJouni Malinen event->service_specific_info_len); 1601cd4e3c3eSJouni Malinen snprintf(global_event_resp_buf, sizeof(global_event_resp_buf), 1602cd4e3c3eSJouni Malinen "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac," 16031854ec6fSAmarnath Hullur Subramanyam MAC_ADDR_STR " ", (event->requestor_instance_id >> 24), 16041854ec6fSAmarnath Hullur Subramanyam event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr)); 1605cd4e3c3eSJouni Malinen 1606cd4e3c3eSJouni Malinen /* Print the match filter */ 1607cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:"); 16081854ec6fSAmarnath Hullur Subramanyam nan_hex_dump(global_dut, event->sdf_match_filter, 16091854ec6fSAmarnath Hullur Subramanyam event->sdf_match_filter_len); 1610cd4e3c3eSJouni Malinen 1611cd4e3c3eSJouni Malinen /* Print the conn_capability */ 1612cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 1613cd4e3c3eSJouni Malinen "Printing PostConnectivity Capability"); 1614cd4e3c3eSJouni Malinen if (event->is_conn_capability_valid) { 1615cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s", 1616cd4e3c3eSJouni Malinen event->conn_capability.is_wfd_supported ? 1617cd4e3c3eSJouni Malinen "yes" : "no"); 1618cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s", 1619cd4e3c3eSJouni Malinen (event->conn_capability.is_wfds_supported ? 1620cd4e3c3eSJouni Malinen "yes" : "no")); 1621cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s", 1622cd4e3c3eSJouni Malinen (event->conn_capability.is_tdls_supported ? 1623cd4e3c3eSJouni Malinen "yes" : "no")); 1624cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s", 1625cd4e3c3eSJouni Malinen (event->conn_capability.is_ibss_supported ? 1626cd4e3c3eSJouni Malinen "yes" : "no")); 1627cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s", 1628cd4e3c3eSJouni Malinen (event->conn_capability.is_mesh_supported ? 1629cd4e3c3eSJouni Malinen "yes" : "no")); 1630cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d", 1631cd4e3c3eSJouni Malinen event->conn_capability.wlan_infra_field); 1632cd4e3c3eSJouni Malinen } else { 1633cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 1634cd4e3c3eSJouni Malinen "PostConnectivity Capability not present"); 1635cd4e3c3eSJouni Malinen } 1636cd4e3c3eSJouni Malinen 1637cd4e3c3eSJouni Malinen /* Print the discovery_attr */ 1638cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 1639cd4e3c3eSJouni Malinen "Printing PostDiscovery Attribute"); 16401854ec6fSAmarnath Hullur Subramanyam if (event->num_rx_discovery_attr) { 16411854ec6fSAmarnath Hullur Subramanyam int idx; 16421854ec6fSAmarnath Hullur Subramanyam 16431854ec6fSAmarnath Hullur Subramanyam for (idx = 0; idx < event->num_rx_discovery_attr; idx++) { 16441854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 16451854ec6fSAmarnath Hullur Subramanyam "PostDiscovery Attribute - %d", idx); 1646cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 1647cd4e3c3eSJouni Malinen "Conn Type:%d Device Role:%d" 1648cd4e3c3eSJouni Malinen MAC_ADDR_STR, 16491854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].type, 16501854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].role, 16511854ec6fSAmarnath Hullur Subramanyam MAC_ADDR_ARRAY(event->discovery_attr[idx].addr)); 16521854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 16531854ec6fSAmarnath Hullur Subramanyam "Duration:%d MapId:%d " 16541854ec6fSAmarnath Hullur Subramanyam "avail_interval_bitmap:%04x", 16551854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].duration, 16561854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].mapid, 16571854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].avail_interval_bitmap); 1658cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 1659cd4e3c3eSJouni Malinen "Printing Mesh Id:"); 16601854ec6fSAmarnath Hullur Subramanyam nan_hex_dump(global_dut, 16611854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].mesh_id, 16621854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].mesh_id_len); 16631854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 16641854ec6fSAmarnath Hullur Subramanyam "Printing Infrastructure Ssid:"); 16651854ec6fSAmarnath Hullur Subramanyam nan_hex_dump(global_dut, 16661854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].infrastructure_ssid_val, 16671854ec6fSAmarnath Hullur Subramanyam event->discovery_attr[idx].infrastructure_ssid_len); 16681854ec6fSAmarnath Hullur Subramanyam } 1669cd4e3c3eSJouni Malinen } else { 1670cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 1671cd4e3c3eSJouni Malinen "PostDiscovery attribute not present"); 1672cd4e3c3eSJouni Malinen } 1673cd4e3c3eSJouni Malinen 1674cd4e3c3eSJouni Malinen /* Print the fam */ 16751854ec6fSAmarnath Hullur Subramanyam if (event->num_chans) { 16761854ec6fSAmarnath Hullur Subramanyam nan_print_further_availability_chan(global_dut, 16771854ec6fSAmarnath Hullur Subramanyam event->num_chans, 16781854ec6fSAmarnath Hullur Subramanyam &event->famchan[0]); 16791854ec6fSAmarnath Hullur Subramanyam } else { 16801854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 16811854ec6fSAmarnath Hullur Subramanyam "Further Availability Map not present"); 16821854ec6fSAmarnath Hullur Subramanyam } 16831854ec6fSAmarnath Hullur Subramanyam if (event->cluster_attribute_len) { 16841854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 16851854ec6fSAmarnath Hullur Subramanyam "Printing Cluster Attribute:"); 16861854ec6fSAmarnath Hullur Subramanyam nan_hex_dump(global_dut, event->cluster_attribute, 16871854ec6fSAmarnath Hullur Subramanyam event->cluster_attribute_len); 16881854ec6fSAmarnath Hullur Subramanyam } else { 16891854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 16901854ec6fSAmarnath Hullur Subramanyam "Cluster Attribute not present"); 1691cd4e3c3eSJouni Malinen } 1692cd4e3c3eSJouni Malinen } 1693cd4e3c3eSJouni Malinen 1694cd4e3c3eSJouni Malinen 1695cd4e3c3eSJouni Malinen /* Events Callback */ 16961854ec6fSAmarnath Hullur Subramanyam void nan_event_match_expired(NanMatchExpiredInd *event) 1697cd4e3c3eSJouni Malinen { 1698cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 16991854ec6fSAmarnath Hullur Subramanyam "%s: publish_subscribe_id %d match_handle %08x", 17001854ec6fSAmarnath Hullur Subramanyam __func__, event->publish_subscribe_id, 17011854ec6fSAmarnath Hullur Subramanyam event->requestor_instance_id); 1702cd4e3c3eSJouni Malinen } 1703cd4e3c3eSJouni Malinen 1704cd4e3c3eSJouni Malinen 1705cd4e3c3eSJouni Malinen /* Events Callback */ 1706cd4e3c3eSJouni Malinen void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event) 1707cd4e3c3eSJouni Malinen { 17081854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 17091854ec6fSAmarnath Hullur Subramanyam "%s: Subscribe Id %d reason %d", 17101854ec6fSAmarnath Hullur Subramanyam __func__, event->subscribe_id, event->reason); 1711cd4e3c3eSJouni Malinen } 1712cd4e3c3eSJouni Malinen 1713cd4e3c3eSJouni Malinen 1714cd4e3c3eSJouni Malinen /* Events Callback */ 1715cd4e3c3eSJouni Malinen void nan_event_followup(NanFollowupInd *event) 1716cd4e3c3eSJouni Malinen { 1717cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 17181854ec6fSAmarnath Hullur Subramanyam "%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d " 17191854ec6fSAmarnath Hullur Subramanyam MAC_ADDR_STR, __func__, event->publish_subscribe_id, 17201854ec6fSAmarnath Hullur Subramanyam event->requestor_instance_id, event->dw_or_faw, 1721cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(event->addr)); 1722cd4e3c3eSJouni Malinen 1723fa417337SRakesh Sunki global_match_handle = event->requestor_instance_id; 1724fa417337SRakesh Sunki global_header_handle = event->publish_subscribe_id; 17251854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__); 17261854ec6fSAmarnath Hullur Subramanyam nan_hex_dump(global_dut, event->service_specific_info, 1727cd4e3c3eSJouni Malinen event->service_specific_info_len); 1728cd4e3c3eSJouni Malinen event_anyresponse = 1; 1729cd4e3c3eSJouni Malinen snprintf(global_event_resp_buf, sizeof(global_event_resp_buf), 1730cd4e3c3eSJouni Malinen "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac," 17311854ec6fSAmarnath Hullur Subramanyam MAC_ADDR_STR " ", event->requestor_instance_id >> 24, 17321854ec6fSAmarnath Hullur Subramanyam event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr)); 1733cd4e3c3eSJouni Malinen } 1734cd4e3c3eSJouni Malinen 1735cd4e3c3eSJouni Malinen 1736cd4e3c3eSJouni Malinen /* Events Callback */ 1737cd4e3c3eSJouni Malinen void nan_event_disceng_event(NanDiscEngEventInd *event) 1738cd4e3c3eSJouni Malinen { 17391854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d", 17401854ec6fSAmarnath Hullur Subramanyam __func__, event->event_type); 1741cd4e3c3eSJouni Malinen 17421854ec6fSAmarnath Hullur Subramanyam if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) { 1743cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster " 1744cd4e3c3eSJouni Malinen MAC_ADDR_STR, 1745cd4e3c3eSJouni Malinen __func__, 1746cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(event->data.cluster.addr)); 1747116be195SKantesh Mundaragi /* To ensure sta_get_events to get the events 1748116be195SKantesh Mundaragi * only after joining the NAN cluster. */ 1749116be195SKantesh Mundaragi pthread_cond_signal(&gCondition); 1750cd4e3c3eSJouni Malinen } 17511854ec6fSAmarnath Hullur Subramanyam if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) { 1752cd4e3c3eSJouni Malinen sigma_dut_print(global_dut, DUT_MSG_INFO, 1753cd4e3c3eSJouni Malinen "%s: Started cluster " MAC_ADDR_STR, 1754cd4e3c3eSJouni Malinen __func__, 1755cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(event->data.cluster.addr)); 1756cd4e3c3eSJouni Malinen } 17571854ec6fSAmarnath Hullur Subramanyam if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) { 17581854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, 17591854ec6fSAmarnath Hullur Subramanyam "%s: Discovery Mac Address " 1760cd4e3c3eSJouni Malinen MAC_ADDR_STR, 1761cd4e3c3eSJouni Malinen __func__, 1762cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(event->data.mac_addr.addr)); 1763cd4e3c3eSJouni Malinen memcpy(global_nan_mac_addr, event->data.mac_addr.addr, 1764cd4e3c3eSJouni Malinen sizeof(global_nan_mac_addr)); 1765cd4e3c3eSJouni Malinen } 1766cd4e3c3eSJouni Malinen } 1767cd4e3c3eSJouni Malinen 1768cd4e3c3eSJouni Malinen 1769cd4e3c3eSJouni Malinen /* Events Callback */ 1770cd4e3c3eSJouni Malinen void nan_event_disabled(NanDisabledInd *event) 1771cd4e3c3eSJouni Malinen { 17721854ec6fSAmarnath Hullur Subramanyam sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d", 17731854ec6fSAmarnath Hullur Subramanyam __func__, event->reason); 1774cd4e3c3eSJouni Malinen /* pthread_cond_signal(&gCondition); */ 1775cd4e3c3eSJouni Malinen } 1776cd4e3c3eSJouni Malinen 1777cd4e3c3eSJouni Malinen 17784c086678SRakesh Sunki /* Events callback */ 17794c086678SRakesh Sunki static void ndp_event_data_indication(NanDataPathRequestInd *event) 17804c086678SRakesh Sunki { 17814c086678SRakesh Sunki sigma_dut_print(global_dut, DUT_MSG_INFO, 17824c086678SRakesh Sunki "%s: Service Instance Id: %d Peer Discovery MAC ADDR " 17834c086678SRakesh Sunki MAC_ADDR_STR 17844c086678SRakesh Sunki " NDP Instance Id: %d App Info len %d App Info %s", 17854c086678SRakesh Sunki __func__, 17864c086678SRakesh Sunki event->service_instance_id, 17874c086678SRakesh Sunki MAC_ADDR_ARRAY(event->peer_disc_mac_addr), 17884c086678SRakesh Sunki event->ndp_instance_id, 17894c086678SRakesh Sunki event->app_info.ndp_app_info_len, 17904c086678SRakesh Sunki event->app_info.ndp_app_info); 17914c086678SRakesh Sunki 17924c086678SRakesh Sunki global_ndp_instance_id = event->ndp_instance_id; 17934c086678SRakesh Sunki } 17944c086678SRakesh Sunki 17954c086678SRakesh Sunki 17964c086678SRakesh Sunki /* Events callback */ 17974c086678SRakesh Sunki static void ndp_event_data_confirm(NanDataPathConfirmInd *event) 17984c086678SRakesh Sunki { 17998f8e74b5SRakesh Sunki char cmd[200]; 18008f8e74b5SRakesh Sunki char ipv6_buf[100]; 18018f8e74b5SRakesh Sunki 18024c086678SRakesh Sunki sigma_dut_print(global_dut, DUT_MSG_INFO, 18034c086678SRakesh Sunki "Received NDP Confirm Indication"); 18044c086678SRakesh Sunki 18058f8e74b5SRakesh Sunki memset(cmd, 0, sizeof(cmd)); 18068f8e74b5SRakesh Sunki memset(ipv6_buf, 0, sizeof(ipv6_buf)); 18078f8e74b5SRakesh Sunki 18084c086678SRakesh Sunki global_ndp_instance_id = event->ndp_instance_id; 18098f8e74b5SRakesh Sunki 18108f8e74b5SRakesh Sunki if (event->rsp_code == NAN_DP_REQUEST_ACCEPT) { 18114c086678SRakesh Sunki if (system("ifconfig nan0 up") != 0) { 18124c086678SRakesh Sunki sigma_dut_print(global_dut, DUT_MSG_ERROR, 18134c086678SRakesh Sunki "Failed to set nan interface up"); 18144c086678SRakesh Sunki return; 18154c086678SRakesh Sunki } 18168f8e74b5SRakesh Sunki if (system("ip -6 route add fe80::/64 dev nan0 table local") != 18178f8e74b5SRakesh Sunki 0) { 18184c086678SRakesh Sunki sigma_dut_print(global_dut, DUT_MSG_ERROR, 18194c086678SRakesh Sunki "Failed to run:ip -6 route replace fe80::/64 dev nan0 table local"); 18208f8e74b5SRakesh Sunki } 18218f8e74b5SRakesh Sunki convert_mac_addr_to_ipv6_lladdr(event->peer_ndi_mac_addr, 18228f8e74b5SRakesh Sunki ipv6_buf, sizeof(ipv6_buf)); 18238f8e74b5SRakesh Sunki snprintf(cmd, sizeof(cmd), 18248f8e74b5SRakesh Sunki "ip -6 neighbor replace %s lladdr %02x:%02x:%02x:%02x:%02x:%02x nud permanent dev nan0", 18258f8e74b5SRakesh Sunki ipv6_buf, event->peer_ndi_mac_addr[0], 18268f8e74b5SRakesh Sunki event->peer_ndi_mac_addr[1], 18278f8e74b5SRakesh Sunki event->peer_ndi_mac_addr[2], 18288f8e74b5SRakesh Sunki event->peer_ndi_mac_addr[3], 18298f8e74b5SRakesh Sunki event->peer_ndi_mac_addr[4], 18308f8e74b5SRakesh Sunki event->peer_ndi_mac_addr[5]); 18318f8e74b5SRakesh Sunki sigma_dut_print(global_dut, DUT_MSG_INFO, 18328f8e74b5SRakesh Sunki "neighbor replace cmd = %s", cmd); 18338f8e74b5SRakesh Sunki if (system(cmd) != 0) { 18348f8e74b5SRakesh Sunki sigma_dut_print(global_dut, DUT_MSG_ERROR, 18358f8e74b5SRakesh Sunki "Failed to run: ip -6 neighbor replace"); 18364c086678SRakesh Sunki return; 18374c086678SRakesh Sunki } 18384c086678SRakesh Sunki } 18398f8e74b5SRakesh Sunki } 18404c086678SRakesh Sunki 18414c086678SRakesh Sunki 1842cd4e3c3eSJouni Malinen void * my_thread_function(void *ptr) 1843cd4e3c3eSJouni Malinen { 18441854ec6fSAmarnath Hullur Subramanyam wifi_event_loop(global_wifi_handle); 1845cd4e3c3eSJouni Malinen pthread_exit(0); 1846cd4e3c3eSJouni Malinen return (void *) NULL; 1847cd4e3c3eSJouni Malinen } 1848cd4e3c3eSJouni Malinen 1849cd4e3c3eSJouni Malinen 1850cd4e3c3eSJouni Malinen static NanCallbackHandler callbackHandler = { 1851cd4e3c3eSJouni Malinen .NotifyResponse = nan_notify_response, 1852cd4e3c3eSJouni Malinen .EventPublishReplied = nan_event_publish_replied, 1853cd4e3c3eSJouni Malinen .EventPublishTerminated = nan_event_publish_terminated, 1854cd4e3c3eSJouni Malinen .EventMatch = nan_event_match, 18551854ec6fSAmarnath Hullur Subramanyam .EventMatchExpired = nan_event_match_expired, 1856cd4e3c3eSJouni Malinen .EventSubscribeTerminated = nan_event_subscribe_terminated, 1857cd4e3c3eSJouni Malinen .EventFollowup = nan_event_followup, 1858cd4e3c3eSJouni Malinen .EventDiscEngEvent = nan_event_disceng_event, 1859cd4e3c3eSJouni Malinen .EventDisabled = nan_event_disabled, 18604c086678SRakesh Sunki .EventDataRequest = ndp_event_data_indication, 18614c086678SRakesh Sunki .EventDataConfirm = ndp_event_data_confirm, 1862cd4e3c3eSJouni Malinen }; 1863cd4e3c3eSJouni Malinen 1864132c6d2bSKantesh Mundaragi 1865cd4e3c3eSJouni Malinen void nan_init(struct sigma_dut *dut) 1866cd4e3c3eSJouni Malinen { 1867cd4e3c3eSJouni Malinen pthread_t thread1; /* thread variables */ 18681854ec6fSAmarnath Hullur Subramanyam wifi_error err = wifi_initialize(&global_wifi_handle); 1869cd4e3c3eSJouni Malinen 1870cd4e3c3eSJouni Malinen if (err) { 1871cd4e3c3eSJouni Malinen printf("wifi hal initialize failed\n"); 1872cd4e3c3eSJouni Malinen return; 1873cd4e3c3eSJouni Malinen } 1874cd4e3c3eSJouni Malinen 18751854ec6fSAmarnath Hullur Subramanyam global_interface_handle = wifi_get_iface_handle(global_wifi_handle, 18761854ec6fSAmarnath Hullur Subramanyam (char *) "wlan0"); 1877cd4e3c3eSJouni Malinen /* create threads 1 */ 1878cd4e3c3eSJouni Malinen pthread_create(&thread1, NULL, &my_thread_function, NULL); 1879cd4e3c3eSJouni Malinen 1880cd4e3c3eSJouni Malinen pthread_mutex_init(&gMutex, NULL); 1881cd4e3c3eSJouni Malinen pthread_cond_init(&gCondition, NULL); 1882132c6d2bSKantesh Mundaragi if (global_interface_handle) 18831854ec6fSAmarnath Hullur Subramanyam nan_register_handler(global_interface_handle, callbackHandler); 1884cd4e3c3eSJouni Malinen } 1885cd4e3c3eSJouni Malinen 1886cd4e3c3eSJouni Malinen 1887cd4e3c3eSJouni Malinen void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn, 1888cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 1889cd4e3c3eSJouni Malinen { 1890cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default"); 1891cd4e3c3eSJouni Malinen 1892*2052daa2SAnurag Das #ifdef ANDROID 1893*2052daa2SAnurag Das if (dut->nanservicediscoveryinprogress) { 1894*2052daa2SAnurag Das char *argv[5]; 1895*2052daa2SAnurag Das pid_t pid; 1896*2052daa2SAnurag Das 1897*2052daa2SAnurag Das argv[0] = "am"; 1898*2052daa2SAnurag Das argv[1] = "broadcast"; 1899*2052daa2SAnurag Das argv[2] = "-a"; 1900*2052daa2SAnurag Das argv[3] = "org.codeaurora.nanservicediscovery.close"; 1901*2052daa2SAnurag Das argv[4] = NULL; 1902*2052daa2SAnurag Das 1903*2052daa2SAnurag Das pid = fork(); 1904*2052daa2SAnurag Das if (pid == -1) { 1905*2052daa2SAnurag Das sigma_dut_print(dut, DUT_MSG_ERROR, "fork: %s", 1906*2052daa2SAnurag Das strerror(errno)); 1907*2052daa2SAnurag Das } else if (pid == 0) { 1908*2052daa2SAnurag Das execv("/system/bin/am", argv); 1909*2052daa2SAnurag Das sigma_dut_print(dut, DUT_MSG_ERROR, "execv: %s", 1910*2052daa2SAnurag Das strerror(errno)); 1911*2052daa2SAnurag Das exit(0); 1912*2052daa2SAnurag Das } 1913*2052daa2SAnurag Das dut->nanservicediscoveryinprogress = 0; 1914*2052daa2SAnurag Das } 1915*2052daa2SAnurag Das #endif /* ANDROID */ 1916*2052daa2SAnurag Das 1917cd4e3c3eSJouni Malinen if (nan_state == 0) { 1918cd4e3c3eSJouni Malinen nan_init(dut); 1919cd4e3c3eSJouni Malinen nan_state = 1; 1920cd4e3c3eSJouni Malinen } 1921cd4e3c3eSJouni Malinen is_fam = 0; 1922cd4e3c3eSJouni Malinen event_anyresponse = 0; 1923cd4e3c3eSJouni Malinen global_dut = dut; 19247d37f411SRakesh Sunki memset(&dut->nan_pmk[0], 0, NAN_PMK_INFO_LEN); 19257d37f411SRakesh Sunki dut->nan_pmk_len = 0; 1926d7344c02SRakesh Sunki dut->sta_channel = 0; 1927cd4e3c3eSJouni Malinen memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf)); 1928d51e8980SRakesh Sunki memset(&global_nan_sync_stats, 0, sizeof(global_nan_sync_stats)); 19294236368dSRakesh Sunki memset(global_publish_service_name, 0, 19304236368dSRakesh Sunki sizeof(global_publish_service_name)); 19314236368dSRakesh Sunki global_publish_service_name_len = 0; 19324236368dSRakesh Sunki global_publish_id = 0; 19330262cb5fSRakesh Sunki global_subscribe_id = 0; 19347a40a20aSRakesh Sunki 19358a630b8eSRakesh Sunki sigma_nan_data_end(dut, cmd); 19367a40a20aSRakesh Sunki nan_data_interface_delete(0, global_interface_handle, (char *) "nan0"); 1937cd4e3c3eSJouni Malinen sigma_nan_disable(dut, conn, cmd); 1938fa417337SRakesh Sunki global_header_handle = 0; 1939fa417337SRakesh Sunki global_match_handle = 0; 1940cd4e3c3eSJouni Malinen } 1941cd4e3c3eSJouni Malinen 1942cd4e3c3eSJouni Malinen 1943cd4e3c3eSJouni Malinen int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn, 1944cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 1945cd4e3c3eSJouni Malinen { 1946cd4e3c3eSJouni Malinen const char *program = get_param(cmd, "Prog"); 1947cd4e3c3eSJouni Malinen const char *nan_op = get_param(cmd, "NANOp"); 1948cd4e3c3eSJouni Malinen const char *method_type = get_param(cmd, "MethodType"); 1949d7344c02SRakesh Sunki const char *band = get_param(cmd, "band"); 1950*2052daa2SAnurag Das const char *disc_mac_addr = get_param(cmd, "DiscoveryMacAddress"); 1951cd4e3c3eSJouni Malinen char resp_buf[100]; 19527a40a20aSRakesh Sunki wifi_error ret; 1953cd4e3c3eSJouni Malinen 1954cd4e3c3eSJouni Malinen if (program == NULL) 1955cd4e3c3eSJouni Malinen return -1; 1956cd4e3c3eSJouni Malinen 1957cd4e3c3eSJouni Malinen if (strcasecmp(program, "NAN") != 0) { 1958cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 1959cd4e3c3eSJouni Malinen "ErrorCode,Unsupported program"); 1960cd4e3c3eSJouni Malinen return 0; 1961cd4e3c3eSJouni Malinen } 1962cd4e3c3eSJouni Malinen 1963cd4e3c3eSJouni Malinen if (nan_op) { 1964b5604ff8SRakesh Sunki #if NAN_CERT_VERSION >= 3 1965b5604ff8SRakesh Sunki int size = 0; 1966b5604ff8SRakesh Sunki u32 device_type_val = 0; 1967b5604ff8SRakesh Sunki NanDebugParams cfg_debug; 1968b5604ff8SRakesh Sunki 1969b5604ff8SRakesh Sunki memset(&cfg_debug, 0, sizeof(NanDebugParams)); 1970b5604ff8SRakesh Sunki cfg_debug.cmd = NAN_TEST_MODE_CMD_DEVICE_TYPE; 1971b5604ff8SRakesh Sunki if (dut->device_type == STA_testbed) 1972b5604ff8SRakesh Sunki device_type_val = NAN_DEVICE_TYPE_TEST_BED; 1973b5604ff8SRakesh Sunki else if (dut->device_type == STA_dut) 1974b5604ff8SRakesh Sunki device_type_val = NAN_DEVICE_TYPE_DUT; 1975b5604ff8SRakesh Sunki 1976b5604ff8SRakesh Sunki memcpy(cfg_debug.debug_cmd_data, &device_type_val, sizeof(u32)); 1977b5604ff8SRakesh Sunki size = sizeof(u32) + sizeof(u32); 1978b5604ff8SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 1979b5604ff8SRakesh Sunki "%s: Device Type: cmd type = %d and command data = %u", 1980b5604ff8SRakesh Sunki __func__, cfg_debug.cmd, device_type_val); 1981b5604ff8SRakesh Sunki nan_debug_command_config(0, global_interface_handle, 1982b5604ff8SRakesh Sunki cfg_debug, size); 1983b5604ff8SRakesh Sunki #endif 1984cd4e3c3eSJouni Malinen /* 1985cd4e3c3eSJouni Malinen * NANOp has been specified. 1986cd4e3c3eSJouni Malinen * We will build a nan_enable or nan_disable command. 1987cd4e3c3eSJouni Malinen */ 1988cd4e3c3eSJouni Malinen if (strcasecmp(nan_op, "On") == 0) { 1989cd4e3c3eSJouni Malinen if (sigma_nan_enable(dut, conn, cmd) == 0) { 19907a40a20aSRakesh Sunki ret = nan_data_interface_create( 19917a40a20aSRakesh Sunki 0, global_interface_handle, 19927a40a20aSRakesh Sunki (char *) "nan0"); 19937a40a20aSRakesh Sunki if (ret != WIFI_SUCCESS) { 19947a40a20aSRakesh Sunki sigma_dut_print( 19957a40a20aSRakesh Sunki global_dut, DUT_MSG_ERROR, 19967a40a20aSRakesh Sunki "Unable to create NAN data interface"); 19977a40a20aSRakesh Sunki } 1998cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "mac," 1999cd4e3c3eSJouni Malinen MAC_ADDR_STR, 2000cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(global_nan_mac_addr)); 2001cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, resp_buf); 2002cd4e3c3eSJouni Malinen } else { 2003cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 2004cd4e3c3eSJouni Malinen "NAN_ENABLE_FAILED"); 2005cd4e3c3eSJouni Malinen return -1; 2006cd4e3c3eSJouni Malinen } 2007d7344c02SRakesh Sunki 2008d7344c02SRakesh Sunki if (band && strcasecmp(band, "24g") == 0) { 2009d7344c02SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 2010d7344c02SRakesh Sunki "%s: Setting band to 2G Only", 2011d7344c02SRakesh Sunki __func__); 2012d7344c02SRakesh Sunki sigma_ndp_configure_band( 2013d7344c02SRakesh Sunki dut, conn, cmd, 2014d7344c02SRakesh Sunki NAN_DATA_PATH_SUPPORTED_BAND_2G); 2015d7344c02SRakesh Sunki } else if (band && dut->sta_channel > 12) { 2016d7344c02SRakesh Sunki sigma_ndp_configure_band( 2017d7344c02SRakesh Sunki dut, conn, cmd, 2018d7344c02SRakesh Sunki NAN_DATA_PATH_SUPPORT_DUAL_BAND); 2019d7344c02SRakesh Sunki } 2020cd4e3c3eSJouni Malinen } else if (strcasecmp(nan_op, "Off") == 0) { 2021bcf9ef3eSRakesh Sunki nan_data_interface_delete(0, 2022bcf9ef3eSRakesh Sunki global_interface_handle, (char *) "nan0"); 2023cd4e3c3eSJouni Malinen sigma_nan_disable(dut, conn, cmd); 20244236368dSRakesh Sunki memset(global_publish_service_name, 0, 20254236368dSRakesh Sunki sizeof(global_publish_service_name)); 20264236368dSRakesh Sunki global_publish_service_name_len = 0; 20274236368dSRakesh Sunki global_publish_id = 0; 20280262cb5fSRakesh Sunki global_subscribe_id = 0; 2029fa417337SRakesh Sunki global_header_handle = 0; 2030fa417337SRakesh Sunki global_match_handle = 0; 2031cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 2032cd4e3c3eSJouni Malinen } 2033cd4e3c3eSJouni Malinen } 2034cd4e3c3eSJouni Malinen if (nan_state && nan_op == NULL) { 2035cd4e3c3eSJouni Malinen if (method_type) { 2036cd4e3c3eSJouni Malinen if (strcasecmp(method_type, "Publish") == 0) { 2037cd4e3c3eSJouni Malinen sigma_nan_publish_request(dut, conn, cmd); 2038cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 2039cd4e3c3eSJouni Malinen } 2040cd4e3c3eSJouni Malinen if (strcasecmp(method_type, "Subscribe") == 0) { 2041cd4e3c3eSJouni Malinen sigma_nan_subscribe_request(dut, conn, cmd); 2042cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 2043cd4e3c3eSJouni Malinen } 2044cd4e3c3eSJouni Malinen if (strcasecmp(method_type, "Followup") == 0) { 2045cd4e3c3eSJouni Malinen sigma_nan_transmit_followup(dut, conn, cmd); 2046cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 2047cd4e3c3eSJouni Malinen } 204814cfcd25SRakesh Sunki if (strcasecmp(method_type, "DataRequest") == 0) { 204914cfcd25SRakesh Sunki sigma_nan_data_request(dut, conn, cmd); 205014cfcd25SRakesh Sunki send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 205114cfcd25SRakesh Sunki } 2052a5cc284dSRakesh Sunki if (strcasecmp(method_type, "DataResponse") == 0) { 2053a5cc284dSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 2054a5cc284dSRakesh Sunki "%s: method_type is DataResponse", 2055a5cc284dSRakesh Sunki __func__); 2056a5cc284dSRakesh Sunki sigma_nan_data_response(dut, conn, cmd); 2057a5cc284dSRakesh Sunki send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 2058a5cc284dSRakesh Sunki } 20598a630b8eSRakesh Sunki if (strcasecmp(method_type, "DataEnd") == 0) { 20608a630b8eSRakesh Sunki sigma_nan_data_end(dut, cmd); 20618a630b8eSRakesh Sunki send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 20628a630b8eSRakesh Sunki } 2063d5e9b4d1SRakesh Sunki if (strcasecmp(method_type, "rangerequest") == 0) { 2064d5e9b4d1SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 2065d5e9b4d1SRakesh Sunki "%s: method_type is rangerequest", 2066d5e9b4d1SRakesh Sunki __func__); 2067d5e9b4d1SRakesh Sunki sigma_nan_range_request(dut, cmd); 2068d5e9b4d1SRakesh Sunki send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 2069d5e9b4d1SRakesh Sunki } 2070d5e9b4d1SRakesh Sunki if (strcasecmp(method_type, "cancelrange") == 0) { 2071d5e9b4d1SRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 2072d5e9b4d1SRakesh Sunki "%s: method_type is cancelrange", 2073d5e9b4d1SRakesh Sunki __func__); 2074d5e9b4d1SRakesh Sunki sigma_nan_cancel_range(dut, cmd); 2075d5e9b4d1SRakesh Sunki send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 2076d5e9b4d1SRakesh Sunki } 2077b2b6516cSRakesh Sunki if (strcasecmp(method_type, "SchedUpdate") == 0) { 2078b2b6516cSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 2079b2b6516cSRakesh Sunki "%s: method_type is SchedUpdate", 2080b2b6516cSRakesh Sunki __func__); 2081b2b6516cSRakesh Sunki sigma_nan_schedule_update(dut, cmd); 2082b2b6516cSRakesh Sunki send_resp(dut, conn, SIGMA_COMPLETE, "NULL"); 2083b2b6516cSRakesh Sunki } 2084*2052daa2SAnurag Das } else if (disc_mac_addr && 2085*2052daa2SAnurag Das strcasecmp(disc_mac_addr, "GET") == 0) { 2086*2052daa2SAnurag Das snprintf(resp_buf, sizeof(resp_buf), "mac," 2087*2052daa2SAnurag Das MAC_ADDR_STR, 2088*2052daa2SAnurag Das MAC_ADDR_ARRAY(global_nan_mac_addr)); 2089*2052daa2SAnurag Das send_resp(dut, conn, SIGMA_COMPLETE, resp_buf); 2090cd4e3c3eSJouni Malinen } else { 2091cd4e3c3eSJouni Malinen sigma_nan_config_enable(dut, conn, cmd); 2092cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "mac," 2093cd4e3c3eSJouni Malinen MAC_ADDR_STR, 2094cd4e3c3eSJouni Malinen MAC_ADDR_ARRAY(global_nan_mac_addr)); 2095cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, resp_buf); 2096cd4e3c3eSJouni Malinen } 2097cd4e3c3eSJouni Malinen } 2098cd4e3c3eSJouni Malinen 2099cd4e3c3eSJouni Malinen return 0; 2100cd4e3c3eSJouni Malinen } 2101cd4e3c3eSJouni Malinen 2102cd4e3c3eSJouni Malinen 2103cd4e3c3eSJouni Malinen int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn, 2104cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 2105cd4e3c3eSJouni Malinen { 2106cd4e3c3eSJouni Malinen 2107cd4e3c3eSJouni Malinen const char *program = get_param(cmd, "Program"); 2108cd4e3c3eSJouni Malinen const char *parameter = get_param(cmd, "Parameter"); 2109cd4e3c3eSJouni Malinen char resp_buf[100]; 2110d51e8980SRakesh Sunki NanStatsRequest req; 2111d51e8980SRakesh Sunki struct timespec abstime; 2112d51e8980SRakesh Sunki u64 master_rank; 2113d51e8980SRakesh Sunki u8 master_pref; 2114d51e8980SRakesh Sunki u8 random_factor; 2115d51e8980SRakesh Sunki u8 hop_count; 2116d51e8980SRakesh Sunki u32 beacon_transmit_time; 2117d51e8980SRakesh Sunki u32 ndp_channel_freq; 2118d51e8980SRakesh Sunki u32 ndp_channel_freq2; 2119a3b5966cSRakesh Sunki #if NAN_CERT_VERSION >= 3 2120a3b5966cSRakesh Sunki u32 sched_update_channel_freq; 2121a3b5966cSRakesh Sunki #endif 2122cd4e3c3eSJouni Malinen 2123cd4e3c3eSJouni Malinen if (program == NULL) { 2124cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name"); 2125cd4e3c3eSJouni Malinen return -1; 2126cd4e3c3eSJouni Malinen } 2127cd4e3c3eSJouni Malinen if (strcasecmp(program, "NAN") != 0) { 2128cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 2129cd4e3c3eSJouni Malinen "ErrorCode,Unsupported program"); 2130cd4e3c3eSJouni Malinen return 0; 2131cd4e3c3eSJouni Malinen } 2132cd4e3c3eSJouni Malinen 2133cd4e3c3eSJouni Malinen if (parameter == NULL) { 2134cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter"); 2135cd4e3c3eSJouni Malinen return -1; 2136cd4e3c3eSJouni Malinen } 2137cd4e3c3eSJouni Malinen 2138d51e8980SRakesh Sunki memset(&req, 0, sizeof(NanStatsRequest)); 2139a3b5966cSRakesh Sunki memset(resp_buf, 0, sizeof(resp_buf)); 2140d51e8980SRakesh Sunki req.stats_type = (NanStatsType) NAN_STATS_ID_DE_TIMING_SYNC; 2141d51e8980SRakesh Sunki nan_stats_request(0, global_interface_handle, &req); 2142d51e8980SRakesh Sunki /* 2143d51e8980SRakesh Sunki * To ensure sta_get_events to get the events 2144d51e8980SRakesh Sunki * only after joining the NAN cluster 2145d51e8980SRakesh Sunki */ 2146d51e8980SRakesh Sunki abstime.tv_sec = 4; 2147d51e8980SRakesh Sunki abstime.tv_nsec = 0; 2148d51e8980SRakesh Sunki wait(abstime); 2149d51e8980SRakesh Sunki 2150d51e8980SRakesh Sunki master_rank = global_nan_sync_stats.myRank; 2151d51e8980SRakesh Sunki master_pref = (global_nan_sync_stats.myRank & 0xFF00000000000000) >> 56; 2152d51e8980SRakesh Sunki random_factor = (global_nan_sync_stats.myRank & 0x00FF000000000000) >> 2153d51e8980SRakesh Sunki 48; 2154d51e8980SRakesh Sunki hop_count = global_nan_sync_stats.currAmHopCount; 2155d51e8980SRakesh Sunki beacon_transmit_time = global_nan_sync_stats.currAmBTT; 2156d51e8980SRakesh Sunki ndp_channel_freq = global_nan_sync_stats.ndpChannelFreq; 2157d51e8980SRakesh Sunki ndp_channel_freq2 = global_nan_sync_stats.ndpChannelFreq2; 2158a3b5966cSRakesh Sunki #if NAN_CERT_VERSION >= 3 2159a3b5966cSRakesh Sunki sched_update_channel_freq = 2160a3b5966cSRakesh Sunki global_nan_sync_stats.schedUpdateChannelFreq; 2161d51e8980SRakesh Sunki 2162cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, 2163a3b5966cSRakesh Sunki "%s: NanStatsRequest Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d ndp_channel_freq:%d ndp_channel_freq2:%d sched_update_channel_freq:%d", 2164a3b5966cSRakesh Sunki __func__, master_pref, random_factor, 2165a3b5966cSRakesh Sunki hop_count, beacon_transmit_time, 2166a3b5966cSRakesh Sunki ndp_channel_freq, ndp_channel_freq2, 2167a3b5966cSRakesh Sunki sched_update_channel_freq); 2168a3b5966cSRakesh Sunki #else /* #if NAN_CERT_VERSION >= 3 */ 2169a3b5966cSRakesh Sunki sigma_dut_print(dut, DUT_MSG_INFO, 2170d51e8980SRakesh Sunki "%s: NanStatsRequest Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d ndp_channel_freq:%d ndp_channel_freq2:%d", 2171d51e8980SRakesh Sunki __func__, master_pref, random_factor, 2172d51e8980SRakesh Sunki hop_count, beacon_transmit_time, 2173d51e8980SRakesh Sunki ndp_channel_freq, ndp_channel_freq2); 2174a3b5966cSRakesh Sunki #endif /* #if NAN_CERT_VERSION >= 3 */ 2175cd4e3c3eSJouni Malinen 2176cd4e3c3eSJouni Malinen if (strcasecmp(parameter, "MasterPref") == 0) { 2177cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x", 2178d51e8980SRakesh Sunki master_pref); 2179cd4e3c3eSJouni Malinen } else if (strcasecmp(parameter, "MasterRank") == 0) { 2180cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx", 2181d51e8980SRakesh Sunki master_rank); 2182cd4e3c3eSJouni Malinen } else if (strcasecmp(parameter, "RandFactor") == 0) { 2183cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x", 2184d51e8980SRakesh Sunki random_factor); 2185cd4e3c3eSJouni Malinen } else if (strcasecmp(parameter, "HopCount") == 0) { 2186cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x", 2187d51e8980SRakesh Sunki hop_count); 2188cd4e3c3eSJouni Malinen } else if (strcasecmp(parameter, "BeaconTransTime") == 0) { 2189cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x", 2190d51e8980SRakesh Sunki beacon_transmit_time); 2191cd4e3c3eSJouni Malinen } else if (strcasecmp(parameter, "NANStatus") == 0) { 2192cd4e3c3eSJouni Malinen if (nan_state == 1) 2193cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "On"); 2194cd4e3c3eSJouni Malinen else 2195cd4e3c3eSJouni Malinen snprintf(resp_buf, sizeof(resp_buf), "Off"); 2196d51e8980SRakesh Sunki } else if (strcasecmp(parameter, "NDPChannel") == 0) { 2197d51e8980SRakesh Sunki if (ndp_channel_freq != 0 && ndp_channel_freq2 != 0) { 2198d51e8980SRakesh Sunki snprintf(resp_buf, sizeof(resp_buf), 2199d51e8980SRakesh Sunki "ndpchannel,%d,ndpchannel,%d", 2200d51e8980SRakesh Sunki freq_to_channel(ndp_channel_freq), 2201d51e8980SRakesh Sunki freq_to_channel(ndp_channel_freq2)); 2202d51e8980SRakesh Sunki } else if (ndp_channel_freq != 0) { 2203d51e8980SRakesh Sunki snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d", 2204d51e8980SRakesh Sunki freq_to_channel(ndp_channel_freq)); 2205d51e8980SRakesh Sunki } else if (ndp_channel_freq2 != 0) { 2206d51e8980SRakesh Sunki snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d", 2207d51e8980SRakesh Sunki freq_to_channel(ndp_channel_freq2)); 2208d51e8980SRakesh Sunki } else { 2209d51e8980SRakesh Sunki sigma_dut_print(dut, DUT_MSG_ERROR, 2210d51e8980SRakesh Sunki "%s: No Negotiated NDP Channels", __func__); 2211d51e8980SRakesh Sunki } 2212a3b5966cSRakesh Sunki #if NAN_CERT_VERSION >= 3 2213a3b5966cSRakesh Sunki } else if (strcasecmp(parameter, "SchedUpdateChannel") == 0) { 2214a3b5966cSRakesh Sunki snprintf(resp_buf, sizeof(resp_buf), "schedupdatechannel,%d", 2215a3b5966cSRakesh Sunki freq_to_channel(sched_update_channel_freq)); 2216a3b5966cSRakesh Sunki #endif 2217cd4e3c3eSJouni Malinen } else { 2218cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter"); 2219cd4e3c3eSJouni Malinen return 0; 2220cd4e3c3eSJouni Malinen } 2221cd4e3c3eSJouni Malinen 2222cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, resp_buf); 2223cd4e3c3eSJouni Malinen return 0; 2224cd4e3c3eSJouni Malinen } 2225cd4e3c3eSJouni Malinen 2226cd4e3c3eSJouni Malinen 2227cd4e3c3eSJouni Malinen int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn, 2228cd4e3c3eSJouni Malinen struct sigma_cmd *cmd) 2229cd4e3c3eSJouni Malinen { 2230cd4e3c3eSJouni Malinen const char *action = get_param(cmd, "Action"); 2231cd4e3c3eSJouni Malinen 2232132c6d2bSKantesh Mundaragi if (!action) 2233132c6d2bSKantesh Mundaragi return 0; 2234132c6d2bSKantesh Mundaragi 2235cd4e3c3eSJouni Malinen /* Check action for start, stop and get events. */ 2236cd4e3c3eSJouni Malinen if (strcasecmp(action, "Start") == 0) { 2237cd4e3c3eSJouni Malinen memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf)); 2238cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, NULL); 2239cd4e3c3eSJouni Malinen } else if (strcasecmp(action, "Stop") == 0) { 2240cd4e3c3eSJouni Malinen event_anyresponse = 0; 2241cd4e3c3eSJouni Malinen memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf)); 2242cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, NULL); 2243cd4e3c3eSJouni Malinen } else if (strcasecmp(action, "Get") == 0) { 2244cd4e3c3eSJouni Malinen if (event_anyresponse == 1) { 2245cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 2246cd4e3c3eSJouni Malinen global_event_resp_buf); 2247cd4e3c3eSJouni Malinen } else { 2248cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE"); 2249cd4e3c3eSJouni Malinen } 2250cd4e3c3eSJouni Malinen } 2251cd4e3c3eSJouni Malinen return 0; 2252cd4e3c3eSJouni Malinen } 22534b75f96cSRakesh Sunki 22544b75f96cSRakesh Sunki #else /* #if NAN_CERT_VERSION */ 22554b75f96cSRakesh Sunki 22564b75f96cSRakesh Sunki int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut, 22574b75f96cSRakesh Sunki struct sigma_conn *conn, 22584b75f96cSRakesh Sunki struct sigma_cmd *cmd) 22594b75f96cSRakesh Sunki { 22604b75f96cSRakesh Sunki return 1; 22614b75f96cSRakesh Sunki } 22624b75f96cSRakesh Sunki 22634b75f96cSRakesh Sunki 22644b75f96cSRakesh Sunki int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn, 22654b75f96cSRakesh Sunki struct sigma_cmd *cmd) 22664b75f96cSRakesh Sunki { 22674b75f96cSRakesh Sunki return 0; 22684b75f96cSRakesh Sunki 22694b75f96cSRakesh Sunki } 22704b75f96cSRakesh Sunki 22714b75f96cSRakesh Sunki 22724b75f96cSRakesh Sunki void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn, 22734b75f96cSRakesh Sunki struct sigma_cmd *cmd) 22744b75f96cSRakesh Sunki { 22754b75f96cSRakesh Sunki return; 22764b75f96cSRakesh Sunki } 22774b75f96cSRakesh Sunki 22784b75f96cSRakesh Sunki 22794b75f96cSRakesh Sunki int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn, 22804b75f96cSRakesh Sunki struct sigma_cmd *cmd) 22814b75f96cSRakesh Sunki { 22824b75f96cSRakesh Sunki return 0; 22834b75f96cSRakesh Sunki } 22844b75f96cSRakesh Sunki 22854b75f96cSRakesh Sunki 22864b75f96cSRakesh Sunki int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn, 22874b75f96cSRakesh Sunki struct sigma_cmd *cmd) 22884b75f96cSRakesh Sunki { 22894b75f96cSRakesh Sunki return 0; 22904b75f96cSRakesh Sunki } 22914b75f96cSRakesh Sunki 22924b75f96cSRakesh Sunki #endif /* #if NAN_CERT_VERSION */ 2293