blob: 0fd348014519364e29b6628312271fe2f0de1762 [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (NAN functionality)
Rakesh Sunki4b75f962017-03-30 14:47:55 -07003 * Copyright (c) 2014-2017, Qualcomm Atheros, Inc.
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004 * All Rights Reserved.
5 * Licensed under the Clear BSD license. See README for more details.
6 */
7
8#include "sigma_dut.h"
9#include <sys/stat.h>
10#include "wpa_ctrl.h"
11#include "wpa_helpers.h"
12#include "wifi_hal.h"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -070013#include "nan_cert.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014
Rakesh Sunki4b75f962017-03-30 14:47:55 -070015#if NAN_CERT_VERSION >= 2
16
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017pthread_cond_t gCondition;
18pthread_mutex_t gMutex;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -070019wifi_handle global_wifi_handle;
20wifi_interface_handle global_interface_handle;
Rakesh Sunkid51e8982017-03-30 14:47:55 -070021static NanSyncStats global_nan_sync_stats;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020022static int nan_state = 0;
23static int event_anyresponse = 0;
24static int is_fam = 0;
25
Rakesh Sunki4c086672017-03-30 14:47:55 -070026static uint16_t global_ndp_instance_id = 0;
Rakesh Sunki4d5912d2017-03-30 14:47:55 -070027static uint16_t global_publish_id = 0;
28static uint16_t global_subscribe_id = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020029uint16_t global_header_handle = 0;
30uint32_t global_match_handle = 0;
31
32#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
33#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
34#ifndef ETH_ALEN
35#define ETH_ALEN 6
36#endif
37
38struct sigma_dut *global_dut = NULL;
39static char global_nan_mac_addr[ETH_ALEN];
Rakesh Sunki14cfcd22017-03-30 14:47:55 -070040static char global_peer_mac_addr[ETH_ALEN];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020041static char global_event_resp_buf[1024];
42
43static int nan_further_availability_tx(struct sigma_dut *dut,
44 struct sigma_conn *conn,
45 struct sigma_cmd *cmd);
46static int nan_further_availability_rx(struct sigma_dut *dut,
47 struct sigma_conn *conn,
48 struct sigma_cmd *cmd);
49
50
51void nan_hex_dump(struct sigma_dut *dut, uint8_t *data, size_t len)
52{
53 char buf[512];
54 uint16_t index;
55 uint8_t *ptr;
56 int pos;
57
58 memset(buf, 0, sizeof(buf));
59 ptr = data;
60 pos = 0;
61 for (index = 0; index < len; index++) {
62 pos += sprintf(&(buf[pos]), "%02x ", *ptr++);
63 if (pos > 508)
64 break;
65 }
66 sigma_dut_print(dut, DUT_MSG_INFO, "HEXDUMP len=[%d]", (int) len);
67 sigma_dut_print(dut, DUT_MSG_INFO, "buf:%s", buf);
68}
69
70
71int nan_parse_hex(unsigned char c)
72{
73 if (c >= '0' && c <= '9')
74 return c - '0';
75 if (c >= 'a' && c <= 'f')
76 return c - 'a' + 10;
77 if (c >= 'A' && c <= 'F')
78 return c - 'A' + 10;
79 return 0;
80}
81
82
83int nan_parse_token(const char *tokenIn, u8 *tokenOut, int *filterLen)
84{
85 int total_len = 0, len = 0;
86 char *saveptr = NULL;
87
88 tokenIn = strtok_r((char *) tokenIn, ":", &saveptr);
89 while (tokenIn != NULL) {
90 len = strlen(tokenIn);
91 if (len == 1 && *tokenIn == '*')
92 len = 0;
93 tokenOut[total_len++] = (u8) len;
94 if (len != 0)
95 memcpy((u8 *) tokenOut + total_len, tokenIn, len);
96 total_len += len;
97 tokenIn = strtok_r(NULL, ":", &saveptr);
98 }
99 *filterLen = total_len;
100 return 0;
101}
102
103
104int nan_parse_mac_address(struct sigma_dut *dut, const char *arg, u8 *addr)
105{
106 if (strlen(arg) != 17) {
107 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid mac address %s",
108 arg);
109 sigma_dut_print(dut, DUT_MSG_ERROR,
110 "expected format xx:xx:xx:xx:xx:xx");
111 return -1;
112 }
113
114 addr[0] = nan_parse_hex(arg[0]) << 4 | nan_parse_hex(arg[1]);
115 addr[1] = nan_parse_hex(arg[3]) << 4 | nan_parse_hex(arg[4]);
116 addr[2] = nan_parse_hex(arg[6]) << 4 | nan_parse_hex(arg[7]);
117 addr[3] = nan_parse_hex(arg[9]) << 4 | nan_parse_hex(arg[10]);
118 addr[4] = nan_parse_hex(arg[12]) << 4 | nan_parse_hex(arg[13]);
119 addr[5] = nan_parse_hex(arg[15]) << 4 | nan_parse_hex(arg[16]);
120
121 return 0;
122}
123
124
125int nan_parse_mac_address_list(struct sigma_dut *dut, const char *input,
126 u8 *output, u16 max_addr_allowed)
127{
128 /*
129 * Reads a list of mac address separated by space. Each MAC address
130 * should have the format of aa:bb:cc:dd:ee:ff.
131 */
132 char *saveptr;
133 char *token;
134 int i = 0;
135
136 for (i = 0; i < max_addr_allowed; i++) {
137 token = strtok_r((i == 0) ? (char *) input : NULL,
138 " ", &saveptr);
139 if (token) {
140 nan_parse_mac_address(dut, token, output);
141 output += NAN_MAC_ADDR_LEN;
142 } else
143 break;
144 }
145
146 sigma_dut_print(dut, DUT_MSG_INFO, "Num MacAddress:%d", i);
147
148 return i;
149}
150
151
152int nan_parse_hex_string(struct sigma_dut *dut, const char *input,
153 u8 *output, int *outputlen)
154{
155 int i = 0;
156 int j = 0;
157
158 for (i = 0; i < (int) strlen(input) && j < *outputlen; i += 2) {
159 output[j] = nan_parse_hex(input[i]);
160 if (i + 1 < (int) strlen(input)) {
161 output[j] = ((output[j] << 4) |
162 nan_parse_hex(input[i + 1]));
163 }
164 j++;
165 }
166 *outputlen = j;
167 sigma_dut_print(dut, DUT_MSG_INFO, "Input:%s inputlen:%d outputlen:%d",
168 input, (int) strlen(input), (int) *outputlen);
169 return 0;
170}
171
172
173int wait(struct timespec abstime)
174{
175 struct timeval now;
176
177 gettimeofday(&now, NULL);
178
179 abstime.tv_sec += now.tv_sec;
180 if (((abstime.tv_nsec + now.tv_usec * 1000) > 1000 * 1000 * 1000) ||
181 (abstime.tv_nsec + now.tv_usec * 1000 < 0)) {
182 abstime.tv_sec += 1;
183 abstime.tv_nsec += now.tv_usec * 1000;
184 abstime.tv_nsec -= 1000 * 1000 * 1000;
185 } else {
186 abstime.tv_nsec += now.tv_usec * 1000;
187 }
188
189 return pthread_cond_timedwait(&gCondition, &gMutex, &abstime);
190}
191
192
193int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
194 struct sigma_conn *conn,
195 struct sigma_cmd *cmd)
196{
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700197 const char *oper_chan = get_param(cmd, "oper_chn");
Rakesh Sunki7d37f412017-03-30 14:47:55 -0700198 const char *pmk = get_param(cmd, "PMK");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200199
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700200 if (oper_chan) {
201 sigma_dut_print(dut, DUT_MSG_INFO, "Operating Channel: %s",
202 oper_chan);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700203 dut->sta_channel = atoi(oper_chan);
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700204 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200205
Rakesh Sunki7d37f412017-03-30 14:47:55 -0700206 if (pmk) {
207 int pmk_len;
208
209 sigma_dut_print(dut, DUT_MSG_INFO, "%s given string pmk: %s",
210 __func__, pmk);
211 memset(dut->nan_pmk, 0, NAN_PMK_INFO_LEN);
212 dut->nan_pmk_len = 0;
213 pmk_len = NAN_PMK_INFO_LEN;
214 nan_parse_hex_string(dut, &pmk[2], &dut->nan_pmk[0], &pmk_len);
215 dut->nan_pmk_len = pmk_len;
216 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
217 __func__, dut->nan_pmk_len);
218 sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex pmk", __func__);
219 nan_hex_dump(dut, &dut->nan_pmk[0], dut->nan_pmk_len);
220 }
221
Rakesh Sunki14bff1d2017-03-30 14:47:55 -0700222 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200223 return 0;
224}
225
226
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700227void nan_print_further_availability_chan(struct sigma_dut *dut,
228 u8 num_chans,
229 NanFurtherAvailabilityChannel *fachan)
230{
231 int idx;
232
233 sigma_dut_print(dut, DUT_MSG_INFO,
234 "********Printing FurtherAvailabilityChan Info******");
235 sigma_dut_print(dut, DUT_MSG_INFO, "Numchans:%d", num_chans);
236 for (idx = 0; idx < num_chans; idx++) {
237 sigma_dut_print(dut, DUT_MSG_INFO,
238 "[%d]: NanAvailDuration:%d class_val:%02x channel:%d",
239 idx, fachan->entry_control,
240 fachan->class_val, fachan->channel);
241 sigma_dut_print(dut, DUT_MSG_INFO,
242 "[%d]: mapid:%d Availability bitmap:%08x",
243 idx, fachan->mapid,
244 fachan->avail_interval_bitmap);
245 }
246 sigma_dut_print(dut, DUT_MSG_INFO,
247 "*********************Done**********************");
248}
249
250
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200251int sigma_nan_enable(struct sigma_dut *dut, struct sigma_conn *conn,
252 struct sigma_cmd *cmd)
253{
254 const char *master_pref = get_param(cmd, "MasterPref");
255 const char *rand_fac = get_param(cmd, "RandFactor");
256 const char *hop_count = get_param(cmd, "HopCount");
257 const char *high_tsf = get_param(cmd, "HighTSF");
258 const char *sdftx_band = get_param(cmd, "SDFTxBand");
259 const char *oper_chan = get_param(cmd, "oper_chn");
260 const char *further_avail_ind = get_param(cmd, "FurtherAvailInd");
261 const char *band = get_param(cmd, "Band");
262 const char *only_5g = get_param(cmd, "5GOnly");
Rakesh Sunki38dd72e2017-03-30 14:47:55 -0700263 const char *nan_availability = get_param(cmd, "NANAvailability");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200264 struct timespec abstime;
265 NanEnableRequest req;
266
267 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200268 req.cluster_low = 0;
269 req.cluster_high = 0xFFFF;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700270 req.master_pref = 100;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200271
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700272 /* This is a debug hack to beacon in channel 11 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200273 if (oper_chan) {
274 req.config_2dot4g_support = 1;
275 req.support_2dot4g_val = 111;
276 }
277
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200278 if (master_pref) {
279 int master_pref_val = strtoul(master_pref, NULL, 0);
280
281 req.master_pref = master_pref_val;
282 }
283
284 if (rand_fac) {
285 int rand_fac_val = strtoul(rand_fac, NULL, 0);
286
287 req.config_random_factor_force = 1;
288 req.random_factor_force_val = rand_fac_val;
289 }
290
291 if (hop_count) {
292 int hop_count_val = strtoul(hop_count, NULL, 0);
293
294 req.config_hop_count_force = 1;
295 req.hop_count_force_val = hop_count_val;
296 }
297
298 if (sdftx_band) {
299 if (strcasecmp(sdftx_band, "5G") == 0) {
300 req.config_2dot4g_support = 1;
301 req.support_2dot4g_val = 0;
302 }
303 }
304
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700305 sigma_dut_print(dut, DUT_MSG_INFO,
306 "%s: Setting dual band 2.4 GHz and 5 GHz by default",
307 __func__);
308 /* Enable 2.4 GHz support */
309 req.config_2dot4g_support = 1;
310 req.support_2dot4g_val = 1;
311 req.config_2dot4g_beacons = 1;
312 req.beacon_2dot4g_val = 1;
313 req.config_2dot4g_sdf = 1;
314 req.sdf_2dot4g_val = 1;
315
316 /* Enable 5 GHz support */
317 req.config_support_5g = 1;
318 req.support_5g_val = 1;
319 req.config_5g_beacons = 1;
320 req.beacon_5g_val = 1;
321 req.config_5g_sdf = 1;
322 req.sdf_5g_val = 1;
323
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200324 if (band) {
325 if (strcasecmp(band, "24G") == 0) {
326 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700327 "Band 2.4 GHz selected, disable 5 GHz");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200328 /* Disable 5G support */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700329 req.config_support_5g = 1;
330 req.support_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200331 req.config_5g_beacons = 1;
332 req.beacon_5g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700333 req.config_5g_sdf = 1;
334 req.sdf_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200335 }
336 }
337
338 if (further_avail_ind) {
339 sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled");
340 if (strcasecmp(further_avail_ind, "tx") == 0) {
341 is_fam = 1;
342 nan_further_availability_tx(dut, conn, cmd);
343 return 0;
344 } else if (strcasecmp(further_avail_ind, "rx") == 0) {
345 nan_further_availability_rx(dut, conn, cmd);
346 return 0;
347 }
348 }
349
350 if (only_5g && atoi(only_5g)) {
351 sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled");
352 req.config_2dot4g_support = 1;
353 req.support_2dot4g_val = 1;
354 req.config_2dot4g_beacons = 1;
355 req.beacon_2dot4g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700356 req.config_2dot4g_sdf = 1;
357 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200358 }
359
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700360 nan_enable_request(0, global_interface_handle, &req);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700361
Rakesh Sunki38dd72e2017-03-30 14:47:55 -0700362 if (nan_availability) {
363 int cmd_len, size;
364 NanDebugParams cfg_debug;
365
366 sigma_dut_print(dut, DUT_MSG_INFO,
367 "%s given string nan_availability: %s",
368 __func__, nan_availability);
369 memset(&cfg_debug, 0, sizeof(NanDebugParams));
370 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY;
371 size = NAN_MAX_DEBUG_MESSAGE_DATA_LEN;
372 nan_parse_hex_string(dut, &nan_availability[2],
373 &cfg_debug.debug_cmd_data[0], &size);
374 sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex nan_availability",
375 __func__);
376 nan_hex_dump(dut, &cfg_debug.debug_cmd_data[0], size);
377 cmd_len = size + sizeof(u32);
378 nan_debug_command_config(0, global_interface_handle,
379 cfg_debug, cmd_len);
380 }
381
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700382 /* To ensure sta_get_events to get the events
383 * only after joining the NAN cluster. */
384 abstime.tv_sec = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200385 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700386 wait(abstime);
387
388 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200389}
390
391
392int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn,
393 struct sigma_cmd *cmd)
394{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200395 struct timespec abstime;
396
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700397 nan_disable_request(0, global_interface_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200398
399 abstime.tv_sec = 4;
400 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700401 wait(abstime);
402
403 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200404}
405
406
407int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn,
408 struct sigma_cmd *cmd)
409{
410 const char *master_pref = get_param(cmd, "MasterPref");
411 const char *rand_fac = get_param(cmd, "RandFactor");
412 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700413 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200414 struct timespec abstime;
415 NanConfigRequest req;
416
417 memset(&req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200418 req.config_rssi_proximity = 1;
419 req.rssi_proximity = 70;
420
421 if (master_pref) {
422 int master_pref_val = strtoul(master_pref, NULL, 0);
423
424 req.config_master_pref = 1;
425 req.master_pref = master_pref_val;
426 }
427
428 if (rand_fac) {
429 int rand_fac_val = strtoul(rand_fac, NULL, 0);
430
431 req.config_random_factor_force = 1;
432 req.random_factor_force_val = rand_fac_val;
433 }
434
435 if (hop_count) {
436 int hop_count_val = strtoul(hop_count, NULL, 0);
437
438 req.config_hop_count_force = 1;
439 req.hop_count_force_val = hop_count_val;
440 }
441
Rakesh Sunki107356c2017-03-30 14:47:55 -0700442 ret = nan_config_request(0, global_interface_handle, &req);
443 if (ret != WIFI_SUCCESS)
444 send_resp(dut, conn, SIGMA_ERROR, "NAN config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200445
446 abstime.tv_sec = 4;
447 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700448 wait(abstime);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200449
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700450 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200451}
452
453
454static int sigma_nan_subscribe_request(struct sigma_dut *dut,
455 struct sigma_conn *conn,
456 struct sigma_cmd *cmd)
457{
458 const char *subscribe_type = get_param(cmd, "SubscribeType");
459 const char *service_name = get_param(cmd, "ServiceName");
460 const char *disc_range = get_param(cmd, "DiscoveryRange");
461 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
462 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
463 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
464 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
465 const char *include_bit = get_param(cmd, "IncludeBit");
466 const char *mac = get_param(cmd, "MAC");
467 const char *srf_type = get_param(cmd, "SRFType");
468 NanSubscribeRequest req;
469 int filter_len_rx = 0, filter_len_tx = 0;
470 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
471 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700472 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200473
474 memset(&req, 0, sizeof(NanSubscribeRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200475 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -0700476 req.period = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200477 req.subscribe_type = 1;
478 req.serviceResponseFilter = 1; /* MAC */
479 req.serviceResponseInclude = 0;
480 req.ssiRequiredForMatchIndication = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700481 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200482 req.subscribe_count = 0;
483
484 if (subscribe_type) {
485 if (strcasecmp(subscribe_type, "Active") == 0) {
486 req.subscribe_type = 1;
487 } else if (strcasecmp(subscribe_type, "Passive") == 0) {
488 req.subscribe_type = 0;
489 } else if (strcasecmp(subscribe_type, "Cancel") == 0) {
490 NanSubscribeCancelRequest req;
491
492 memset(&req, 0, sizeof(NanSubscribeCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700493 ret = nan_subscribe_cancel_request(
494 0, global_interface_handle, &req);
495 if (ret != WIFI_SUCCESS) {
496 send_resp(dut, conn, SIGMA_ERROR,
497 "NAN subscribe cancel request failed");
498 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200499 return 0;
500 }
501 }
502
503 if (disc_range)
504 req.rssi_threshold_flag = atoi(disc_range);
505
506 if (sdftx_dw)
507 req.subscribe_count = atoi(sdftx_dw);
508
509 /* Check this once again if config can be called here (TBD) */
510 if (discrange_ltd)
511 req.rssi_threshold_flag = atoi(discrange_ltd);
512
513 if (include_bit) {
514 int include_bit_val = atoi(include_bit);
515
516 req.serviceResponseInclude = include_bit_val;
517 sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d",
518 req.serviceResponseInclude);
519 }
520
521 if (srf_type) {
522 int srf_type_val = atoi(srf_type);
523
524 if (srf_type_val == 1)
525 req.serviceResponseFilter = 0; /* Bloom */
526 else
527 req.serviceResponseFilter = 1; /* MAC */
528 req.useServiceResponseFilter = 1;
529 sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d",
530 req.serviceResponseFilter);
531 }
532
533 if (mac) {
534 sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac);
535 req.num_intf_addr_present = nan_parse_mac_address_list(
536 dut, mac, &req.intf_addr[0][0],
537 NAN_MAX_SUBSCRIBE_MAX_ADDRESS);
538 }
539
540 memset(input_rx, 0, sizeof(input_rx));
541 memset(input_tx, 0, sizeof(input_tx));
542 if (rx_match_filter) {
543 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
544 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
545 filter_len_rx);
546 }
547 if (tx_match_filter) {
548 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
549 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
550 filter_len_tx);
551 }
552
553 if (tx_match_filter) {
554 req.tx_match_filter_len = filter_len_tx;
555 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
556 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
557 }
558 if (rx_match_filter) {
559 req.rx_match_filter_len = filter_len_rx;
560 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
561 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
562 }
563
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700564 if (service_name) {
565 strlcpy((char *) req.service_name, service_name,
566 strlen(service_name) + 1);
567 req.service_name_len = strlen(service_name);
568 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200569
Rakesh Sunki107356c2017-03-30 14:47:55 -0700570 ret = nan_subscribe_request(0, global_interface_handle, &req);
571 if (ret != WIFI_SUCCESS) {
572 send_resp(dut, conn, SIGMA_ERROR,
573 "NAN subscribe request failed");
574 }
575
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200576 return 0;
577}
578
579
Rakesh Sunkid7344c02017-03-30 14:47:55 -0700580static int sigma_ndp_configure_band(struct sigma_dut *dut,
581 struct sigma_conn *conn,
582 struct sigma_cmd *cmd,
583 NdpSupportedBand band_config_val)
584{
585 wifi_error ret;
586 NanDebugParams cfg_debug;
587 int size;
588
589 memset(&cfg_debug, 0, sizeof(NanDebugParams));
590 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS;
591 memcpy(cfg_debug.debug_cmd_data, &band_config_val, sizeof(int));
592 sigma_dut_print(dut, DUT_MSG_INFO, "%s:setting debug cmd=0x%x",
593 __func__, cfg_debug.cmd);
594 size = sizeof(u32) + sizeof(int);
595 ret = nan_debug_command_config(0, global_interface_handle, cfg_debug,
596 size);
597 if (ret != WIFI_SUCCESS)
598 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
599
600 return 0;
601}
602
603
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700604static int sigma_nan_data_request(struct sigma_dut *dut,
605 struct sigma_conn *conn,
606 struct sigma_cmd *cmd)
607{
608 const char *ndp_security = get_param(cmd, "DataPathSecurity");
609 const char *ndp_resp_mac = get_param(cmd, "RespNanMac");
610 const char *include_immutable = get_param(cmd, "includeimmutable");
611 const char *avoid_channel = get_param(cmd, "avoidchannel");
612 const char *invalid_nan_schedule = get_param(cmd, "InvalidNANSchedule");
613 const char *map_order = get_param(cmd, "maporder");
614 wifi_error ret;
615 NanDataPathInitiatorRequest init_req;
616 NanDebugParams cfg_debug;
617 int size;
618
619 memset(&init_req, 0, sizeof(NanDataPathInitiatorRequest));
620
621 if (ndp_security) {
622 if (strcasecmp(ndp_security, "open") == 0)
623 init_req.ndp_cfg.security_cfg =
624 NAN_DP_CONFIG_NO_SECURITY;
625 else if (strcasecmp(ndp_security, "secure") == 0)
626 init_req.ndp_cfg.security_cfg = NAN_DP_CONFIG_SECURITY;
627 }
628
629 if (include_immutable) {
630 int include_immutable_val = 0;
631
632 memset(&cfg_debug, 0, sizeof(NanDebugParams));
633 cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE;
634 include_immutable_val = atoi(include_immutable);
635 memcpy(cfg_debug.debug_cmd_data, &include_immutable_val,
636 sizeof(int));
637 size = sizeof(u32) + sizeof(int);
638 nan_debug_command_config(0, global_interface_handle,
639 cfg_debug, size);
640 }
641
642 if (avoid_channel) {
643 int avoid_channel_freq = 0;
644
645 memset(&cfg_debug, 0, sizeof(NanDebugParams));
646 avoid_channel_freq = channel_to_freq(atoi(avoid_channel));
647 cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL;
648 memcpy(cfg_debug.debug_cmd_data, &avoid_channel_freq,
649 sizeof(int));
650 size = sizeof(u32) + sizeof(int);
651 nan_debug_command_config(0, global_interface_handle,
652 cfg_debug, size);
653 }
654
655 if (invalid_nan_schedule) {
656 int invalid_nan_schedule_type = 0;
657
658 memset(&cfg_debug, 0, sizeof(NanDebugParams));
659 invalid_nan_schedule_type = atoi(invalid_nan_schedule);
660 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_TYPE;
661 memcpy(cfg_debug.debug_cmd_data,
662 &invalid_nan_schedule_type, sizeof(int));
663 size = sizeof(u32) + sizeof(int);
664 sigma_dut_print(dut, DUT_MSG_INFO,
665 "%s: invalid schedule type: cmd type = %d and command data = %d",
666 __func__, cfg_debug.cmd,
667 invalid_nan_schedule_type);
668 nan_debug_command_config(0, global_interface_handle,
669 cfg_debug, size);
670 }
671
672 if (map_order) {
673 int map_order_val = 0;
674
675 memset(&cfg_debug, 0, sizeof(NanDebugParams));
676 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER;
677 map_order_val = atoi(map_order);
678 memcpy(cfg_debug.debug_cmd_data, &map_order_val, sizeof(int));
679 size = sizeof(u32) + sizeof(int);
680 sigma_dut_print(dut, DUT_MSG_INFO,
681 "%s: map order: cmd type = %d and command data = %d",
682 __func__,
683 cfg_debug.cmd, invalid_nan_schedule_type);
684 nan_debug_command_config(0, global_interface_handle,
685 cfg_debug, size);
686 }
687
688 /*
689 * Setting this flag, so that interface for ping6 command
690 * is set appropriately in traffic_send_ping().
691 */
692 dut->ndp_enable = 1;
693
694 /*
695 * Intended sleep after NAN data interface create
696 * before the NAN data request
697 */
698 sleep(4);
699
700 init_req.requestor_instance_id = global_match_handle;
701 strlcpy((char *) init_req.ndp_iface, "nan0",
702 sizeof(init_req.ndp_iface));
703
704 if (ndp_resp_mac) {
705 nan_parse_mac_address(dut, ndp_resp_mac,
706 init_req.peer_disc_mac_addr);
707 sigma_dut_print(
708 dut, DUT_MSG_INFO, "PEER MAC ADDR: " MAC_ADDR_STR,
709 MAC_ADDR_ARRAY(init_req.peer_disc_mac_addr));
710 } else {
711 memcpy(init_req.peer_disc_mac_addr, global_peer_mac_addr,
712 sizeof(init_req.peer_disc_mac_addr));
713 }
714
715 /* Not requesting the channel and letting FW decide */
716 if (dut->sta_channel == 0) {
717 init_req.channel_request_type = NAN_DP_CHANNEL_NOT_REQUESTED;
718 init_req.channel = 0;
719 } else {
720 init_req.channel_request_type = NAN_DP_FORCE_CHANNEL_SETUP;
721 init_req.channel = channel_to_freq(dut->sta_channel);
722 }
723 sigma_dut_print(dut, DUT_MSG_INFO,
724 "%s: Initiator Request: Channel = %d Channel Request Type = %d",
725 __func__, init_req.channel,
726 init_req.channel_request_type);
727
728 if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) {
729 memcpy(&init_req.key_info.body.pmk_info.pmk[0],
730 &dut->nan_pmk[0], NAN_PMK_INFO_LEN);
731 init_req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
732 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
733 __func__,
734 init_req.key_info.body.pmk_info.pmk_len);
735 }
736
737 ret = nan_data_request_initiator(0, global_interface_handle, &init_req);
738 if (ret != WIFI_SUCCESS) {
739 send_resp(dut, conn, SIGMA_ERROR,
740 "Unable to initiate nan data request");
741 return 0;
742 }
743
744 return 0;
745}
746
747
Rakesh Sunkia5cc2842017-03-30 14:47:55 -0700748static int sigma_nan_data_response(struct sigma_dut *dut,
749 struct sigma_conn *conn,
750 struct sigma_cmd *cmd)
751{
752 const char *ndl_response = get_param(cmd, "NDLresponse");
753 const char *m4_response_type = get_param(cmd, "M4ResponseType");
754 wifi_error ret;
755 NanDebugParams cfg_debug;
756 int size;
757
758 if (ndl_response) {
759 int auto_responder_mode_val = 0;
760
761 sigma_dut_print(dut, DUT_MSG_INFO,
762 "%s: ndl_response = (%s) is passed",
763 __func__, ndl_response);
764 memset(&cfg_debug, 0, sizeof(NanDebugParams));
765 cfg_debug.cmd = NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE;
766 if (strcasecmp(ndl_response, "Auto") == 0) {
767 auto_responder_mode_val = NAN_DATA_RESPONDER_MODE_AUTO;
768 } else if (strcasecmp(ndl_response, "Reject") == 0) {
769 auto_responder_mode_val =
770 NAN_DATA_RESPONDER_MODE_REJECT;
771 } else if (strcasecmp(ndl_response, "Accept") == 0) {
772 auto_responder_mode_val =
773 NAN_DATA_RESPONDER_MODE_ACCEPT;
774 } else if (strcasecmp(ndl_response, "Counter") == 0) {
775 auto_responder_mode_val =
776 NAN_DATA_RESPONDER_MODE_COUNTER;
777 } else {
778 sigma_dut_print(dut, DUT_MSG_ERROR,
779 "%s: Invalid ndl_response",
780 __func__);
781 return 0;
782 }
783 memcpy(cfg_debug.debug_cmd_data, &auto_responder_mode_val,
784 sizeof(int));
785 size = sizeof(u32) + sizeof(int);
786 ret = nan_debug_command_config(0, global_interface_handle,
787 cfg_debug, size);
788 if (ret != WIFI_SUCCESS) {
789 send_resp(dut, conn, SIGMA_ERROR,
790 "Nan config request failed");
791 }
792 }
793
794 if (m4_response_type) {
795 int m4_response_type_val = 0;
796
797 sigma_dut_print(dut, DUT_MSG_INFO,
798 "%s: m4_response_type = (%s) is passed",
799 __func__, m4_response_type);
800 memset(&cfg_debug, 0, sizeof(NanDebugParams));
801 cfg_debug.cmd = NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE;
802 if (strcasecmp(m4_response_type, "Accept") == 0)
803 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_ACCEPT;
804 else if (strcasecmp(m4_response_type, "Reject") == 0)
805 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_REJECT;
806 else if (strcasecmp(m4_response_type, "BadMic") == 0)
807 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_BADMIC;
808
809 memcpy(cfg_debug.debug_cmd_data, &m4_response_type_val,
810 sizeof(int));
811 size = sizeof(u32) + sizeof(int);
812 ret = nan_debug_command_config(0, global_interface_handle,
813 cfg_debug, size);
814 if (ret != WIFI_SUCCESS) {
815 send_resp(dut, conn, SIGMA_ERROR,
816 "Nan config request failed");
817 }
818 }
819
820 return 0;
821}
822
823
Rakesh Sunki8a630b82017-03-30 14:47:55 -0700824static int sigma_nan_data_end(struct sigma_dut *dut, struct sigma_cmd *cmd)
825{
826 const char *nmf_security_config = get_param(cmd, "Security");
827 NanDataPathEndRequest req;
828 NanDebugParams cfg_debug;
829 int size;
830
831 memset(&req, 0, sizeof(NanDataPathEndRequest));
832 memset(&cfg_debug, 0, sizeof(NanDebugParams));
833 if (nmf_security_config) {
834 int nmf_security_config_val = 0;
835
836 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_NMF_CLEAR_CONFIG;
837 if (strcasecmp(nmf_security_config, "open") == 0)
838 nmf_security_config_val = NAN_NMF_CLEAR_ENABLE;
839 else if (strcasecmp(nmf_security_config, "secure") == 0)
840 nmf_security_config_val = NAN_NMF_CLEAR_DISABLE;
841 memcpy(cfg_debug.debug_cmd_data,
842 &nmf_security_config_val, sizeof(int));
843 size = sizeof(u32) + sizeof(int);
844 sigma_dut_print(dut, DUT_MSG_INFO,
845 "%s: nmf_security_config_val -- cmd type = %d and command data = %d",
846 __func__, cfg_debug.cmd,
847 nmf_security_config_val);
848 nan_debug_command_config(0, global_interface_handle,
849 cfg_debug, size);
850 }
851
852 req.num_ndp_instances = 1;
853 req.ndp_instance_id[0] = global_ndp_instance_id;
854
855 nan_data_end(0, global_interface_handle, &req);
856 return 0;
857}
858
859
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200860int config_post_disc_attr(void)
861{
Rakesh Sunki107356c2017-03-30 14:47:55 -0700862 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200863 NanConfigRequest configReq;
864
865 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200866
867 /* Configure Post disc attr */
868 /* Make these defines and use correct enum */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700869 configReq.num_config_discovery_attr = 1;
870 configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */
871 configReq.discovery_attr_val[0].role = 0;
872 configReq.discovery_attr_val[0].transmit_freq = 1;
873 configReq.discovery_attr_val[0].duration = 0;
874 configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200875
Rakesh Sunki107356c2017-03-30 14:47:55 -0700876 ret = nan_config_request(0, global_interface_handle, &configReq);
877 if (ret != WIFI_SUCCESS) {
878 sigma_dut_print(global_dut, DUT_MSG_INFO,
879 "NAN config request failed while configuring post discovery attribute");
880 }
881
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200882 return 0;
883}
884
885
886int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn,
887 struct sigma_cmd *cmd)
888{
889 const char *publish_type = get_param(cmd, "PublishType");
890 const char *service_name = get_param(cmd, "ServiceName");
891 const char *disc_range = get_param(cmd, "DiscoveryRange");
892 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
893 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
894 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
895 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
896 NanPublishRequest req;
897 int filter_len_rx = 0, filter_len_tx = 0;
898 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
899 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700900 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200901
902 memset(&req, 0, sizeof(NanPublishRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200903 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -0700904 req.period = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700905 req.publish_match_indicator = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200906 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
907 req.tx_type = NAN_TX_TYPE_BROADCAST;
908 req.publish_count = 0;
Rakesh Sunki0a0eea82017-03-30 14:47:55 -0700909 req.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_ALL;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700910
911 if (service_name) {
912 strlcpy((char *) req.service_name, service_name,
913 strlen(service_name) + 1);
914 req.service_name_len = strlen(service_name);
915 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200916
917 if (publish_type) {
918 if (strcasecmp(publish_type, "Solicited") == 0) {
919 req.publish_type = NAN_PUBLISH_TYPE_SOLICITED;
920 } else if (strcasecmp(publish_type, "Cancel") == 0) {
921 NanPublishCancelRequest req;
922
923 memset(&req, 0, sizeof(NanPublishCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700924 ret = nan_publish_cancel_request(
925 0, global_interface_handle, &req);
926 if (ret != WIFI_SUCCESS) {
927 send_resp(dut, conn, SIGMA_ERROR,
928 "Unable to cancel nan publish request");
929 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200930 return 0;
931 }
932 }
933
934 if (disc_range)
935 req.rssi_threshold_flag = atoi(disc_range);
936
937 if (sdftx_dw)
938 req.publish_count = atoi(sdftx_dw);
939
940 if (discrange_ltd)
941 req.rssi_threshold_flag = atoi(discrange_ltd);
942
943 memset(input_rx, 0, sizeof(input_rx));
944 memset(input_tx, 0, sizeof(input_tx));
945 if (rx_match_filter) {
946 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
947 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
948 filter_len_rx);
949 }
950 if (tx_match_filter) {
951 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
952 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
953 filter_len_tx);
954 }
955
956 if (is_fam == 1) {
957 config_post_disc_attr();
958 /* TODO: Add comments regarding this step */
959 req.connmap = 0x10;
960 }
961
962 if (tx_match_filter) {
963 req.tx_match_filter_len = filter_len_tx;
964 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
965 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
966 }
967
968 if (rx_match_filter) {
969 req.rx_match_filter_len = filter_len_rx;
970 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
971 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
972 }
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700973
974 if (service_name) {
975 strlcpy((char *) req.service_name, service_name,
976 strlen(service_name) + 1);
977 req.service_name_len = strlen(service_name);
978 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200979
Rakesh Sunki107356c2017-03-30 14:47:55 -0700980 ret = nan_publish_request(0, global_interface_handle, &req);
981 if (ret != WIFI_SUCCESS)
982 send_resp(dut, conn, SIGMA_ERROR, "Unable to publish");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200983
984 return 0;
985}
986
987
988static int nan_further_availability_rx(struct sigma_dut *dut,
989 struct sigma_conn *conn,
990 struct sigma_cmd *cmd)
991{
992 const char *master_pref = get_param(cmd, "MasterPref");
993 const char *rand_fac = get_param(cmd, "RandFactor");
994 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700995 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200996 struct timespec abstime;
997
998 NanEnableRequest req;
999
1000 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001001 req.cluster_low = 0;
1002 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001003 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001004
1005 if (master_pref)
1006 req.master_pref = strtoul(master_pref, NULL, 0);
1007
1008 if (rand_fac) {
1009 int rand_fac_val = strtoul(rand_fac, NULL, 0);
1010
1011 req.config_random_factor_force = 1;
1012 req.random_factor_force_val = rand_fac_val;
1013 }
1014
1015 if (hop_count) {
1016 int hop_count_val = strtoul(hop_count, NULL, 0);
1017
1018 req.config_hop_count_force = 1;
1019 req.hop_count_force_val = hop_count_val;
1020 }
1021
Rakesh Sunki107356c2017-03-30 14:47:55 -07001022 ret = nan_enable_request(0, global_interface_handle, &req);
1023 if (ret != WIFI_SUCCESS) {
1024 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
1025 return 0;
1026 }
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001027
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001028 abstime.tv_sec = 4;
1029 abstime.tv_nsec = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001030 wait(abstime);
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001031
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001032 return 0;
1033}
1034
1035
1036static int nan_further_availability_tx(struct sigma_dut *dut,
1037 struct sigma_conn *conn,
1038 struct sigma_cmd *cmd)
1039{
1040 const char *master_pref = get_param(cmd, "MasterPref");
1041 const char *rand_fac = get_param(cmd, "RandFactor");
1042 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001043 wifi_error ret;
1044
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001045 NanEnableRequest req;
1046 NanConfigRequest configReq;
1047
1048 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001049 req.cluster_low = 0;
1050 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001051 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001052
1053 if (master_pref)
1054 req.master_pref = strtoul(master_pref, NULL, 0);
1055
1056 if (rand_fac) {
1057 int rand_fac_val = strtoul(rand_fac, NULL, 0);
1058
1059 req.config_random_factor_force = 1;
1060 req.random_factor_force_val = rand_fac_val;
1061 }
1062
1063 if (hop_count) {
1064 int hop_count_val = strtoul(hop_count, NULL, 0);
1065
1066 req.config_hop_count_force = 1;
1067 req.hop_count_force_val = hop_count_val;
1068 }
1069
Rakesh Sunki107356c2017-03-30 14:47:55 -07001070 ret = nan_enable_request(0, global_interface_handle, &req);
1071 if (ret != WIFI_SUCCESS) {
1072 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
1073 return 0;
1074 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001075
1076 /* Start the config of fam */
1077
1078 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001079
1080 configReq.config_fam = 1;
1081 configReq.fam_val.numchans = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001082 configReq.fam_val.famchan[0].entry_control = 0;
1083 configReq.fam_val.famchan[0].class_val = 81;
1084 configReq.fam_val.famchan[0].channel = 6;
1085 configReq.fam_val.famchan[0].mapid = 0;
1086 configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe;
1087
Rakesh Sunki107356c2017-03-30 14:47:55 -07001088 ret = nan_config_request(0, global_interface_handle, &configReq);
1089 if (ret != WIFI_SUCCESS)
1090 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001091
1092 return 0;
1093}
1094
1095
1096int sigma_nan_transmit_followup(struct sigma_dut *dut,
1097 struct sigma_conn *conn,
1098 struct sigma_cmd *cmd)
1099{
1100 const char *mac = get_param(cmd, "mac");
1101 const char *requestor_id = get_param(cmd, "RemoteInstanceId");
1102 const char *local_id = get_param(cmd, "LocalInstanceId");
1103 const char *service_name = get_param(cmd, "servicename");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001104 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001105 NanTransmitFollowupRequest req;
1106
1107 memset(&req, 0, sizeof(NanTransmitFollowupRequest));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001108 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001109 req.addr[0] = 0xFF;
1110 req.addr[1] = 0xFF;
1111 req.addr[2] = 0xFF;
1112 req.addr[3] = 0xFF;
1113 req.addr[4] = 0xFF;
1114 req.addr[5] = 0xFF;
1115 req.priority = NAN_TX_PRIORITY_NORMAL;
1116 req.dw_or_faw = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001117
1118 if (service_name)
1119 req.service_specific_info_len = strlen(service_name);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001120
1121 if (requestor_id) {
1122 /* int requestor_id_val = atoi(requestor_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001123 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001124 }
1125 if (local_id) {
1126 /* int local_id_val = atoi(local_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001127 req.publish_subscribe_id = global_header_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001128 }
1129
1130 if (mac == NULL) {
1131 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address");
1132 return -1;
1133 }
1134 nan_parse_mac_address(dut, mac, req.addr);
1135
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001136 if (requestor_id)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001137 req.requestor_instance_id = strtoul(requestor_id, NULL, 0);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001138
Rakesh Sunki107356c2017-03-30 14:47:55 -07001139 ret = nan_transmit_followup_request(0, global_interface_handle, &req);
1140 if (ret != WIFI_SUCCESS) {
1141 send_resp(dut, conn, SIGMA_ERROR,
1142 "Unable to complete nan transmit followup");
1143 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001144
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001145 return 0;
1146}
1147
Rakesh Sunki107356c2017-03-30 14:47:55 -07001148
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001149/* NotifyResponse invoked to notify the status of the Request */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001150void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001151{
1152 sigma_dut_print(global_dut, DUT_MSG_INFO,
Rakesh Sunkifdbd60b2017-03-30 14:47:55 -07001153 "%s: status %d response_type %d",
1154 __func__, rsp_data->status, rsp_data->response_type);
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001155 if (rsp_data->response_type == NAN_RESPONSE_STATS &&
1156 rsp_data->body.stats_response.stats_type ==
1157 NAN_STATS_ID_DE_TIMING_SYNC) {
1158 NanSyncStats *pSyncStats;
1159
1160 sigma_dut_print(global_dut, DUT_MSG_INFO,
1161 "%s: stats_type %d", __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001162 rsp_data->body.stats_response.stats_type);
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001163 pSyncStats = &rsp_data->body.stats_response.data.sync_stats;
1164 memcpy(&global_nan_sync_stats, pSyncStats,
1165 sizeof(NanSyncStats));
1166 pthread_cond_signal(&gCondition);
Rakesh Sunki4d5912d2017-03-30 14:47:55 -07001167 } else if (rsp_data->response_type == NAN_RESPONSE_PUBLISH) {
1168 sigma_dut_print(global_dut, DUT_MSG_INFO,
1169 "%s: publish_id %d\n",
1170 __func__,
1171 rsp_data->body.publish_response.publish_id);
1172 global_publish_id = rsp_data->body.publish_response.publish_id;
1173 } else if (rsp_data->response_type == NAN_RESPONSE_SUBSCRIBE) {
1174 sigma_dut_print(global_dut, DUT_MSG_INFO,
1175 "%s: subscribe_id %d\n",
1176 __func__,
1177 rsp_data->body.subscribe_response.subscribe_id);
1178 global_subscribe_id =
1179 rsp_data->body.subscribe_response.subscribe_id;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001180 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001181}
1182
1183
1184/* Events Callback */
1185void nan_event_publish_replied(NanPublishRepliedInd *event)
1186{
1187 sigma_dut_print(global_dut, DUT_MSG_INFO,
1188 "%s: handle %d " MAC_ADDR_STR " rssi:%d",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001189 __func__, event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001190 MAC_ADDR_ARRAY(event->addr), event->rssi_value);
1191 event_anyresponse = 1;
1192 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001193 "EventName,Replied,RemoteInstanceID %d,mac," MAC_ADDR_STR,
1194 (event->requestor_instance_id >> 24),
1195 MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001196}
1197
1198
1199/* Events Callback */
1200void nan_event_publish_terminated(NanPublishTerminatedInd *event)
1201{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001202 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d",
1203 __func__, event->publish_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001204}
1205
1206
1207/* Events Callback */
1208void nan_event_match(NanMatchInd *event)
1209{
1210 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001211 "%s: Pub/Sub Id %d remote_requestor_id %08x "
1212 MAC_ADDR_STR
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001213 " rssi:%d",
1214 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001215 event->publish_subscribe_id,
1216 event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001217 MAC_ADDR_ARRAY(event->addr),
1218 event->rssi_value);
1219 event_anyresponse = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001220 global_header_handle = event->publish_subscribe_id;
1221 global_match_handle = event->requestor_instance_id;
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07001222 memcpy(global_peer_mac_addr, event->addr, sizeof(global_peer_mac_addr));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001223
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001224 /* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */
1225 /* global_pub_sub_handle = event->header.handle; */
1226 /* Print the SSI */
1227 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001228 nan_hex_dump(global_dut, event->service_specific_info,
1229 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001230 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1231 "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001232 MAC_ADDR_STR " ", (event->requestor_instance_id >> 24),
1233 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001234
1235 /* Print the match filter */
1236 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001237 nan_hex_dump(global_dut, event->sdf_match_filter,
1238 event->sdf_match_filter_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001239
1240 /* Print the conn_capability */
1241 sigma_dut_print(global_dut, DUT_MSG_INFO,
1242 "Printing PostConnectivity Capability");
1243 if (event->is_conn_capability_valid) {
1244 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s",
1245 event->conn_capability.is_wfd_supported ?
1246 "yes" : "no");
1247 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s",
1248 (event->conn_capability.is_wfds_supported ?
1249 "yes" : "no"));
1250 sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s",
1251 (event->conn_capability.is_tdls_supported ?
1252 "yes" : "no"));
1253 sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s",
1254 (event->conn_capability.is_ibss_supported ?
1255 "yes" : "no"));
1256 sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s",
1257 (event->conn_capability.is_mesh_supported ?
1258 "yes" : "no"));
1259 sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d",
1260 event->conn_capability.wlan_infra_field);
1261 } else {
1262 sigma_dut_print(global_dut, DUT_MSG_INFO,
1263 "PostConnectivity Capability not present");
1264 }
1265
1266 /* Print the discovery_attr */
1267 sigma_dut_print(global_dut, DUT_MSG_INFO,
1268 "Printing PostDiscovery Attribute");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001269 if (event->num_rx_discovery_attr) {
1270 int idx;
1271
1272 for (idx = 0; idx < event->num_rx_discovery_attr; idx++) {
1273 sigma_dut_print(global_dut, DUT_MSG_INFO,
1274 "PostDiscovery Attribute - %d", idx);
1275 sigma_dut_print(global_dut, DUT_MSG_INFO,
1276 "Conn Type:%d Device Role:%d"
1277 MAC_ADDR_STR,
1278 event->discovery_attr[idx].type,
1279 event->discovery_attr[idx].role,
1280 MAC_ADDR_ARRAY(event->discovery_attr[idx].addr));
1281 sigma_dut_print(global_dut, DUT_MSG_INFO,
1282 "Duration:%d MapId:%d "
1283 "avail_interval_bitmap:%04x",
1284 event->discovery_attr[idx].duration,
1285 event->discovery_attr[idx].mapid,
1286 event->discovery_attr[idx].avail_interval_bitmap);
1287 sigma_dut_print(global_dut, DUT_MSG_INFO,
1288 "Printing Mesh Id:");
1289 nan_hex_dump(global_dut,
1290 event->discovery_attr[idx].mesh_id,
1291 event->discovery_attr[idx].mesh_id_len);
1292 sigma_dut_print(global_dut, DUT_MSG_INFO,
1293 "Printing Infrastructure Ssid:");
1294 nan_hex_dump(global_dut,
1295 event->discovery_attr[idx].infrastructure_ssid_val,
1296 event->discovery_attr[idx].infrastructure_ssid_len);
1297 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001298 } else {
1299 sigma_dut_print(global_dut, DUT_MSG_INFO,
1300 "PostDiscovery attribute not present");
1301 }
1302
1303 /* Print the fam */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001304 if (event->num_chans) {
1305 nan_print_further_availability_chan(global_dut,
1306 event->num_chans,
1307 &event->famchan[0]);
1308 } else {
1309 sigma_dut_print(global_dut, DUT_MSG_INFO,
1310 "Further Availability Map not present");
1311 }
1312 if (event->cluster_attribute_len) {
1313 sigma_dut_print(global_dut, DUT_MSG_INFO,
1314 "Printing Cluster Attribute:");
1315 nan_hex_dump(global_dut, event->cluster_attribute,
1316 event->cluster_attribute_len);
1317 } else {
1318 sigma_dut_print(global_dut, DUT_MSG_INFO,
1319 "Cluster Attribute not present");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001320 }
1321}
1322
1323
1324/* Events Callback */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001325void nan_event_match_expired(NanMatchExpiredInd *event)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001326{
1327 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001328 "%s: publish_subscribe_id %d match_handle %08x",
1329 __func__, event->publish_subscribe_id,
1330 event->requestor_instance_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001331}
1332
1333
1334/* Events Callback */
1335void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event)
1336{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001337 sigma_dut_print(global_dut, DUT_MSG_INFO,
1338 "%s: Subscribe Id %d reason %d",
1339 __func__, event->subscribe_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001340}
1341
1342
1343/* Events Callback */
1344void nan_event_followup(NanFollowupInd *event)
1345{
1346 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001347 "%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d "
1348 MAC_ADDR_STR, __func__, event->publish_subscribe_id,
1349 event->requestor_instance_id, event->dw_or_faw,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001350 MAC_ADDR_ARRAY(event->addr));
1351
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001352 global_match_handle = event->publish_subscribe_id;
1353 global_header_handle = event->requestor_instance_id;
1354 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__);
1355 nan_hex_dump(global_dut, event->service_specific_info,
1356 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001357 event_anyresponse = 1;
1358 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1359 "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001360 MAC_ADDR_STR " ", event->requestor_instance_id >> 24,
1361 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001362}
1363
1364
1365/* Events Callback */
1366void nan_event_disceng_event(NanDiscEngEventInd *event)
1367{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001368 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d",
1369 __func__, event->event_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001370
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001371 if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001372 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster "
1373 MAC_ADDR_STR,
1374 __func__,
1375 MAC_ADDR_ARRAY(event->data.cluster.addr));
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001376 /* To ensure sta_get_events to get the events
1377 * only after joining the NAN cluster. */
1378 pthread_cond_signal(&gCondition);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001379 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001380 if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001381 sigma_dut_print(global_dut, DUT_MSG_INFO,
1382 "%s: Started cluster " MAC_ADDR_STR,
1383 __func__,
1384 MAC_ADDR_ARRAY(event->data.cluster.addr));
1385 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001386 if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) {
1387 sigma_dut_print(global_dut, DUT_MSG_INFO,
1388 "%s: Discovery Mac Address "
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001389 MAC_ADDR_STR,
1390 __func__,
1391 MAC_ADDR_ARRAY(event->data.mac_addr.addr));
1392 memcpy(global_nan_mac_addr, event->data.mac_addr.addr,
1393 sizeof(global_nan_mac_addr));
1394 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001395}
1396
1397
1398/* Events Callback */
1399void nan_event_disabled(NanDisabledInd *event)
1400{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001401 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d",
1402 __func__, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001403 /* pthread_cond_signal(&gCondition); */
1404}
1405
1406
Rakesh Sunki4c086672017-03-30 14:47:55 -07001407/* Events callback */
1408static void ndp_event_data_indication(NanDataPathRequestInd *event)
1409{
1410 sigma_dut_print(global_dut, DUT_MSG_INFO,
1411 "%s: Service Instance Id: %d Peer Discovery MAC ADDR "
1412 MAC_ADDR_STR
1413 " NDP Instance Id: %d App Info len %d App Info %s",
1414 __func__,
1415 event->service_instance_id,
1416 MAC_ADDR_ARRAY(event->peer_disc_mac_addr),
1417 event->ndp_instance_id,
1418 event->app_info.ndp_app_info_len,
1419 event->app_info.ndp_app_info);
1420
1421 global_ndp_instance_id = event->ndp_instance_id;
1422}
1423
1424
1425/* Events callback */
1426static void ndp_event_data_confirm(NanDataPathConfirmInd *event)
1427{
1428 sigma_dut_print(global_dut, DUT_MSG_INFO,
1429 "Received NDP Confirm Indication");
1430
1431 global_ndp_instance_id = event->ndp_instance_id;
1432 if (system("ifconfig nan0 up") != 0) {
1433 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1434 "Failed to set nan interface up");
1435 return;
1436 }
1437 if (system("ip -6 route add fe80::/64 dev nan0 table local") != 0) {
1438 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1439 "Failed to run:ip -6 route replace fe80::/64 dev nan0 table local");
1440 return;
1441 }
1442}
1443
1444
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001445void * my_thread_function(void *ptr)
1446{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001447 wifi_event_loop(global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001448 pthread_exit(0);
1449 return (void *) NULL;
1450}
1451
1452
1453static NanCallbackHandler callbackHandler = {
1454 .NotifyResponse = nan_notify_response,
1455 .EventPublishReplied = nan_event_publish_replied,
1456 .EventPublishTerminated = nan_event_publish_terminated,
1457 .EventMatch = nan_event_match,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001458 .EventMatchExpired = nan_event_match_expired,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001459 .EventSubscribeTerminated = nan_event_subscribe_terminated,
1460 .EventFollowup = nan_event_followup,
1461 .EventDiscEngEvent = nan_event_disceng_event,
1462 .EventDisabled = nan_event_disabled,
Rakesh Sunki4c086672017-03-30 14:47:55 -07001463 .EventDataRequest = ndp_event_data_indication,
1464 .EventDataConfirm = ndp_event_data_confirm,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001465};
1466
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001467
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001468void nan_init(struct sigma_dut *dut)
1469{
1470 pthread_t thread1; /* thread variables */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001471 wifi_error err = wifi_initialize(&global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001472
1473 if (err) {
1474 printf("wifi hal initialize failed\n");
1475 return;
1476 }
1477
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001478 global_interface_handle = wifi_get_iface_handle(global_wifi_handle,
1479 (char *) "wlan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001480 /* create threads 1 */
1481 pthread_create(&thread1, NULL, &my_thread_function, NULL);
1482
1483 pthread_mutex_init(&gMutex, NULL);
1484 pthread_cond_init(&gCondition, NULL);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001485 if (global_interface_handle)
1486 nan_register_handler(global_interface_handle, callbackHandler);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001487}
1488
1489
1490void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1491 struct sigma_cmd *cmd)
1492{
1493 sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default");
1494
1495 if (nan_state == 0) {
1496 nan_init(dut);
1497 nan_state = 1;
1498 }
1499 is_fam = 0;
1500 event_anyresponse = 0;
1501 global_dut = dut;
Rakesh Sunki7d37f412017-03-30 14:47:55 -07001502 memset(&dut->nan_pmk[0], 0, NAN_PMK_INFO_LEN);
1503 dut->nan_pmk_len = 0;
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001504 dut->sta_channel = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001505 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001506 memset(&global_nan_sync_stats, 0, sizeof(global_nan_sync_stats));
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001507
Rakesh Sunki8a630b82017-03-30 14:47:55 -07001508 sigma_nan_data_end(dut, cmd);
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001509 nan_data_interface_delete(0, global_interface_handle, (char *) "nan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001510 sigma_nan_disable(dut, conn, cmd);
1511}
1512
1513
1514int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1515 struct sigma_cmd *cmd)
1516{
1517 const char *program = get_param(cmd, "Prog");
1518 const char *nan_op = get_param(cmd, "NANOp");
1519 const char *method_type = get_param(cmd, "MethodType");
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001520 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001521 char resp_buf[100];
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001522 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001523
1524 if (program == NULL)
1525 return -1;
1526
1527 if (strcasecmp(program, "NAN") != 0) {
1528 send_resp(dut, conn, SIGMA_ERROR,
1529 "ErrorCode,Unsupported program");
1530 return 0;
1531 }
1532
1533 if (nan_op) {
1534 /*
1535 * NANOp has been specified.
1536 * We will build a nan_enable or nan_disable command.
1537 */
1538 if (strcasecmp(nan_op, "On") == 0) {
1539 if (sigma_nan_enable(dut, conn, cmd) == 0) {
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001540 ret = nan_data_interface_create(
1541 0, global_interface_handle,
1542 (char *) "nan0");
1543 if (ret != WIFI_SUCCESS) {
1544 sigma_dut_print(
1545 global_dut, DUT_MSG_ERROR,
1546 "Unable to create NAN data interface");
1547 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001548 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1549 MAC_ADDR_STR,
1550 MAC_ADDR_ARRAY(global_nan_mac_addr));
1551 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1552 } else {
1553 send_resp(dut, conn, SIGMA_ERROR,
1554 "NAN_ENABLE_FAILED");
1555 return -1;
1556 }
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001557
1558 if (band && strcasecmp(band, "24g") == 0) {
1559 sigma_dut_print(dut, DUT_MSG_INFO,
1560 "%s: Setting band to 2G Only",
1561 __func__);
1562 sigma_ndp_configure_band(
1563 dut, conn, cmd,
1564 NAN_DATA_PATH_SUPPORTED_BAND_2G);
1565 } else if (band && dut->sta_channel > 12) {
1566 sigma_ndp_configure_band(
1567 dut, conn, cmd,
1568 NAN_DATA_PATH_SUPPORT_DUAL_BAND);
1569 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001570 } else if (strcasecmp(nan_op, "Off") == 0) {
1571 sigma_nan_disable(dut, conn, cmd);
1572 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1573 }
1574 }
1575 if (nan_state && nan_op == NULL) {
1576 if (method_type) {
1577 if (strcasecmp(method_type, "Publish") == 0) {
1578 sigma_nan_publish_request(dut, conn, cmd);
1579 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1580 }
1581 if (strcasecmp(method_type, "Subscribe") == 0) {
1582 sigma_nan_subscribe_request(dut, conn, cmd);
1583 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1584 }
1585 if (strcasecmp(method_type, "Followup") == 0) {
1586 sigma_nan_transmit_followup(dut, conn, cmd);
1587 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1588 }
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07001589 if (strcasecmp(method_type, "DataRequest") == 0) {
1590 sigma_nan_data_request(dut, conn, cmd);
1591 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1592 }
Rakesh Sunkia5cc2842017-03-30 14:47:55 -07001593 if (strcasecmp(method_type, "DataResponse") == 0) {
1594 sigma_dut_print(dut, DUT_MSG_INFO,
1595 "%s: method_type is DataResponse",
1596 __func__);
1597 sigma_nan_data_response(dut, conn, cmd);
1598 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1599 }
Rakesh Sunki8a630b82017-03-30 14:47:55 -07001600 if (strcasecmp(method_type, "DataEnd") == 0) {
1601 sigma_nan_data_end(dut, cmd);
1602 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1603 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001604 } else {
1605 sigma_nan_config_enable(dut, conn, cmd);
1606 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1607 MAC_ADDR_STR,
1608 MAC_ADDR_ARRAY(global_nan_mac_addr));
1609 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1610 }
1611 }
1612
1613 return 0;
1614}
1615
1616
1617int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1618 struct sigma_cmd *cmd)
1619{
1620
1621 const char *program = get_param(cmd, "Program");
1622 const char *parameter = get_param(cmd, "Parameter");
1623 char resp_buf[100];
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001624 NanStatsRequest req;
1625 struct timespec abstime;
1626 u64 master_rank;
1627 u8 master_pref;
1628 u8 random_factor;
1629 u8 hop_count;
1630 u32 beacon_transmit_time;
1631 u32 ndp_channel_freq;
1632 u32 ndp_channel_freq2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001633
1634 if (program == NULL) {
1635 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name");
1636 return -1;
1637 }
1638 if (strcasecmp(program, "NAN") != 0) {
1639 send_resp(dut, conn, SIGMA_ERROR,
1640 "ErrorCode,Unsupported program");
1641 return 0;
1642 }
1643
1644 if (parameter == NULL) {
1645 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter");
1646 return -1;
1647 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001648
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001649 memset(&req, 0, sizeof(NanStatsRequest));
1650 req.stats_type = (NanStatsType) NAN_STATS_ID_DE_TIMING_SYNC;
1651 nan_stats_request(0, global_interface_handle, &req);
1652 /*
1653 * To ensure sta_get_events to get the events
1654 * only after joining the NAN cluster
1655 */
1656 abstime.tv_sec = 4;
1657 abstime.tv_nsec = 0;
1658 wait(abstime);
1659
1660 master_rank = global_nan_sync_stats.myRank;
1661 master_pref = (global_nan_sync_stats.myRank & 0xFF00000000000000) >> 56;
1662 random_factor = (global_nan_sync_stats.myRank & 0x00FF000000000000) >>
1663 48;
1664 hop_count = global_nan_sync_stats.currAmHopCount;
1665 beacon_transmit_time = global_nan_sync_stats.currAmBTT;
1666 ndp_channel_freq = global_nan_sync_stats.ndpChannelFreq;
1667 ndp_channel_freq2 = global_nan_sync_stats.ndpChannelFreq2;
1668
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001669 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001670 "%s: NanStatsRequest Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d ndp_channel_freq:%d ndp_channel_freq2:%d",
1671 __func__, master_pref, random_factor,
1672 hop_count, beacon_transmit_time,
1673 ndp_channel_freq, ndp_channel_freq2);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001674
1675 if (strcasecmp(parameter, "MasterPref") == 0) {
1676 snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001677 master_pref);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001678 } else if (strcasecmp(parameter, "MasterRank") == 0) {
1679 snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001680 master_rank);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001681 } else if (strcasecmp(parameter, "RandFactor") == 0) {
1682 snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001683 random_factor);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001684 } else if (strcasecmp(parameter, "HopCount") == 0) {
1685 snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001686 hop_count);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001687 } else if (strcasecmp(parameter, "BeaconTransTime") == 0) {
1688 snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001689 beacon_transmit_time);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001690 } else if (strcasecmp(parameter, "NANStatus") == 0) {
1691 if (nan_state == 1)
1692 snprintf(resp_buf, sizeof(resp_buf), "On");
1693 else
1694 snprintf(resp_buf, sizeof(resp_buf), "Off");
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001695 } else if (strcasecmp(parameter, "NDPChannel") == 0) {
1696 if (ndp_channel_freq != 0 && ndp_channel_freq2 != 0) {
1697 snprintf(resp_buf, sizeof(resp_buf),
1698 "ndpchannel,%d,ndpchannel,%d",
1699 freq_to_channel(ndp_channel_freq),
1700 freq_to_channel(ndp_channel_freq2));
1701 } else if (ndp_channel_freq != 0) {
1702 snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
1703 freq_to_channel(ndp_channel_freq));
1704 } else if (ndp_channel_freq2 != 0) {
1705 snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
1706 freq_to_channel(ndp_channel_freq2));
1707 } else {
1708 sigma_dut_print(dut, DUT_MSG_ERROR,
1709 "%s: No Negotiated NDP Channels", __func__);
1710 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001711 } else {
1712 send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
1713 return 0;
1714 }
1715
1716 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1717 return 0;
1718}
1719
1720
1721int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1722 struct sigma_cmd *cmd)
1723{
1724 const char *action = get_param(cmd, "Action");
1725
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001726 if (!action)
1727 return 0;
1728
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001729 /* Check action for start, stop and get events. */
1730 if (strcasecmp(action, "Start") == 0) {
1731 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1732 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1733 } else if (strcasecmp(action, "Stop") == 0) {
1734 event_anyresponse = 0;
1735 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1736 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1737 } else if (strcasecmp(action, "Get") == 0) {
1738 if (event_anyresponse == 1) {
1739 send_resp(dut, conn, SIGMA_COMPLETE,
1740 global_event_resp_buf);
1741 } else {
1742 send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE");
1743 }
1744 }
1745 return 0;
1746}
Rakesh Sunki4b75f962017-03-30 14:47:55 -07001747
1748#else /* #if NAN_CERT_VERSION */
1749
1750int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
1751 struct sigma_conn *conn,
1752 struct sigma_cmd *cmd)
1753{
1754 return 1;
1755}
1756
1757
1758int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1759 struct sigma_cmd *cmd)
1760{
1761 return 0;
1762
1763}
1764
1765
1766void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1767 struct sigma_cmd *cmd)
1768{
1769 return;
1770}
1771
1772
1773int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1774 struct sigma_cmd *cmd)
1775{
1776 return 0;
1777}
1778
1779
1780int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1781 struct sigma_cmd *cmd)
1782{
1783 return 0;
1784}
1785
1786#endif /* #if NAN_CERT_VERSION */