blob: f056dec5ce0cf54d8e381d00b623b535d18ab86d [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
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -070032#define DEFAULT_SVC "QNanCluster"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020033#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
34#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
35#ifndef ETH_ALEN
36#define ETH_ALEN 6
37#endif
38
39struct sigma_dut *global_dut = NULL;
40static char global_nan_mac_addr[ETH_ALEN];
Rakesh Sunki14cfcd22017-03-30 14:47:55 -070041static char global_peer_mac_addr[ETH_ALEN];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020042static char global_event_resp_buf[1024];
Rakesh Sunki42363682017-05-16 15:00:42 -070043static u8 global_publish_service_name[NAN_MAX_SERVICE_NAME_LEN];
44static u32 global_publish_service_name_len = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020045
46static int nan_further_availability_tx(struct sigma_dut *dut,
47 struct sigma_conn *conn,
48 struct sigma_cmd *cmd);
49static int nan_further_availability_rx(struct sigma_dut *dut,
50 struct sigma_conn *conn,
51 struct sigma_cmd *cmd);
52
53
54void nan_hex_dump(struct sigma_dut *dut, uint8_t *data, size_t len)
55{
56 char buf[512];
57 uint16_t index;
58 uint8_t *ptr;
59 int pos;
60
61 memset(buf, 0, sizeof(buf));
62 ptr = data;
63 pos = 0;
64 for (index = 0; index < len; index++) {
65 pos += sprintf(&(buf[pos]), "%02x ", *ptr++);
66 if (pos > 508)
67 break;
68 }
69 sigma_dut_print(dut, DUT_MSG_INFO, "HEXDUMP len=[%d]", (int) len);
70 sigma_dut_print(dut, DUT_MSG_INFO, "buf:%s", buf);
71}
72
73
74int nan_parse_hex(unsigned char c)
75{
76 if (c >= '0' && c <= '9')
77 return c - '0';
78 if (c >= 'a' && c <= 'f')
79 return c - 'a' + 10;
80 if (c >= 'A' && c <= 'F')
81 return c - 'A' + 10;
82 return 0;
83}
84
85
86int nan_parse_token(const char *tokenIn, u8 *tokenOut, int *filterLen)
87{
88 int total_len = 0, len = 0;
89 char *saveptr = NULL;
90
91 tokenIn = strtok_r((char *) tokenIn, ":", &saveptr);
92 while (tokenIn != NULL) {
93 len = strlen(tokenIn);
94 if (len == 1 && *tokenIn == '*')
95 len = 0;
96 tokenOut[total_len++] = (u8) len;
97 if (len != 0)
98 memcpy((u8 *) tokenOut + total_len, tokenIn, len);
99 total_len += len;
100 tokenIn = strtok_r(NULL, ":", &saveptr);
101 }
102 *filterLen = total_len;
103 return 0;
104}
105
106
107int nan_parse_mac_address(struct sigma_dut *dut, const char *arg, u8 *addr)
108{
109 if (strlen(arg) != 17) {
110 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid mac address %s",
111 arg);
112 sigma_dut_print(dut, DUT_MSG_ERROR,
113 "expected format xx:xx:xx:xx:xx:xx");
114 return -1;
115 }
116
117 addr[0] = nan_parse_hex(arg[0]) << 4 | nan_parse_hex(arg[1]);
118 addr[1] = nan_parse_hex(arg[3]) << 4 | nan_parse_hex(arg[4]);
119 addr[2] = nan_parse_hex(arg[6]) << 4 | nan_parse_hex(arg[7]);
120 addr[3] = nan_parse_hex(arg[9]) << 4 | nan_parse_hex(arg[10]);
121 addr[4] = nan_parse_hex(arg[12]) << 4 | nan_parse_hex(arg[13]);
122 addr[5] = nan_parse_hex(arg[15]) << 4 | nan_parse_hex(arg[16]);
123
124 return 0;
125}
126
127
128int nan_parse_mac_address_list(struct sigma_dut *dut, const char *input,
129 u8 *output, u16 max_addr_allowed)
130{
131 /*
132 * Reads a list of mac address separated by space. Each MAC address
133 * should have the format of aa:bb:cc:dd:ee:ff.
134 */
135 char *saveptr;
136 char *token;
137 int i = 0;
138
139 for (i = 0; i < max_addr_allowed; i++) {
140 token = strtok_r((i == 0) ? (char *) input : NULL,
141 " ", &saveptr);
142 if (token) {
143 nan_parse_mac_address(dut, token, output);
144 output += NAN_MAC_ADDR_LEN;
145 } else
146 break;
147 }
148
149 sigma_dut_print(dut, DUT_MSG_INFO, "Num MacAddress:%d", i);
150
151 return i;
152}
153
154
155int nan_parse_hex_string(struct sigma_dut *dut, const char *input,
156 u8 *output, int *outputlen)
157{
158 int i = 0;
159 int j = 0;
160
161 for (i = 0; i < (int) strlen(input) && j < *outputlen; i += 2) {
162 output[j] = nan_parse_hex(input[i]);
163 if (i + 1 < (int) strlen(input)) {
164 output[j] = ((output[j] << 4) |
165 nan_parse_hex(input[i + 1]));
166 }
167 j++;
168 }
169 *outputlen = j;
170 sigma_dut_print(dut, DUT_MSG_INFO, "Input:%s inputlen:%d outputlen:%d",
171 input, (int) strlen(input), (int) *outputlen);
172 return 0;
173}
174
175
176int wait(struct timespec abstime)
177{
178 struct timeval now;
179
180 gettimeofday(&now, NULL);
181
182 abstime.tv_sec += now.tv_sec;
183 if (((abstime.tv_nsec + now.tv_usec * 1000) > 1000 * 1000 * 1000) ||
184 (abstime.tv_nsec + now.tv_usec * 1000 < 0)) {
185 abstime.tv_sec += 1;
186 abstime.tv_nsec += now.tv_usec * 1000;
187 abstime.tv_nsec -= 1000 * 1000 * 1000;
188 } else {
189 abstime.tv_nsec += now.tv_usec * 1000;
190 }
191
192 return pthread_cond_timedwait(&gCondition, &gMutex, &abstime);
193}
194
195
196int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
197 struct sigma_conn *conn,
198 struct sigma_cmd *cmd)
199{
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700200 const char *oper_chan = get_param(cmd, "oper_chn");
Rakesh Sunki7d37f412017-03-30 14:47:55 -0700201 const char *pmk = get_param(cmd, "PMK");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200202
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700203 if (oper_chan) {
204 sigma_dut_print(dut, DUT_MSG_INFO, "Operating Channel: %s",
205 oper_chan);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700206 dut->sta_channel = atoi(oper_chan);
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700207 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200208
Rakesh Sunki7d37f412017-03-30 14:47:55 -0700209 if (pmk) {
210 int pmk_len;
211
212 sigma_dut_print(dut, DUT_MSG_INFO, "%s given string pmk: %s",
213 __func__, pmk);
214 memset(dut->nan_pmk, 0, NAN_PMK_INFO_LEN);
215 dut->nan_pmk_len = 0;
216 pmk_len = NAN_PMK_INFO_LEN;
217 nan_parse_hex_string(dut, &pmk[2], &dut->nan_pmk[0], &pmk_len);
218 dut->nan_pmk_len = pmk_len;
219 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
220 __func__, dut->nan_pmk_len);
221 sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex pmk", __func__);
222 nan_hex_dump(dut, &dut->nan_pmk[0], dut->nan_pmk_len);
223 }
224
Rakesh Sunki14bff1d2017-03-30 14:47:55 -0700225 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200226 return 0;
227}
228
229
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700230void nan_print_further_availability_chan(struct sigma_dut *dut,
231 u8 num_chans,
232 NanFurtherAvailabilityChannel *fachan)
233{
234 int idx;
235
236 sigma_dut_print(dut, DUT_MSG_INFO,
237 "********Printing FurtherAvailabilityChan Info******");
238 sigma_dut_print(dut, DUT_MSG_INFO, "Numchans:%d", num_chans);
239 for (idx = 0; idx < num_chans; idx++) {
240 sigma_dut_print(dut, DUT_MSG_INFO,
241 "[%d]: NanAvailDuration:%d class_val:%02x channel:%d",
242 idx, fachan->entry_control,
243 fachan->class_val, fachan->channel);
244 sigma_dut_print(dut, DUT_MSG_INFO,
245 "[%d]: mapid:%d Availability bitmap:%08x",
246 idx, fachan->mapid,
247 fachan->avail_interval_bitmap);
248 }
249 sigma_dut_print(dut, DUT_MSG_INFO,
250 "*********************Done**********************");
251}
252
253
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200254int sigma_nan_enable(struct sigma_dut *dut, struct sigma_conn *conn,
255 struct sigma_cmd *cmd)
256{
257 const char *master_pref = get_param(cmd, "MasterPref");
258 const char *rand_fac = get_param(cmd, "RandFactor");
259 const char *hop_count = get_param(cmd, "HopCount");
260 const char *high_tsf = get_param(cmd, "HighTSF");
261 const char *sdftx_band = get_param(cmd, "SDFTxBand");
262 const char *oper_chan = get_param(cmd, "oper_chn");
263 const char *further_avail_ind = get_param(cmd, "FurtherAvailInd");
264 const char *band = get_param(cmd, "Band");
265 const char *only_5g = get_param(cmd, "5GOnly");
Rakesh Sunki38dd72e2017-03-30 14:47:55 -0700266 const char *nan_availability = get_param(cmd, "NANAvailability");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200267 struct timespec abstime;
268 NanEnableRequest req;
269
270 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200271 req.cluster_low = 0;
272 req.cluster_high = 0xFFFF;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700273 req.master_pref = 100;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200274
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700275 /* This is a debug hack to beacon in channel 11 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200276 if (oper_chan) {
277 req.config_2dot4g_support = 1;
278 req.support_2dot4g_val = 111;
279 }
280
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200281 if (master_pref) {
282 int master_pref_val = strtoul(master_pref, NULL, 0);
283
284 req.master_pref = master_pref_val;
285 }
286
287 if (rand_fac) {
288 int rand_fac_val = strtoul(rand_fac, NULL, 0);
289
290 req.config_random_factor_force = 1;
291 req.random_factor_force_val = rand_fac_val;
292 }
293
294 if (hop_count) {
295 int hop_count_val = strtoul(hop_count, NULL, 0);
296
297 req.config_hop_count_force = 1;
298 req.hop_count_force_val = hop_count_val;
299 }
300
301 if (sdftx_band) {
302 if (strcasecmp(sdftx_band, "5G") == 0) {
303 req.config_2dot4g_support = 1;
304 req.support_2dot4g_val = 0;
305 }
306 }
307
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700308 sigma_dut_print(dut, DUT_MSG_INFO,
309 "%s: Setting dual band 2.4 GHz and 5 GHz by default",
310 __func__);
311 /* Enable 2.4 GHz support */
312 req.config_2dot4g_support = 1;
313 req.support_2dot4g_val = 1;
314 req.config_2dot4g_beacons = 1;
315 req.beacon_2dot4g_val = 1;
316 req.config_2dot4g_sdf = 1;
317 req.sdf_2dot4g_val = 1;
318
319 /* Enable 5 GHz support */
320 req.config_support_5g = 1;
321 req.support_5g_val = 1;
322 req.config_5g_beacons = 1;
323 req.beacon_5g_val = 1;
324 req.config_5g_sdf = 1;
325 req.sdf_5g_val = 1;
326
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200327 if (band) {
328 if (strcasecmp(band, "24G") == 0) {
329 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700330 "Band 2.4 GHz selected, disable 5 GHz");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200331 /* Disable 5G support */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700332 req.config_support_5g = 1;
333 req.support_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200334 req.config_5g_beacons = 1;
335 req.beacon_5g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700336 req.config_5g_sdf = 1;
337 req.sdf_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200338 }
339 }
340
341 if (further_avail_ind) {
342 sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled");
343 if (strcasecmp(further_avail_ind, "tx") == 0) {
344 is_fam = 1;
345 nan_further_availability_tx(dut, conn, cmd);
346 return 0;
347 } else if (strcasecmp(further_avail_ind, "rx") == 0) {
348 nan_further_availability_rx(dut, conn, cmd);
349 return 0;
350 }
351 }
352
353 if (only_5g && atoi(only_5g)) {
354 sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled");
355 req.config_2dot4g_support = 1;
356 req.support_2dot4g_val = 1;
357 req.config_2dot4g_beacons = 1;
358 req.beacon_2dot4g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700359 req.config_2dot4g_sdf = 1;
360 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200361 }
362
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700363 nan_enable_request(0, global_interface_handle, &req);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700364
Rakesh Sunki38dd72e2017-03-30 14:47:55 -0700365 if (nan_availability) {
366 int cmd_len, size;
367 NanDebugParams cfg_debug;
368
369 sigma_dut_print(dut, DUT_MSG_INFO,
370 "%s given string nan_availability: %s",
371 __func__, nan_availability);
372 memset(&cfg_debug, 0, sizeof(NanDebugParams));
373 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY;
374 size = NAN_MAX_DEBUG_MESSAGE_DATA_LEN;
375 nan_parse_hex_string(dut, &nan_availability[2],
376 &cfg_debug.debug_cmd_data[0], &size);
377 sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex nan_availability",
378 __func__);
379 nan_hex_dump(dut, &cfg_debug.debug_cmd_data[0], size);
380 cmd_len = size + sizeof(u32);
381 nan_debug_command_config(0, global_interface_handle,
382 cfg_debug, cmd_len);
383 }
384
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700385 /* To ensure sta_get_events to get the events
386 * only after joining the NAN cluster. */
387 abstime.tv_sec = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200388 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700389 wait(abstime);
390
391 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200392}
393
394
395int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn,
396 struct sigma_cmd *cmd)
397{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200398 struct timespec abstime;
399
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700400 nan_disable_request(0, global_interface_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200401
402 abstime.tv_sec = 4;
403 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700404 wait(abstime);
405
406 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200407}
408
409
410int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn,
411 struct sigma_cmd *cmd)
412{
413 const char *master_pref = get_param(cmd, "MasterPref");
414 const char *rand_fac = get_param(cmd, "RandFactor");
415 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700416 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200417 struct timespec abstime;
418 NanConfigRequest req;
419
420 memset(&req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200421 req.config_rssi_proximity = 1;
422 req.rssi_proximity = 70;
423
424 if (master_pref) {
425 int master_pref_val = strtoul(master_pref, NULL, 0);
426
427 req.config_master_pref = 1;
428 req.master_pref = master_pref_val;
429 }
430
431 if (rand_fac) {
432 int rand_fac_val = strtoul(rand_fac, NULL, 0);
433
434 req.config_random_factor_force = 1;
435 req.random_factor_force_val = rand_fac_val;
436 }
437
438 if (hop_count) {
439 int hop_count_val = strtoul(hop_count, NULL, 0);
440
441 req.config_hop_count_force = 1;
442 req.hop_count_force_val = hop_count_val;
443 }
444
Rakesh Sunki107356c2017-03-30 14:47:55 -0700445 ret = nan_config_request(0, global_interface_handle, &req);
446 if (ret != WIFI_SUCCESS)
447 send_resp(dut, conn, SIGMA_ERROR, "NAN config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200448
449 abstime.tv_sec = 4;
450 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700451 wait(abstime);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200452
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700453 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200454}
455
456
457static int sigma_nan_subscribe_request(struct sigma_dut *dut,
458 struct sigma_conn *conn,
459 struct sigma_cmd *cmd)
460{
461 const char *subscribe_type = get_param(cmd, "SubscribeType");
462 const char *service_name = get_param(cmd, "ServiceName");
463 const char *disc_range = get_param(cmd, "DiscoveryRange");
464 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
465 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
466 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
467 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
468 const char *include_bit = get_param(cmd, "IncludeBit");
469 const char *mac = get_param(cmd, "MAC");
470 const char *srf_type = get_param(cmd, "SRFType");
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700471 const char *awake_dw_interval = get_param(cmd, "awakeDWint");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200472 NanSubscribeRequest req;
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700473 NanConfigRequest config_req;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200474 int filter_len_rx = 0, filter_len_tx = 0;
475 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
476 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700477 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200478
479 memset(&req, 0, sizeof(NanSubscribeRequest));
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700480 memset(&config_req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200481 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -0700482 req.period = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200483 req.subscribe_type = 1;
484 req.serviceResponseFilter = 1; /* MAC */
485 req.serviceResponseInclude = 0;
486 req.ssiRequiredForMatchIndication = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700487 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200488 req.subscribe_count = 0;
489
490 if (subscribe_type) {
491 if (strcasecmp(subscribe_type, "Active") == 0) {
492 req.subscribe_type = 1;
493 } else if (strcasecmp(subscribe_type, "Passive") == 0) {
494 req.subscribe_type = 0;
495 } else if (strcasecmp(subscribe_type, "Cancel") == 0) {
496 NanSubscribeCancelRequest req;
497
498 memset(&req, 0, sizeof(NanSubscribeCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700499 ret = nan_subscribe_cancel_request(
500 0, global_interface_handle, &req);
501 if (ret != WIFI_SUCCESS) {
502 send_resp(dut, conn, SIGMA_ERROR,
503 "NAN subscribe cancel request failed");
504 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200505 return 0;
506 }
507 }
508
509 if (disc_range)
510 req.rssi_threshold_flag = atoi(disc_range);
511
512 if (sdftx_dw)
513 req.subscribe_count = atoi(sdftx_dw);
514
515 /* Check this once again if config can be called here (TBD) */
516 if (discrange_ltd)
517 req.rssi_threshold_flag = atoi(discrange_ltd);
518
519 if (include_bit) {
520 int include_bit_val = atoi(include_bit);
521
522 req.serviceResponseInclude = include_bit_val;
523 sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d",
524 req.serviceResponseInclude);
525 }
526
527 if (srf_type) {
528 int srf_type_val = atoi(srf_type);
529
530 if (srf_type_val == 1)
531 req.serviceResponseFilter = 0; /* Bloom */
532 else
533 req.serviceResponseFilter = 1; /* MAC */
534 req.useServiceResponseFilter = 1;
535 sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d",
536 req.serviceResponseFilter);
537 }
538
539 if (mac) {
540 sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac);
541 req.num_intf_addr_present = nan_parse_mac_address_list(
542 dut, mac, &req.intf_addr[0][0],
543 NAN_MAX_SUBSCRIBE_MAX_ADDRESS);
544 }
545
546 memset(input_rx, 0, sizeof(input_rx));
547 memset(input_tx, 0, sizeof(input_tx));
548 if (rx_match_filter) {
549 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
550 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
551 filter_len_rx);
552 }
553 if (tx_match_filter) {
554 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
555 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
556 filter_len_tx);
557 }
558
559 if (tx_match_filter) {
560 req.tx_match_filter_len = filter_len_tx;
561 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
562 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
563 }
564 if (rx_match_filter) {
565 req.rx_match_filter_len = filter_len_rx;
566 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
567 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
568 }
569
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700570 if (service_name) {
571 strlcpy((char *) req.service_name, service_name,
572 strlen(service_name) + 1);
573 req.service_name_len = strlen(service_name);
574 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200575
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700576 if (awake_dw_interval) {
577 int input_dw_interval_val = atoi(awake_dw_interval);
578 int awake_dw_int = 0;
579
580 if (input_dw_interval_val > NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL) {
581 sigma_dut_print(dut, DUT_MSG_INFO,
582 "%s: input active dw interval = %d overwritting dw interval to Max allowed dw interval 16",
583 __func__, input_dw_interval_val);
584 input_dw_interval_val =
585 NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL;
586 }
587 sigma_dut_print(dut, DUT_MSG_INFO,
588 "%s: input active DW interval = %d",
589 __func__, input_dw_interval_val);
590 /*
591 * Indicates the interval for Sync beacons and SDF's in 2.4 GHz
592 * or 5 GHz band. Valid values of DW Interval are: 1, 2, 3, 4,
593 * and 5; 0 is reserved. The SDF includes in OTA when enabled.
594 * The publish/subscribe period values don't override the device
595 * level configurations.
596 * input_dw_interval_val is provided by the user are in the
597 * format 2^n-1 = 1/2/4/8/16. Internal implementation expects n
598 * to be passed to indicate the awake_dw_interval.
599 */
600 if (input_dw_interval_val == 1 ||
601 input_dw_interval_val % 2 == 0) {
602 while (input_dw_interval_val > 0) {
603 input_dw_interval_val >>= 1;
604 awake_dw_int++;
605 }
606 }
607 sigma_dut_print(dut, DUT_MSG_INFO,
608 "%s:converted active DW interval = %d",
609 __func__, awake_dw_int);
610 config_req.config_dw.config_2dot4g_dw_band = 1;
611 config_req.config_dw.dw_2dot4g_interval_val = awake_dw_int;
612 config_req.config_dw.config_5g_dw_band = 1;
613 config_req.config_dw.dw_5g_interval_val = awake_dw_int;
614 ret = nan_config_request(0, global_interface_handle,
615 &config_req);
616 if (ret != WIFI_SUCCESS) {
617 sigma_dut_print(dut, DUT_MSG_ERROR,
618 "%s:NAN config request failed",
619 __func__);
620 return -2;
621 }
622 }
623
Rakesh Sunki107356c2017-03-30 14:47:55 -0700624 ret = nan_subscribe_request(0, global_interface_handle, &req);
625 if (ret != WIFI_SUCCESS) {
626 send_resp(dut, conn, SIGMA_ERROR,
627 "NAN subscribe request failed");
628 }
629
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200630 return 0;
631}
632
633
Rakesh Sunkid7344c02017-03-30 14:47:55 -0700634static int sigma_ndp_configure_band(struct sigma_dut *dut,
635 struct sigma_conn *conn,
636 struct sigma_cmd *cmd,
637 NdpSupportedBand band_config_val)
638{
639 wifi_error ret;
640 NanDebugParams cfg_debug;
641 int size;
642
643 memset(&cfg_debug, 0, sizeof(NanDebugParams));
644 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS;
645 memcpy(cfg_debug.debug_cmd_data, &band_config_val, sizeof(int));
646 sigma_dut_print(dut, DUT_MSG_INFO, "%s:setting debug cmd=0x%x",
647 __func__, cfg_debug.cmd);
648 size = sizeof(u32) + sizeof(int);
649 ret = nan_debug_command_config(0, global_interface_handle, cfg_debug,
650 size);
651 if (ret != WIFI_SUCCESS)
652 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
653
654 return 0;
655}
656
657
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700658static int sigma_nan_data_request(struct sigma_dut *dut,
659 struct sigma_conn *conn,
660 struct sigma_cmd *cmd)
661{
662 const char *ndp_security = get_param(cmd, "DataPathSecurity");
663 const char *ndp_resp_mac = get_param(cmd, "RespNanMac");
664 const char *include_immutable = get_param(cmd, "includeimmutable");
665 const char *avoid_channel = get_param(cmd, "avoidchannel");
666 const char *invalid_nan_schedule = get_param(cmd, "InvalidNANSchedule");
667 const char *map_order = get_param(cmd, "maporder");
Rakesh Sunki8a4845d2017-05-16 15:27:13 -0700668#if NAN_CERT_VERSION >= 3
669 const char *qos_config = get_param(cmd, "QoS");
670#endif
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700671 wifi_error ret;
672 NanDataPathInitiatorRequest init_req;
673 NanDebugParams cfg_debug;
674 int size;
675
676 memset(&init_req, 0, sizeof(NanDataPathInitiatorRequest));
677
678 if (ndp_security) {
679 if (strcasecmp(ndp_security, "open") == 0)
680 init_req.ndp_cfg.security_cfg =
681 NAN_DP_CONFIG_NO_SECURITY;
682 else if (strcasecmp(ndp_security, "secure") == 0)
683 init_req.ndp_cfg.security_cfg = NAN_DP_CONFIG_SECURITY;
684 }
685
686 if (include_immutable) {
687 int include_immutable_val = 0;
688
689 memset(&cfg_debug, 0, sizeof(NanDebugParams));
690 cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE;
691 include_immutable_val = atoi(include_immutable);
692 memcpy(cfg_debug.debug_cmd_data, &include_immutable_val,
693 sizeof(int));
694 size = sizeof(u32) + sizeof(int);
695 nan_debug_command_config(0, global_interface_handle,
696 cfg_debug, size);
697 }
698
699 if (avoid_channel) {
700 int avoid_channel_freq = 0;
701
702 memset(&cfg_debug, 0, sizeof(NanDebugParams));
703 avoid_channel_freq = channel_to_freq(atoi(avoid_channel));
704 cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL;
705 memcpy(cfg_debug.debug_cmd_data, &avoid_channel_freq,
706 sizeof(int));
707 size = sizeof(u32) + sizeof(int);
708 nan_debug_command_config(0, global_interface_handle,
709 cfg_debug, size);
710 }
711
712 if (invalid_nan_schedule) {
713 int invalid_nan_schedule_type = 0;
714
715 memset(&cfg_debug, 0, sizeof(NanDebugParams));
716 invalid_nan_schedule_type = atoi(invalid_nan_schedule);
717 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_TYPE;
718 memcpy(cfg_debug.debug_cmd_data,
719 &invalid_nan_schedule_type, sizeof(int));
720 size = sizeof(u32) + sizeof(int);
721 sigma_dut_print(dut, DUT_MSG_INFO,
722 "%s: invalid schedule type: cmd type = %d and command data = %d",
723 __func__, cfg_debug.cmd,
724 invalid_nan_schedule_type);
725 nan_debug_command_config(0, global_interface_handle,
726 cfg_debug, size);
727 }
728
729 if (map_order) {
730 int map_order_val = 0;
731
732 memset(&cfg_debug, 0, sizeof(NanDebugParams));
733 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER;
734 map_order_val = atoi(map_order);
735 memcpy(cfg_debug.debug_cmd_data, &map_order_val, sizeof(int));
736 size = sizeof(u32) + sizeof(int);
737 sigma_dut_print(dut, DUT_MSG_INFO,
738 "%s: map order: cmd type = %d and command data = %d",
739 __func__,
Rakesh Sunki9eaa6772017-04-04 11:37:03 -0700740 cfg_debug.cmd, map_order_val);
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700741 nan_debug_command_config(0, global_interface_handle,
742 cfg_debug, size);
743 }
744
Rakesh Sunki8a4845d2017-05-16 15:27:13 -0700745#if NAN_CERT_VERSION >= 3
746 if (qos_config) {
747 u32 qos_config_val = 0;
748
749 memset(&cfg_debug, 0, sizeof(NanDebugParams));
750 cfg_debug.cmd = NAN_TEST_MODE_CMD_CONFIG_QOS;
751 qos_config_val = atoi(qos_config);
752 memcpy(cfg_debug.debug_cmd_data, &qos_config_val, sizeof(u32));
753 size = sizeof(u32) + sizeof(u32);
754 sigma_dut_print(dut, DUT_MSG_INFO,
755 "%s: qos config: cmd type = %d and command data = %d",
756 __func__, cfg_debug.cmd, qos_config_val);
757 nan_debug_command_config(0, global_interface_handle,
758 cfg_debug, size);
759 }
760#endif
761
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700762 /*
763 * Setting this flag, so that interface for ping6 command
764 * is set appropriately in traffic_send_ping().
765 */
766 dut->ndp_enable = 1;
767
768 /*
769 * Intended sleep after NAN data interface create
770 * before the NAN data request
771 */
772 sleep(4);
773
774 init_req.requestor_instance_id = global_match_handle;
775 strlcpy((char *) init_req.ndp_iface, "nan0",
776 sizeof(init_req.ndp_iface));
777
778 if (ndp_resp_mac) {
779 nan_parse_mac_address(dut, ndp_resp_mac,
780 init_req.peer_disc_mac_addr);
781 sigma_dut_print(
782 dut, DUT_MSG_INFO, "PEER MAC ADDR: " MAC_ADDR_STR,
783 MAC_ADDR_ARRAY(init_req.peer_disc_mac_addr));
784 } else {
785 memcpy(init_req.peer_disc_mac_addr, global_peer_mac_addr,
786 sizeof(init_req.peer_disc_mac_addr));
787 }
788
789 /* Not requesting the channel and letting FW decide */
790 if (dut->sta_channel == 0) {
791 init_req.channel_request_type = NAN_DP_CHANNEL_NOT_REQUESTED;
792 init_req.channel = 0;
793 } else {
794 init_req.channel_request_type = NAN_DP_FORCE_CHANNEL_SETUP;
795 init_req.channel = channel_to_freq(dut->sta_channel);
796 }
797 sigma_dut_print(dut, DUT_MSG_INFO,
798 "%s: Initiator Request: Channel = %d Channel Request Type = %d",
799 __func__, init_req.channel,
800 init_req.channel_request_type);
801
802 if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) {
Rakesh Sunki395b0152017-05-16 15:30:36 -0700803 init_req.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700804 memcpy(&init_req.key_info.body.pmk_info.pmk[0],
805 &dut->nan_pmk[0], NAN_PMK_INFO_LEN);
806 init_req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
807 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
808 __func__,
809 init_req.key_info.body.pmk_info.pmk_len);
810 }
811
812 ret = nan_data_request_initiator(0, global_interface_handle, &init_req);
813 if (ret != WIFI_SUCCESS) {
814 send_resp(dut, conn, SIGMA_ERROR,
815 "Unable to initiate nan data request");
816 return 0;
817 }
818
819 return 0;
820}
821
822
Rakesh Sunkia5cc2842017-03-30 14:47:55 -0700823static int sigma_nan_data_response(struct sigma_dut *dut,
824 struct sigma_conn *conn,
825 struct sigma_cmd *cmd)
826{
827 const char *ndl_response = get_param(cmd, "NDLresponse");
828 const char *m4_response_type = get_param(cmd, "M4ResponseType");
829 wifi_error ret;
830 NanDebugParams cfg_debug;
831 int size;
832
833 if (ndl_response) {
834 int auto_responder_mode_val = 0;
835
836 sigma_dut_print(dut, DUT_MSG_INFO,
837 "%s: ndl_response = (%s) is passed",
838 __func__, ndl_response);
839 memset(&cfg_debug, 0, sizeof(NanDebugParams));
840 cfg_debug.cmd = NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE;
841 if (strcasecmp(ndl_response, "Auto") == 0) {
842 auto_responder_mode_val = NAN_DATA_RESPONDER_MODE_AUTO;
843 } else if (strcasecmp(ndl_response, "Reject") == 0) {
844 auto_responder_mode_val =
845 NAN_DATA_RESPONDER_MODE_REJECT;
846 } else if (strcasecmp(ndl_response, "Accept") == 0) {
847 auto_responder_mode_val =
848 NAN_DATA_RESPONDER_MODE_ACCEPT;
849 } else if (strcasecmp(ndl_response, "Counter") == 0) {
850 auto_responder_mode_val =
851 NAN_DATA_RESPONDER_MODE_COUNTER;
852 } else {
853 sigma_dut_print(dut, DUT_MSG_ERROR,
854 "%s: Invalid ndl_response",
855 __func__);
856 return 0;
857 }
858 memcpy(cfg_debug.debug_cmd_data, &auto_responder_mode_val,
859 sizeof(int));
860 size = sizeof(u32) + sizeof(int);
861 ret = nan_debug_command_config(0, global_interface_handle,
862 cfg_debug, size);
863 if (ret != WIFI_SUCCESS) {
864 send_resp(dut, conn, SIGMA_ERROR,
865 "Nan config request failed");
866 }
867 }
868
869 if (m4_response_type) {
870 int m4_response_type_val = 0;
871
872 sigma_dut_print(dut, DUT_MSG_INFO,
873 "%s: m4_response_type = (%s) is passed",
874 __func__, m4_response_type);
875 memset(&cfg_debug, 0, sizeof(NanDebugParams));
876 cfg_debug.cmd = NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE;
877 if (strcasecmp(m4_response_type, "Accept") == 0)
878 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_ACCEPT;
879 else if (strcasecmp(m4_response_type, "Reject") == 0)
880 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_REJECT;
881 else if (strcasecmp(m4_response_type, "BadMic") == 0)
882 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_BADMIC;
883
884 memcpy(cfg_debug.debug_cmd_data, &m4_response_type_val,
885 sizeof(int));
886 size = sizeof(u32) + sizeof(int);
887 ret = nan_debug_command_config(0, global_interface_handle,
888 cfg_debug, size);
889 if (ret != WIFI_SUCCESS) {
890 send_resp(dut, conn, SIGMA_ERROR,
891 "Nan config request failed");
892 }
893 }
894
895 return 0;
896}
897
898
Rakesh Sunki8a630b82017-03-30 14:47:55 -0700899static int sigma_nan_data_end(struct sigma_dut *dut, struct sigma_cmd *cmd)
900{
901 const char *nmf_security_config = get_param(cmd, "Security");
902 NanDataPathEndRequest req;
903 NanDebugParams cfg_debug;
904 int size;
905
906 memset(&req, 0, sizeof(NanDataPathEndRequest));
907 memset(&cfg_debug, 0, sizeof(NanDebugParams));
908 if (nmf_security_config) {
909 int nmf_security_config_val = 0;
910
911 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_NMF_CLEAR_CONFIG;
912 if (strcasecmp(nmf_security_config, "open") == 0)
913 nmf_security_config_val = NAN_NMF_CLEAR_ENABLE;
914 else if (strcasecmp(nmf_security_config, "secure") == 0)
915 nmf_security_config_val = NAN_NMF_CLEAR_DISABLE;
916 memcpy(cfg_debug.debug_cmd_data,
917 &nmf_security_config_val, sizeof(int));
918 size = sizeof(u32) + sizeof(int);
919 sigma_dut_print(dut, DUT_MSG_INFO,
920 "%s: nmf_security_config_val -- cmd type = %d and command data = %d",
921 __func__, cfg_debug.cmd,
922 nmf_security_config_val);
923 nan_debug_command_config(0, global_interface_handle,
924 cfg_debug, size);
925 }
926
927 req.num_ndp_instances = 1;
928 req.ndp_instance_id[0] = global_ndp_instance_id;
929
930 nan_data_end(0, global_interface_handle, &req);
931 return 0;
932}
933
934
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -0700935static int sigma_nan_range_request(struct sigma_dut *dut,
936 struct sigma_cmd *cmd)
937{
938 const char *dest_mac = get_param(cmd, "destmac");
939 NanSubscribeRequest req;
940
941 memset(&req, 0, sizeof(NanSubscribeRequest));
942 req.period = 1;
943 req.subscribe_type = NAN_SUBSCRIBE_TYPE_ACTIVE;
944 req.serviceResponseFilter = NAN_SRF_ATTR_BLOOM_FILTER;
945 req.serviceResponseInclude = NAN_SRF_INCLUDE_RESPOND;
946 req.ssiRequiredForMatchIndication = NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
947 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
948 req.subscribe_count = 0;
949 strlcpy((char *) req.service_name, DEFAULT_SVC,
950 NAN_MAX_SERVICE_NAME_LEN);
951 req.service_name_len = strlen((char *) req.service_name);
952
953 req.subscribe_id = global_subscribe_id;
954 req.sdea_params.ranging_state = 1;
955 req.sdea_params.range_report = NAN_ENABLE_RANGE_REPORT;
956 req.range_response_cfg.requestor_instance_id = global_match_handle;
957 req.range_response_cfg.ranging_response = NAN_RANGE_REQUEST_ACCEPT;
958 req.ranging_cfg.config_ranging_indications =
959 NAN_RANGING_INDICATE_CONTINUOUS_MASK;
960 if (dest_mac) {
961 nan_parse_mac_address(dut, dest_mac,
962 req.range_response_cfg.peer_addr);
963 sigma_dut_print(
964 dut, DUT_MSG_INFO, "peer mac addr: " MAC_ADDR_STR,
965 MAC_ADDR_ARRAY(req.range_response_cfg.peer_addr));
966 }
967 nan_subscribe_request(0, global_interface_handle, &req);
968
969 return 0;
970}
971
972
973static int sigma_nan_cancel_range(struct sigma_dut *dut,
974 struct sigma_cmd *cmd)
975{
976 const char *dest_mac = get_param(cmd, "destmac");
977 NanPublishRequest req;
978
979 memset(&req, 0, sizeof(NanPublishRequest));
980 req.ttl = 0;
981 req.period = 1;
982 req.publish_match_indicator = 1;
983 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
984 req.tx_type = NAN_TX_TYPE_BROADCAST;
985 req.publish_count = 0;
986 strlcpy((char *) req.service_name, DEFAULT_SVC,
987 NAN_MAX_SERVICE_NAME_LEN);
988 req.service_name_len = strlen((char *) req.service_name);
989 req.publish_id = global_publish_id;
990 req.range_response_cfg.ranging_response = NAN_RANGE_REQUEST_CANCEL;
991 if (dest_mac) {
992 nan_parse_mac_address(dut, dest_mac,
993 req.range_response_cfg.peer_addr);
994 sigma_dut_print(
995 dut, DUT_MSG_INFO, "peer mac addr: " MAC_ADDR_STR,
996 MAC_ADDR_ARRAY(req.range_response_cfg.peer_addr));
997 }
998 nan_publish_request(0, global_interface_handle, &req);
999
1000 return 0;
1001}
1002
1003
Rakesh Sunkib2b65162017-03-30 14:47:55 -07001004static int sigma_nan_schedule_update(struct sigma_dut *dut,
1005 struct sigma_cmd *cmd)
1006{
1007 const char *schedule_update_type = get_param(cmd, "type");
1008 const char *channel_availability = get_param(cmd,
1009 "ChannelAvailability");
1010 const char *responder_nmi_mac = get_param(cmd, "ResponderNMI");
1011 NanDebugParams cfg_debug;
1012 int size = 0;
1013
1014 memset(&cfg_debug, 0, sizeof(NanDebugParams));
1015
1016 if (!schedule_update_type)
1017 return 0;
1018
1019 if (strcasecmp(schedule_update_type, "ULWnotify") == 0) {
1020 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY;
1021 size = sizeof(u32);
1022 sigma_dut_print(dut, DUT_MSG_INFO,
1023 "%s: Schedule Update cmd type = %d", __func__,
1024 cfg_debug.cmd);
1025 if (channel_availability) {
1026 int channel_availability_val;
1027
1028 channel_availability_val = atoi(channel_availability);
1029 size += sizeof(int);
1030 memcpy(cfg_debug.debug_cmd_data,
1031 &channel_availability_val, sizeof(int));
1032 sigma_dut_print(dut, DUT_MSG_INFO,
1033 "%s: Schedule Update cmd data = %d size = %d",
1034 __func__, channel_availability_val,
1035 size);
1036 }
1037 } else if (strcasecmp(schedule_update_type, "NDLnegotiate") == 0) {
1038 cfg_debug.cmd =
1039 NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE;
1040 size = sizeof(u32);
1041 sigma_dut_print(dut, DUT_MSG_INFO,
1042 "%s: Schedule Update cmd type = %d", __func__,
1043 cfg_debug.cmd);
1044 if (responder_nmi_mac) {
1045 u8 responder_nmi_mac_addr[NAN_MAC_ADDR_LEN];
1046
1047 nan_parse_mac_address(dut, responder_nmi_mac,
1048 responder_nmi_mac_addr);
1049 size += NAN_MAC_ADDR_LEN;
1050 memcpy(cfg_debug.debug_cmd_data, responder_nmi_mac_addr,
1051 NAN_MAC_ADDR_LEN);
1052 sigma_dut_print(dut, DUT_MSG_INFO,
1053 "%s: RESPONDER NMI MAC: "MAC_ADDR_STR,
1054 __func__,
1055 MAC_ADDR_ARRAY(responder_nmi_mac_addr));
1056 sigma_dut_print(dut, DUT_MSG_INFO,
1057 "%s: Schedule Update: cmd size = %d",
1058 __func__, size);
1059 }
1060 } else if (strcasecmp(schedule_update_type, "NDLnotify") == 0) {
1061 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY;
1062 size = sizeof(u32);
1063 sigma_dut_print(dut, DUT_MSG_INFO,
1064 "%s: Schedule Update cmd type = %d", __func__,
1065 cfg_debug.cmd);
1066 }
1067
1068 nan_debug_command_config(0, global_interface_handle, cfg_debug, size);
1069
1070 return 0;
1071}
1072
1073
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001074int config_post_disc_attr(void)
1075{
Rakesh Sunki107356c2017-03-30 14:47:55 -07001076 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001077 NanConfigRequest configReq;
1078
1079 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001080
1081 /* Configure Post disc attr */
1082 /* Make these defines and use correct enum */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001083 configReq.num_config_discovery_attr = 1;
1084 configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */
1085 configReq.discovery_attr_val[0].role = 0;
1086 configReq.discovery_attr_val[0].transmit_freq = 1;
1087 configReq.discovery_attr_val[0].duration = 0;
1088 configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001089
Rakesh Sunki107356c2017-03-30 14:47:55 -07001090 ret = nan_config_request(0, global_interface_handle, &configReq);
1091 if (ret != WIFI_SUCCESS) {
1092 sigma_dut_print(global_dut, DUT_MSG_INFO,
1093 "NAN config request failed while configuring post discovery attribute");
1094 }
1095
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001096 return 0;
1097}
1098
1099
1100int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn,
1101 struct sigma_cmd *cmd)
1102{
1103 const char *publish_type = get_param(cmd, "PublishType");
1104 const char *service_name = get_param(cmd, "ServiceName");
1105 const char *disc_range = get_param(cmd, "DiscoveryRange");
1106 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
1107 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
1108 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
1109 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001110 const char *ndp_enable = get_param(cmd, "DataPathFlag");
1111 const char *ndp_type = get_param(cmd, "DataPathType");
1112 const char *data_path_security = get_param(cmd, "datapathsecurity");
Rakesh Sunki48060402017-03-30 14:47:55 -07001113 const char *range_required = get_param(cmd, "rangerequired");
Rakesh Sunkie6f66832017-05-16 15:22:48 -07001114 const char *awake_dw_interval = get_param(cmd, "awakeDWint");
Rakesh Sunki8a4845d2017-05-16 15:27:13 -07001115#if NAN_CERT_VERSION >= 3
1116 const char *qos_config = get_param(cmd, "QoS");
1117#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001118 NanPublishRequest req;
Rakesh Sunkie6f66832017-05-16 15:22:48 -07001119 NanConfigRequest config_req;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001120 int filter_len_rx = 0, filter_len_tx = 0;
1121 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
1122 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -07001123 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001124
1125 memset(&req, 0, sizeof(NanPublishRequest));
Rakesh Sunkie6f66832017-05-16 15:22:48 -07001126 memset(&config_req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001127 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -07001128 req.period = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001129 req.publish_match_indicator = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001130 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
1131 req.tx_type = NAN_TX_TYPE_BROADCAST;
1132 req.publish_count = 0;
Rakesh Sunki0a0eea82017-03-30 14:47:55 -07001133 req.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_ALL;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001134
Rakesh Sunki42363682017-05-16 15:00:42 -07001135 if (global_publish_service_name_len &&
1136 service_name &&
1137 strcasecmp((char *) global_publish_service_name,
1138 service_name) == 0 &&
1139 global_publish_id) {
1140 req.publish_id = global_publish_id;
1141 sigma_dut_print(dut, DUT_MSG_INFO,
1142 "%s: updating publish_id = %d in publish request",
1143 __func__, req.publish_id);
1144 }
1145
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001146 if (service_name) {
1147 strlcpy((char *) req.service_name, service_name,
Rakesh Sunki42363682017-05-16 15:00:42 -07001148 sizeof(req.service_name));
1149 req.service_name_len = strlen((char *) req.service_name);
1150 strlcpy((char *) global_publish_service_name, service_name,
1151 sizeof(global_publish_service_name));
1152 global_publish_service_name_len =
1153 strlen((char *) global_publish_service_name);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001154 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001155
1156 if (publish_type) {
1157 if (strcasecmp(publish_type, "Solicited") == 0) {
1158 req.publish_type = NAN_PUBLISH_TYPE_SOLICITED;
Rakesh Sunki62644ab2017-03-30 14:47:55 -07001159 } else if (strcasecmp(publish_type, "Unsolicited") == 0) {
1160 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001161 } else if (strcasecmp(publish_type, "Cancel") == 0) {
1162 NanPublishCancelRequest req;
1163
1164 memset(&req, 0, sizeof(NanPublishCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -07001165 ret = nan_publish_cancel_request(
1166 0, global_interface_handle, &req);
1167 if (ret != WIFI_SUCCESS) {
1168 send_resp(dut, conn, SIGMA_ERROR,
1169 "Unable to cancel nan publish request");
1170 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001171 return 0;
1172 }
1173 }
1174
1175 if (disc_range)
1176 req.rssi_threshold_flag = atoi(disc_range);
1177
1178 if (sdftx_dw)
1179 req.publish_count = atoi(sdftx_dw);
1180
1181 if (discrange_ltd)
1182 req.rssi_threshold_flag = atoi(discrange_ltd);
1183
1184 memset(input_rx, 0, sizeof(input_rx));
1185 memset(input_tx, 0, sizeof(input_tx));
1186 if (rx_match_filter) {
1187 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
1188 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
1189 filter_len_rx);
1190 }
1191 if (tx_match_filter) {
1192 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
1193 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
1194 filter_len_tx);
1195 }
1196
1197 if (is_fam == 1) {
1198 config_post_disc_attr();
Rakesh Sunkif680e0f2017-03-30 14:47:55 -07001199 /*
1200 * 8-bit bitmap which allows the Host to associate this publish
1201 * with a particular Post-NAN Connectivity attribute which has
1202 * been sent down in a NanConfigureRequest/NanEnableRequest
1203 * message. If the DE fails to find a configured Post-NAN
1204 * connectivity attributes referenced by the bitmap, the DE will
1205 * return an error code to the Host. If the Publish is
1206 * configured to use a Post-NAN Connectivity attribute and the
1207 * Host does not refresh the Post-NAN Connectivity attribute the
1208 * Publish will be canceled and the Host will be sent a
1209 * PublishTerminatedIndication message.
1210 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001211 req.connmap = 0x10;
1212 }
1213
1214 if (tx_match_filter) {
1215 req.tx_match_filter_len = filter_len_tx;
1216 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
1217 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
1218 }
1219
1220 if (rx_match_filter) {
1221 req.rx_match_filter_len = filter_len_rx;
1222 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
1223 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
1224 }
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001225
1226 if (service_name) {
1227 strlcpy((char *) req.service_name, service_name,
1228 strlen(service_name) + 1);
1229 req.service_name_len = strlen(service_name);
1230 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001231
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001232 if (ndp_enable) {
1233 if (strcasecmp(ndp_enable, "enable") == 0)
1234 req.sdea_params.config_nan_data_path = 1;
1235 else
1236 req.sdea_params.config_nan_data_path = 0;
1237
1238 if (ndp_type)
1239 req.sdea_params.ndp_type = atoi(ndp_type);
1240
1241 if (data_path_security) {
1242 if (strcasecmp(data_path_security, "secure") == 0) {
1243 req.sdea_params.security_cfg =
1244 NAN_DP_CONFIG_SECURITY;
1245 } else if (strcasecmp(data_path_security, "open") ==
1246 0) {
1247 req.sdea_params.security_cfg =
1248 NAN_DP_CONFIG_NO_SECURITY;
1249 }
1250 }
1251
1252 if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) {
Rakesh Sunki395b0152017-05-16 15:30:36 -07001253 req.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001254 memcpy(&req.key_info.body.pmk_info.pmk[0],
1255 &dut->nan_pmk[0], NAN_PMK_INFO_LEN);
1256 req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
1257 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
1258 __func__, req.key_info.body.pmk_info.pmk_len);
1259 }
1260 }
Rakesh Sunki48060402017-03-30 14:47:55 -07001261 if (range_required && strcasecmp(range_required, "enable") == 0) {
1262 req.sdea_params.ranging_state = NAN_RANGING_ENABLE;
1263 req.sdea_params.range_report = NAN_ENABLE_RANGE_REPORT;
1264 }
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001265
Rakesh Sunkie6f66832017-05-16 15:22:48 -07001266 if (awake_dw_interval) {
1267 int input_dw_interval_val = atoi(awake_dw_interval);
1268 int awake_dw_int = 0;
1269
1270 if (input_dw_interval_val > NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL) {
1271 sigma_dut_print(dut, DUT_MSG_INFO,
1272 "%s: input active dw interval = %d overwritting dw interval to Max allowed dw interval 16",
1273 __func__, input_dw_interval_val);
1274 input_dw_interval_val =
1275 NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL;
1276 }
1277 sigma_dut_print(dut, DUT_MSG_INFO,
1278 "%s: input active DW interval = %d",
1279 __func__, input_dw_interval_val);
1280 /*
1281 * Indicates the interval for Sync beacons and SDF's in 2.4 GHz
1282 * or 5 GHz band. Valid values of DW Interval are: 1, 2, 3, 4,
1283 * and 5; 0 is reserved. The SDF includes in OTA when enabled.
1284 * The publish/subscribe period. values don't override the
1285 * device level configurations.
1286 * input_dw_interval_val is provided by the user are in the
1287 * format 2^n-1 = 1/2/4/8/16. Internal implementation expects n
1288 * to be passed to indicate the awake_dw_interval.
1289 */
1290 if (input_dw_interval_val == 1 ||
1291 input_dw_interval_val % 2 == 0) {
1292 while (input_dw_interval_val > 0) {
1293 input_dw_interval_val >>= 1;
1294 awake_dw_int++;
1295 }
1296 }
1297 sigma_dut_print(dut, DUT_MSG_INFO,
1298 "%s:converted active DW interval = %d",
1299 __func__, awake_dw_int);
1300 config_req.config_dw.config_2dot4g_dw_band = 1;
1301 config_req.config_dw.dw_2dot4g_interval_val = awake_dw_int;
1302 config_req.config_dw.config_5g_dw_band = 1;
1303 config_req.config_dw.dw_5g_interval_val = awake_dw_int;
1304 ret = nan_config_request(0, global_interface_handle,
1305 &config_req);
1306 if (ret != WIFI_SUCCESS) {
1307 sigma_dut_print(dut, DUT_MSG_ERROR,
1308 "%s:NAN config request failed",
1309 __func__);
1310 return -2;
1311 }
1312 }
1313
Rakesh Sunki8a4845d2017-05-16 15:27:13 -07001314#if NAN_CERT_VERSION >= 3
1315 if (qos_config)
1316 req.sdea_params.qos_cfg = (NanQosCfgStatus) atoi(qos_config);
1317#endif
1318
Rakesh Sunki107356c2017-03-30 14:47:55 -07001319 ret = nan_publish_request(0, global_interface_handle, &req);
1320 if (ret != WIFI_SUCCESS)
1321 send_resp(dut, conn, SIGMA_ERROR, "Unable to publish");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001322
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001323 if (ndp_enable)
1324 dut->ndp_enable = 1;
1325
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001326 return 0;
1327}
1328
1329
1330static int nan_further_availability_rx(struct sigma_dut *dut,
1331 struct sigma_conn *conn,
1332 struct sigma_cmd *cmd)
1333{
1334 const char *master_pref = get_param(cmd, "MasterPref");
1335 const char *rand_fac = get_param(cmd, "RandFactor");
1336 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001337 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001338 struct timespec abstime;
1339
1340 NanEnableRequest req;
1341
1342 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001343 req.cluster_low = 0;
1344 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001345 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001346
1347 if (master_pref)
1348 req.master_pref = strtoul(master_pref, NULL, 0);
1349
1350 if (rand_fac) {
1351 int rand_fac_val = strtoul(rand_fac, NULL, 0);
1352
1353 req.config_random_factor_force = 1;
1354 req.random_factor_force_val = rand_fac_val;
1355 }
1356
1357 if (hop_count) {
1358 int hop_count_val = strtoul(hop_count, NULL, 0);
1359
1360 req.config_hop_count_force = 1;
1361 req.hop_count_force_val = hop_count_val;
1362 }
1363
Rakesh Sunki107356c2017-03-30 14:47:55 -07001364 ret = nan_enable_request(0, global_interface_handle, &req);
1365 if (ret != WIFI_SUCCESS) {
1366 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
1367 return 0;
1368 }
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001369
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001370 abstime.tv_sec = 4;
1371 abstime.tv_nsec = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001372 wait(abstime);
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001373
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001374 return 0;
1375}
1376
1377
1378static int nan_further_availability_tx(struct sigma_dut *dut,
1379 struct sigma_conn *conn,
1380 struct sigma_cmd *cmd)
1381{
1382 const char *master_pref = get_param(cmd, "MasterPref");
1383 const char *rand_fac = get_param(cmd, "RandFactor");
1384 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001385 wifi_error ret;
1386
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001387 NanEnableRequest req;
1388 NanConfigRequest configReq;
1389
1390 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001391 req.cluster_low = 0;
1392 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001393 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001394
1395 if (master_pref)
1396 req.master_pref = strtoul(master_pref, NULL, 0);
1397
1398 if (rand_fac) {
1399 int rand_fac_val = strtoul(rand_fac, NULL, 0);
1400
1401 req.config_random_factor_force = 1;
1402 req.random_factor_force_val = rand_fac_val;
1403 }
1404
1405 if (hop_count) {
1406 int hop_count_val = strtoul(hop_count, NULL, 0);
1407
1408 req.config_hop_count_force = 1;
1409 req.hop_count_force_val = hop_count_val;
1410 }
1411
Rakesh Sunki107356c2017-03-30 14:47:55 -07001412 ret = nan_enable_request(0, global_interface_handle, &req);
1413 if (ret != WIFI_SUCCESS) {
1414 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
1415 return 0;
1416 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001417
1418 /* Start the config of fam */
1419
1420 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001421
1422 configReq.config_fam = 1;
1423 configReq.fam_val.numchans = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001424 configReq.fam_val.famchan[0].entry_control = 0;
1425 configReq.fam_val.famchan[0].class_val = 81;
1426 configReq.fam_val.famchan[0].channel = 6;
1427 configReq.fam_val.famchan[0].mapid = 0;
1428 configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe;
1429
Rakesh Sunki107356c2017-03-30 14:47:55 -07001430 ret = nan_config_request(0, global_interface_handle, &configReq);
1431 if (ret != WIFI_SUCCESS)
1432 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001433
1434 return 0;
1435}
1436
1437
1438int sigma_nan_transmit_followup(struct sigma_dut *dut,
1439 struct sigma_conn *conn,
1440 struct sigma_cmd *cmd)
1441{
1442 const char *mac = get_param(cmd, "mac");
1443 const char *requestor_id = get_param(cmd, "RemoteInstanceId");
1444 const char *local_id = get_param(cmd, "LocalInstanceId");
1445 const char *service_name = get_param(cmd, "servicename");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001446 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001447 NanTransmitFollowupRequest req;
1448
1449 memset(&req, 0, sizeof(NanTransmitFollowupRequest));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001450 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001451 req.addr[0] = 0xFF;
1452 req.addr[1] = 0xFF;
1453 req.addr[2] = 0xFF;
1454 req.addr[3] = 0xFF;
1455 req.addr[4] = 0xFF;
1456 req.addr[5] = 0xFF;
1457 req.priority = NAN_TX_PRIORITY_NORMAL;
1458 req.dw_or_faw = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001459
1460 if (service_name)
1461 req.service_specific_info_len = strlen(service_name);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001462
1463 if (requestor_id) {
1464 /* int requestor_id_val = atoi(requestor_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001465 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001466 }
1467 if (local_id) {
1468 /* int local_id_val = atoi(local_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001469 req.publish_subscribe_id = global_header_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001470 }
1471
1472 if (mac == NULL) {
1473 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address");
1474 return -1;
1475 }
1476 nan_parse_mac_address(dut, mac, req.addr);
1477
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001478 if (requestor_id)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001479 req.requestor_instance_id = strtoul(requestor_id, NULL, 0);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001480
Rakesh Sunki107356c2017-03-30 14:47:55 -07001481 ret = nan_transmit_followup_request(0, global_interface_handle, &req);
1482 if (ret != WIFI_SUCCESS) {
1483 send_resp(dut, conn, SIGMA_ERROR,
1484 "Unable to complete nan transmit followup");
1485 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001486
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001487 return 0;
1488}
1489
Rakesh Sunki107356c2017-03-30 14:47:55 -07001490
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001491/* NotifyResponse invoked to notify the status of the Request */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001492void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001493{
1494 sigma_dut_print(global_dut, DUT_MSG_INFO,
Rakesh Sunkifdbd60b2017-03-30 14:47:55 -07001495 "%s: status %d response_type %d",
1496 __func__, rsp_data->status, rsp_data->response_type);
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001497 if (rsp_data->response_type == NAN_RESPONSE_STATS &&
1498 rsp_data->body.stats_response.stats_type ==
1499 NAN_STATS_ID_DE_TIMING_SYNC) {
1500 NanSyncStats *pSyncStats;
1501
1502 sigma_dut_print(global_dut, DUT_MSG_INFO,
1503 "%s: stats_type %d", __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001504 rsp_data->body.stats_response.stats_type);
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001505 pSyncStats = &rsp_data->body.stats_response.data.sync_stats;
1506 memcpy(&global_nan_sync_stats, pSyncStats,
1507 sizeof(NanSyncStats));
1508 pthread_cond_signal(&gCondition);
Rakesh Sunki4d5912d2017-03-30 14:47:55 -07001509 } else if (rsp_data->response_type == NAN_RESPONSE_PUBLISH) {
1510 sigma_dut_print(global_dut, DUT_MSG_INFO,
1511 "%s: publish_id %d\n",
1512 __func__,
1513 rsp_data->body.publish_response.publish_id);
1514 global_publish_id = rsp_data->body.publish_response.publish_id;
1515 } else if (rsp_data->response_type == NAN_RESPONSE_SUBSCRIBE) {
1516 sigma_dut_print(global_dut, DUT_MSG_INFO,
1517 "%s: subscribe_id %d\n",
1518 __func__,
1519 rsp_data->body.subscribe_response.subscribe_id);
1520 global_subscribe_id =
1521 rsp_data->body.subscribe_response.subscribe_id;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001522 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001523}
1524
1525
1526/* Events Callback */
1527void nan_event_publish_replied(NanPublishRepliedInd *event)
1528{
1529 sigma_dut_print(global_dut, DUT_MSG_INFO,
1530 "%s: handle %d " MAC_ADDR_STR " rssi:%d",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001531 __func__, event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001532 MAC_ADDR_ARRAY(event->addr), event->rssi_value);
1533 event_anyresponse = 1;
1534 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001535 "EventName,Replied,RemoteInstanceID %d,mac," MAC_ADDR_STR,
1536 (event->requestor_instance_id >> 24),
1537 MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001538}
1539
1540
1541/* Events Callback */
1542void nan_event_publish_terminated(NanPublishTerminatedInd *event)
1543{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001544 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d",
1545 __func__, event->publish_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001546}
1547
1548
1549/* Events Callback */
1550void nan_event_match(NanMatchInd *event)
1551{
1552 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001553 "%s: Pub/Sub Id %d remote_requestor_id %08x "
1554 MAC_ADDR_STR
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001555 " rssi:%d",
1556 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001557 event->publish_subscribe_id,
1558 event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001559 MAC_ADDR_ARRAY(event->addr),
1560 event->rssi_value);
1561 event_anyresponse = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001562 global_header_handle = event->publish_subscribe_id;
1563 global_match_handle = event->requestor_instance_id;
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07001564 memcpy(global_peer_mac_addr, event->addr, sizeof(global_peer_mac_addr));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001565
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001566 /* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */
1567 /* global_pub_sub_handle = event->header.handle; */
1568 /* Print the SSI */
1569 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001570 nan_hex_dump(global_dut, event->service_specific_info,
1571 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001572 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1573 "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001574 MAC_ADDR_STR " ", (event->requestor_instance_id >> 24),
1575 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001576
1577 /* Print the match filter */
1578 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001579 nan_hex_dump(global_dut, event->sdf_match_filter,
1580 event->sdf_match_filter_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001581
1582 /* Print the conn_capability */
1583 sigma_dut_print(global_dut, DUT_MSG_INFO,
1584 "Printing PostConnectivity Capability");
1585 if (event->is_conn_capability_valid) {
1586 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s",
1587 event->conn_capability.is_wfd_supported ?
1588 "yes" : "no");
1589 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s",
1590 (event->conn_capability.is_wfds_supported ?
1591 "yes" : "no"));
1592 sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s",
1593 (event->conn_capability.is_tdls_supported ?
1594 "yes" : "no"));
1595 sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s",
1596 (event->conn_capability.is_ibss_supported ?
1597 "yes" : "no"));
1598 sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s",
1599 (event->conn_capability.is_mesh_supported ?
1600 "yes" : "no"));
1601 sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d",
1602 event->conn_capability.wlan_infra_field);
1603 } else {
1604 sigma_dut_print(global_dut, DUT_MSG_INFO,
1605 "PostConnectivity Capability not present");
1606 }
1607
1608 /* Print the discovery_attr */
1609 sigma_dut_print(global_dut, DUT_MSG_INFO,
1610 "Printing PostDiscovery Attribute");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001611 if (event->num_rx_discovery_attr) {
1612 int idx;
1613
1614 for (idx = 0; idx < event->num_rx_discovery_attr; idx++) {
1615 sigma_dut_print(global_dut, DUT_MSG_INFO,
1616 "PostDiscovery Attribute - %d", idx);
1617 sigma_dut_print(global_dut, DUT_MSG_INFO,
1618 "Conn Type:%d Device Role:%d"
1619 MAC_ADDR_STR,
1620 event->discovery_attr[idx].type,
1621 event->discovery_attr[idx].role,
1622 MAC_ADDR_ARRAY(event->discovery_attr[idx].addr));
1623 sigma_dut_print(global_dut, DUT_MSG_INFO,
1624 "Duration:%d MapId:%d "
1625 "avail_interval_bitmap:%04x",
1626 event->discovery_attr[idx].duration,
1627 event->discovery_attr[idx].mapid,
1628 event->discovery_attr[idx].avail_interval_bitmap);
1629 sigma_dut_print(global_dut, DUT_MSG_INFO,
1630 "Printing Mesh Id:");
1631 nan_hex_dump(global_dut,
1632 event->discovery_attr[idx].mesh_id,
1633 event->discovery_attr[idx].mesh_id_len);
1634 sigma_dut_print(global_dut, DUT_MSG_INFO,
1635 "Printing Infrastructure Ssid:");
1636 nan_hex_dump(global_dut,
1637 event->discovery_attr[idx].infrastructure_ssid_val,
1638 event->discovery_attr[idx].infrastructure_ssid_len);
1639 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001640 } else {
1641 sigma_dut_print(global_dut, DUT_MSG_INFO,
1642 "PostDiscovery attribute not present");
1643 }
1644
1645 /* Print the fam */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001646 if (event->num_chans) {
1647 nan_print_further_availability_chan(global_dut,
1648 event->num_chans,
1649 &event->famchan[0]);
1650 } else {
1651 sigma_dut_print(global_dut, DUT_MSG_INFO,
1652 "Further Availability Map not present");
1653 }
1654 if (event->cluster_attribute_len) {
1655 sigma_dut_print(global_dut, DUT_MSG_INFO,
1656 "Printing Cluster Attribute:");
1657 nan_hex_dump(global_dut, event->cluster_attribute,
1658 event->cluster_attribute_len);
1659 } else {
1660 sigma_dut_print(global_dut, DUT_MSG_INFO,
1661 "Cluster Attribute not present");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001662 }
1663}
1664
1665
1666/* Events Callback */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001667void nan_event_match_expired(NanMatchExpiredInd *event)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001668{
1669 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001670 "%s: publish_subscribe_id %d match_handle %08x",
1671 __func__, event->publish_subscribe_id,
1672 event->requestor_instance_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001673}
1674
1675
1676/* Events Callback */
1677void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event)
1678{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001679 sigma_dut_print(global_dut, DUT_MSG_INFO,
1680 "%s: Subscribe Id %d reason %d",
1681 __func__, event->subscribe_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001682}
1683
1684
1685/* Events Callback */
1686void nan_event_followup(NanFollowupInd *event)
1687{
1688 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001689 "%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d "
1690 MAC_ADDR_STR, __func__, event->publish_subscribe_id,
1691 event->requestor_instance_id, event->dw_or_faw,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001692 MAC_ADDR_ARRAY(event->addr));
1693
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001694 global_match_handle = event->publish_subscribe_id;
1695 global_header_handle = event->requestor_instance_id;
1696 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__);
1697 nan_hex_dump(global_dut, event->service_specific_info,
1698 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001699 event_anyresponse = 1;
1700 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1701 "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001702 MAC_ADDR_STR " ", event->requestor_instance_id >> 24,
1703 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001704}
1705
1706
1707/* Events Callback */
1708void nan_event_disceng_event(NanDiscEngEventInd *event)
1709{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001710 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d",
1711 __func__, event->event_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001712
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001713 if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001714 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster "
1715 MAC_ADDR_STR,
1716 __func__,
1717 MAC_ADDR_ARRAY(event->data.cluster.addr));
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001718 /* To ensure sta_get_events to get the events
1719 * only after joining the NAN cluster. */
1720 pthread_cond_signal(&gCondition);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001721 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001722 if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001723 sigma_dut_print(global_dut, DUT_MSG_INFO,
1724 "%s: Started cluster " MAC_ADDR_STR,
1725 __func__,
1726 MAC_ADDR_ARRAY(event->data.cluster.addr));
1727 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001728 if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) {
1729 sigma_dut_print(global_dut, DUT_MSG_INFO,
1730 "%s: Discovery Mac Address "
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001731 MAC_ADDR_STR,
1732 __func__,
1733 MAC_ADDR_ARRAY(event->data.mac_addr.addr));
1734 memcpy(global_nan_mac_addr, event->data.mac_addr.addr,
1735 sizeof(global_nan_mac_addr));
1736 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001737}
1738
1739
1740/* Events Callback */
1741void nan_event_disabled(NanDisabledInd *event)
1742{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001743 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d",
1744 __func__, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001745 /* pthread_cond_signal(&gCondition); */
1746}
1747
1748
Rakesh Sunki4c086672017-03-30 14:47:55 -07001749/* Events callback */
1750static void ndp_event_data_indication(NanDataPathRequestInd *event)
1751{
1752 sigma_dut_print(global_dut, DUT_MSG_INFO,
1753 "%s: Service Instance Id: %d Peer Discovery MAC ADDR "
1754 MAC_ADDR_STR
1755 " NDP Instance Id: %d App Info len %d App Info %s",
1756 __func__,
1757 event->service_instance_id,
1758 MAC_ADDR_ARRAY(event->peer_disc_mac_addr),
1759 event->ndp_instance_id,
1760 event->app_info.ndp_app_info_len,
1761 event->app_info.ndp_app_info);
1762
1763 global_ndp_instance_id = event->ndp_instance_id;
1764}
1765
1766
1767/* Events callback */
1768static void ndp_event_data_confirm(NanDataPathConfirmInd *event)
1769{
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07001770 char cmd[200];
1771 char ipv6_buf[100];
1772
Rakesh Sunki4c086672017-03-30 14:47:55 -07001773 sigma_dut_print(global_dut, DUT_MSG_INFO,
1774 "Received NDP Confirm Indication");
1775
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07001776 memset(cmd, 0, sizeof(cmd));
1777 memset(ipv6_buf, 0, sizeof(ipv6_buf));
1778
Rakesh Sunki4c086672017-03-30 14:47:55 -07001779 global_ndp_instance_id = event->ndp_instance_id;
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07001780
1781 if (event->rsp_code == NAN_DP_REQUEST_ACCEPT) {
1782 if (system("ifconfig nan0 up") != 0) {
1783 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1784 "Failed to set nan interface up");
1785 return;
1786 }
1787 if (system("ip -6 route add fe80::/64 dev nan0 table local") !=
1788 0) {
1789 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1790 "Failed to run:ip -6 route replace fe80::/64 dev nan0 table local");
1791 }
1792 convert_mac_addr_to_ipv6_lladdr(event->peer_ndi_mac_addr,
1793 ipv6_buf, sizeof(ipv6_buf));
1794 snprintf(cmd, sizeof(cmd),
1795 "ip -6 neighbor replace %s lladdr %02x:%02x:%02x:%02x:%02x:%02x nud permanent dev nan0",
1796 ipv6_buf, event->peer_ndi_mac_addr[0],
1797 event->peer_ndi_mac_addr[1],
1798 event->peer_ndi_mac_addr[2],
1799 event->peer_ndi_mac_addr[3],
1800 event->peer_ndi_mac_addr[4],
1801 event->peer_ndi_mac_addr[5]);
1802 sigma_dut_print(global_dut, DUT_MSG_INFO,
1803 "neighbor replace cmd = %s", cmd);
1804 if (system(cmd) != 0) {
1805 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1806 "Failed to run: ip -6 neighbor replace");
1807 return;
1808 }
Rakesh Sunki4c086672017-03-30 14:47:55 -07001809 }
1810}
1811
1812
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001813void * my_thread_function(void *ptr)
1814{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001815 wifi_event_loop(global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001816 pthread_exit(0);
1817 return (void *) NULL;
1818}
1819
1820
1821static NanCallbackHandler callbackHandler = {
1822 .NotifyResponse = nan_notify_response,
1823 .EventPublishReplied = nan_event_publish_replied,
1824 .EventPublishTerminated = nan_event_publish_terminated,
1825 .EventMatch = nan_event_match,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001826 .EventMatchExpired = nan_event_match_expired,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001827 .EventSubscribeTerminated = nan_event_subscribe_terminated,
1828 .EventFollowup = nan_event_followup,
1829 .EventDiscEngEvent = nan_event_disceng_event,
1830 .EventDisabled = nan_event_disabled,
Rakesh Sunki4c086672017-03-30 14:47:55 -07001831 .EventDataRequest = ndp_event_data_indication,
1832 .EventDataConfirm = ndp_event_data_confirm,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001833};
1834
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001835
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001836void nan_init(struct sigma_dut *dut)
1837{
1838 pthread_t thread1; /* thread variables */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001839 wifi_error err = wifi_initialize(&global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001840
1841 if (err) {
1842 printf("wifi hal initialize failed\n");
1843 return;
1844 }
1845
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001846 global_interface_handle = wifi_get_iface_handle(global_wifi_handle,
1847 (char *) "wlan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001848 /* create threads 1 */
1849 pthread_create(&thread1, NULL, &my_thread_function, NULL);
1850
1851 pthread_mutex_init(&gMutex, NULL);
1852 pthread_cond_init(&gCondition, NULL);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001853 if (global_interface_handle)
1854 nan_register_handler(global_interface_handle, callbackHandler);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001855}
1856
1857
1858void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1859 struct sigma_cmd *cmd)
1860{
1861 sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default");
1862
1863 if (nan_state == 0) {
1864 nan_init(dut);
1865 nan_state = 1;
1866 }
1867 is_fam = 0;
1868 event_anyresponse = 0;
1869 global_dut = dut;
Rakesh Sunki7d37f412017-03-30 14:47:55 -07001870 memset(&dut->nan_pmk[0], 0, NAN_PMK_INFO_LEN);
1871 dut->nan_pmk_len = 0;
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001872 dut->sta_channel = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001873 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001874 memset(&global_nan_sync_stats, 0, sizeof(global_nan_sync_stats));
Rakesh Sunki42363682017-05-16 15:00:42 -07001875 memset(global_publish_service_name, 0,
1876 sizeof(global_publish_service_name));
1877 global_publish_service_name_len = 0;
1878 global_publish_id = 0;
Rakesh Sunki0262cb52017-05-17 14:22:05 -07001879 global_subscribe_id = 0;
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001880
Rakesh Sunki8a630b82017-03-30 14:47:55 -07001881 sigma_nan_data_end(dut, cmd);
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001882 nan_data_interface_delete(0, global_interface_handle, (char *) "nan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001883 sigma_nan_disable(dut, conn, cmd);
1884}
1885
1886
1887int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1888 struct sigma_cmd *cmd)
1889{
1890 const char *program = get_param(cmd, "Prog");
1891 const char *nan_op = get_param(cmd, "NANOp");
1892 const char *method_type = get_param(cmd, "MethodType");
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001893 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001894 char resp_buf[100];
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001895 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001896
1897 if (program == NULL)
1898 return -1;
1899
1900 if (strcasecmp(program, "NAN") != 0) {
1901 send_resp(dut, conn, SIGMA_ERROR,
1902 "ErrorCode,Unsupported program");
1903 return 0;
1904 }
1905
1906 if (nan_op) {
1907 /*
1908 * NANOp has been specified.
1909 * We will build a nan_enable or nan_disable command.
1910 */
1911 if (strcasecmp(nan_op, "On") == 0) {
1912 if (sigma_nan_enable(dut, conn, cmd) == 0) {
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001913 ret = nan_data_interface_create(
1914 0, global_interface_handle,
1915 (char *) "nan0");
1916 if (ret != WIFI_SUCCESS) {
1917 sigma_dut_print(
1918 global_dut, DUT_MSG_ERROR,
1919 "Unable to create NAN data interface");
1920 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001921 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1922 MAC_ADDR_STR,
1923 MAC_ADDR_ARRAY(global_nan_mac_addr));
1924 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1925 } else {
1926 send_resp(dut, conn, SIGMA_ERROR,
1927 "NAN_ENABLE_FAILED");
1928 return -1;
1929 }
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001930
1931 if (band && strcasecmp(band, "24g") == 0) {
1932 sigma_dut_print(dut, DUT_MSG_INFO,
1933 "%s: Setting band to 2G Only",
1934 __func__);
1935 sigma_ndp_configure_band(
1936 dut, conn, cmd,
1937 NAN_DATA_PATH_SUPPORTED_BAND_2G);
1938 } else if (band && dut->sta_channel > 12) {
1939 sigma_ndp_configure_band(
1940 dut, conn, cmd,
1941 NAN_DATA_PATH_SUPPORT_DUAL_BAND);
1942 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001943 } else if (strcasecmp(nan_op, "Off") == 0) {
1944 sigma_nan_disable(dut, conn, cmd);
Rakesh Sunki42363682017-05-16 15:00:42 -07001945 memset(global_publish_service_name, 0,
1946 sizeof(global_publish_service_name));
1947 global_publish_service_name_len = 0;
1948 global_publish_id = 0;
Rakesh Sunki0262cb52017-05-17 14:22:05 -07001949 global_subscribe_id = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001950 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1951 }
1952 }
1953 if (nan_state && nan_op == NULL) {
1954 if (method_type) {
1955 if (strcasecmp(method_type, "Publish") == 0) {
1956 sigma_nan_publish_request(dut, conn, cmd);
1957 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1958 }
1959 if (strcasecmp(method_type, "Subscribe") == 0) {
1960 sigma_nan_subscribe_request(dut, conn, cmd);
1961 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1962 }
1963 if (strcasecmp(method_type, "Followup") == 0) {
1964 sigma_nan_transmit_followup(dut, conn, cmd);
1965 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1966 }
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07001967 if (strcasecmp(method_type, "DataRequest") == 0) {
1968 sigma_nan_data_request(dut, conn, cmd);
1969 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1970 }
Rakesh Sunkia5cc2842017-03-30 14:47:55 -07001971 if (strcasecmp(method_type, "DataResponse") == 0) {
1972 sigma_dut_print(dut, DUT_MSG_INFO,
1973 "%s: method_type is DataResponse",
1974 __func__);
1975 sigma_nan_data_response(dut, conn, cmd);
1976 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1977 }
Rakesh Sunki8a630b82017-03-30 14:47:55 -07001978 if (strcasecmp(method_type, "DataEnd") == 0) {
1979 sigma_nan_data_end(dut, cmd);
1980 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1981 }
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -07001982 if (strcasecmp(method_type, "rangerequest") == 0) {
1983 sigma_dut_print(dut, DUT_MSG_INFO,
1984 "%s: method_type is rangerequest",
1985 __func__);
1986 sigma_nan_range_request(dut, cmd);
1987 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1988 }
1989 if (strcasecmp(method_type, "cancelrange") == 0) {
1990 sigma_dut_print(dut, DUT_MSG_INFO,
1991 "%s: method_type is cancelrange",
1992 __func__);
1993 sigma_nan_cancel_range(dut, cmd);
1994 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1995 }
Rakesh Sunkib2b65162017-03-30 14:47:55 -07001996 if (strcasecmp(method_type, "SchedUpdate") == 0) {
1997 sigma_dut_print(dut, DUT_MSG_INFO,
1998 "%s: method_type is SchedUpdate",
1999 __func__);
2000 sigma_nan_schedule_update(dut, cmd);
2001 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2002 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002003 } else {
2004 sigma_nan_config_enable(dut, conn, cmd);
2005 snprintf(resp_buf, sizeof(resp_buf), "mac,"
2006 MAC_ADDR_STR,
2007 MAC_ADDR_ARRAY(global_nan_mac_addr));
2008 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
2009 }
2010 }
2011
2012 return 0;
2013}
2014
2015
2016int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
2017 struct sigma_cmd *cmd)
2018{
2019
2020 const char *program = get_param(cmd, "Program");
2021 const char *parameter = get_param(cmd, "Parameter");
2022 char resp_buf[100];
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002023 NanStatsRequest req;
2024 struct timespec abstime;
2025 u64 master_rank;
2026 u8 master_pref;
2027 u8 random_factor;
2028 u8 hop_count;
2029 u32 beacon_transmit_time;
2030 u32 ndp_channel_freq;
2031 u32 ndp_channel_freq2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002032
2033 if (program == NULL) {
2034 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name");
2035 return -1;
2036 }
2037 if (strcasecmp(program, "NAN") != 0) {
2038 send_resp(dut, conn, SIGMA_ERROR,
2039 "ErrorCode,Unsupported program");
2040 return 0;
2041 }
2042
2043 if (parameter == NULL) {
2044 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter");
2045 return -1;
2046 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002047
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002048 memset(&req, 0, sizeof(NanStatsRequest));
2049 req.stats_type = (NanStatsType) NAN_STATS_ID_DE_TIMING_SYNC;
2050 nan_stats_request(0, global_interface_handle, &req);
2051 /*
2052 * To ensure sta_get_events to get the events
2053 * only after joining the NAN cluster
2054 */
2055 abstime.tv_sec = 4;
2056 abstime.tv_nsec = 0;
2057 wait(abstime);
2058
2059 master_rank = global_nan_sync_stats.myRank;
2060 master_pref = (global_nan_sync_stats.myRank & 0xFF00000000000000) >> 56;
2061 random_factor = (global_nan_sync_stats.myRank & 0x00FF000000000000) >>
2062 48;
2063 hop_count = global_nan_sync_stats.currAmHopCount;
2064 beacon_transmit_time = global_nan_sync_stats.currAmBTT;
2065 ndp_channel_freq = global_nan_sync_stats.ndpChannelFreq;
2066 ndp_channel_freq2 = global_nan_sync_stats.ndpChannelFreq2;
2067
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002068 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002069 "%s: NanStatsRequest Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d ndp_channel_freq:%d ndp_channel_freq2:%d",
2070 __func__, master_pref, random_factor,
2071 hop_count, beacon_transmit_time,
2072 ndp_channel_freq, ndp_channel_freq2);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002073
2074 if (strcasecmp(parameter, "MasterPref") == 0) {
2075 snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002076 master_pref);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002077 } else if (strcasecmp(parameter, "MasterRank") == 0) {
2078 snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002079 master_rank);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002080 } else if (strcasecmp(parameter, "RandFactor") == 0) {
2081 snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002082 random_factor);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002083 } else if (strcasecmp(parameter, "HopCount") == 0) {
2084 snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002085 hop_count);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002086 } else if (strcasecmp(parameter, "BeaconTransTime") == 0) {
2087 snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002088 beacon_transmit_time);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002089 } else if (strcasecmp(parameter, "NANStatus") == 0) {
2090 if (nan_state == 1)
2091 snprintf(resp_buf, sizeof(resp_buf), "On");
2092 else
2093 snprintf(resp_buf, sizeof(resp_buf), "Off");
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002094 } else if (strcasecmp(parameter, "NDPChannel") == 0) {
2095 if (ndp_channel_freq != 0 && ndp_channel_freq2 != 0) {
2096 snprintf(resp_buf, sizeof(resp_buf),
2097 "ndpchannel,%d,ndpchannel,%d",
2098 freq_to_channel(ndp_channel_freq),
2099 freq_to_channel(ndp_channel_freq2));
2100 } else if (ndp_channel_freq != 0) {
2101 snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
2102 freq_to_channel(ndp_channel_freq));
2103 } else if (ndp_channel_freq2 != 0) {
2104 snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
2105 freq_to_channel(ndp_channel_freq2));
2106 } else {
2107 sigma_dut_print(dut, DUT_MSG_ERROR,
2108 "%s: No Negotiated NDP Channels", __func__);
2109 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002110 } else {
2111 send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
2112 return 0;
2113 }
2114
2115 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
2116 return 0;
2117}
2118
2119
2120int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
2121 struct sigma_cmd *cmd)
2122{
2123 const char *action = get_param(cmd, "Action");
2124
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07002125 if (!action)
2126 return 0;
2127
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002128 /* Check action for start, stop and get events. */
2129 if (strcasecmp(action, "Start") == 0) {
2130 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
2131 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
2132 } else if (strcasecmp(action, "Stop") == 0) {
2133 event_anyresponse = 0;
2134 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
2135 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
2136 } else if (strcasecmp(action, "Get") == 0) {
2137 if (event_anyresponse == 1) {
2138 send_resp(dut, conn, SIGMA_COMPLETE,
2139 global_event_resp_buf);
2140 } else {
2141 send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE");
2142 }
2143 }
2144 return 0;
2145}
Rakesh Sunki4b75f962017-03-30 14:47:55 -07002146
2147#else /* #if NAN_CERT_VERSION */
2148
2149int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
2150 struct sigma_conn *conn,
2151 struct sigma_cmd *cmd)
2152{
2153 return 1;
2154}
2155
2156
2157int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
2158 struct sigma_cmd *cmd)
2159{
2160 return 0;
2161
2162}
2163
2164
2165void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
2166 struct sigma_cmd *cmd)
2167{
2168 return;
2169}
2170
2171
2172int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
2173 struct sigma_cmd *cmd)
2174{
2175 return 0;
2176}
2177
2178
2179int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
2180 struct sigma_cmd *cmd)
2181{
2182 return 0;
2183}
2184
2185#endif /* #if NAN_CERT_VERSION */