xref: /wlan-dirver/utils/sigma-dut/nan.c (revision 6734e239599e35849543fd5a45d543b254df7d20)
1 /*
2  * Sigma Control API DUT (NAN functionality)
3  * Copyright (c) 2014-2017, Qualcomm Atheros, Inc.
4  * 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"
13 #include "nan_cert.h"
14 
15 #if NAN_CERT_VERSION >= 2
16 
17 pthread_cond_t gCondition;
18 pthread_mutex_t gMutex;
19 wifi_handle global_wifi_handle;
20 wifi_interface_handle global_interface_handle;
21 static NanSyncStats global_nan_sync_stats;
22 static int nan_state = 0;
23 static int event_anyresponse = 0;
24 static int is_fam = 0;
25 
26 static uint16_t global_ndp_instance_id = 0;
27 static uint16_t global_publish_id = 0;
28 static uint16_t global_subscribe_id = 0;
29 uint16_t global_header_handle = 0;
30 uint32_t global_match_handle = 0;
31 
32 #define DEFAULT_SVC "QNanCluster"
33 #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 
39 struct sigma_dut *global_dut = NULL;
40 static char global_nan_mac_addr[ETH_ALEN];
41 static char global_peer_mac_addr[ETH_ALEN];
42 static char global_event_resp_buf[1024];
43 static u8 global_publish_service_name[NAN_MAX_SERVICE_NAME_LEN];
44 static u32 global_publish_service_name_len = 0;
45 static u8 global_subscribe_service_name[NAN_MAX_SERVICE_NAME_LEN];
46 static u32 global_subscribe_service_name_len = 0;
47 
48 static int nan_further_availability_tx(struct sigma_dut *dut,
49 				       struct sigma_conn *conn,
50 				       struct sigma_cmd *cmd);
51 static int nan_further_availability_rx(struct sigma_dut *dut,
52 				       struct sigma_conn *conn,
53 				       struct sigma_cmd *cmd);
54 
55 
56 void nan_hex_dump(struct sigma_dut *dut, uint8_t *data, size_t len)
57 {
58 	char buf[512];
59 	uint16_t index;
60 	uint8_t *ptr;
61 	int pos;
62 
63 	memset(buf, 0, sizeof(buf));
64 	ptr = data;
65 	pos = 0;
66 	for (index = 0; index < len; index++) {
67 		pos += snprintf(&(buf[pos]), sizeof(buf) - pos,
68 				"%02x ", *ptr++);
69 		if (pos > 508)
70 			break;
71 	}
72 	sigma_dut_print(dut, DUT_MSG_INFO, "HEXDUMP len=[%d]", (int) len);
73 	sigma_dut_print(dut, DUT_MSG_INFO, "buf:%s", buf);
74 }
75 
76 
77 int nan_parse_hex(unsigned char c)
78 {
79 	if (c >= '0' && c <= '9')
80 		return c - '0';
81 	if (c >= 'a' && c <= 'f')
82 		return c - 'a' + 10;
83 	if (c >= 'A' && c <= 'F')
84 		return c - 'A' + 10;
85 	return 0;
86 }
87 
88 
89 int nan_parse_token(const char *tokenIn, u8 *tokenOut, int *filterLen)
90 {
91 	int total_len = 0, len = 0;
92 	char *saveptr = NULL;
93 
94 	tokenIn = strtok_r((char *) tokenIn, ":", &saveptr);
95 	while (tokenIn != NULL) {
96 		len = strlen(tokenIn);
97 		if (len == 1 && *tokenIn == '*')
98 			len = 0;
99 		tokenOut[total_len++] = (u8) len;
100 		if (len != 0)
101 			memcpy((u8 *) tokenOut + total_len, tokenIn, len);
102 		total_len += len;
103 		tokenIn = strtok_r(NULL, ":", &saveptr);
104 	}
105 	*filterLen = total_len;
106 	return 0;
107 }
108 
109 
110 int nan_parse_mac_address(struct sigma_dut *dut, const char *arg, u8 *addr)
111 {
112 	if (strlen(arg) != 17) {
113 		sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid mac address %s",
114 				arg);
115 		sigma_dut_print(dut, DUT_MSG_ERROR,
116 				"expected format xx:xx:xx:xx:xx:xx");
117 		return -1;
118 	}
119 
120 	addr[0] = nan_parse_hex(arg[0]) << 4 | nan_parse_hex(arg[1]);
121 	addr[1] = nan_parse_hex(arg[3]) << 4 | nan_parse_hex(arg[4]);
122 	addr[2] = nan_parse_hex(arg[6]) << 4 | nan_parse_hex(arg[7]);
123 	addr[3] = nan_parse_hex(arg[9]) << 4 | nan_parse_hex(arg[10]);
124 	addr[4] = nan_parse_hex(arg[12]) << 4 | nan_parse_hex(arg[13]);
125 	addr[5] = nan_parse_hex(arg[15]) << 4 | nan_parse_hex(arg[16]);
126 
127 	return 0;
128 }
129 
130 
131 int nan_parse_mac_address_list(struct sigma_dut *dut, const char *input,
132 			       u8 *output, u16 max_addr_allowed)
133 {
134 	/*
135 	 * Reads a list of mac address separated by space. Each MAC address
136 	 * should have the format of aa:bb:cc:dd:ee:ff.
137 	 */
138 	char *saveptr;
139 	char *token;
140 	int i = 0;
141 
142 	for (i = 0; i < max_addr_allowed; i++) {
143 		token = strtok_r((i == 0) ? (char *) input : NULL,
144 				 " ", &saveptr);
145 		if (token) {
146 			nan_parse_mac_address(dut, token, output);
147 			output += NAN_MAC_ADDR_LEN;
148 		} else
149 			break;
150 	}
151 
152 	sigma_dut_print(dut, DUT_MSG_INFO, "Num MacAddress:%d", i);
153 
154 	return i;
155 }
156 
157 
158 int nan_parse_hex_string(struct sigma_dut *dut, const char *input,
159 			 u8 *output, int *outputlen)
160 {
161 	int i = 0;
162 	int j = 0;
163 
164 	for (i = 0; i < (int) strlen(input) && j < *outputlen; i += 2) {
165 		output[j] = nan_parse_hex(input[i]);
166 		if (i + 1 < (int) strlen(input)) {
167 			output[j] = ((output[j] << 4) |
168 				     nan_parse_hex(input[i + 1]));
169 		}
170 		j++;
171 	}
172 	*outputlen = j;
173 	sigma_dut_print(dut, DUT_MSG_INFO, "Input:%s inputlen:%d outputlen:%d",
174 			input, (int) strlen(input), (int) *outputlen);
175 	return 0;
176 }
177 
178 
179 int wait(struct timespec abstime)
180 {
181 	struct timeval now;
182 
183 	gettimeofday(&now, NULL);
184 
185 	abstime.tv_sec += now.tv_sec;
186 	if (((abstime.tv_nsec + now.tv_usec * 1000) > 1000 * 1000 * 1000) ||
187 	    (abstime.tv_nsec + now.tv_usec * 1000 < 0)) {
188 		abstime.tv_sec += 1;
189 		abstime.tv_nsec += now.tv_usec * 1000;
190 		abstime.tv_nsec -= 1000 * 1000 * 1000;
191 	} else {
192 		abstime.tv_nsec  += now.tv_usec * 1000;
193 	}
194 
195 	return pthread_cond_timedwait(&gCondition, &gMutex, &abstime);
196 }
197 
198 
199 int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
200 				      struct sigma_conn *conn,
201 				      struct sigma_cmd *cmd)
202 {
203 	const char *oper_chan = get_param(cmd, "oper_chn");
204 	const char *pmk = get_param(cmd, "PMK");
205 
206 	if (oper_chan) {
207 		sigma_dut_print(dut, DUT_MSG_INFO, "Operating Channel: %s",
208 				oper_chan);
209 		dut->sta_channel = atoi(oper_chan);
210 	}
211 
212 	if (pmk) {
213 		int pmk_len;
214 
215 		sigma_dut_print(dut, DUT_MSG_INFO, "%s given string pmk: %s",
216 				__func__, pmk);
217 		memset(dut->nan_pmk, 0, NAN_PMK_INFO_LEN);
218 		dut->nan_pmk_len = 0;
219 		pmk_len = NAN_PMK_INFO_LEN;
220 		nan_parse_hex_string(dut, &pmk[2], &dut->nan_pmk[0], &pmk_len);
221 		dut->nan_pmk_len = pmk_len;
222 		sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
223 				__func__, dut->nan_pmk_len);
224 		sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex pmk", __func__);
225 		nan_hex_dump(dut, &dut->nan_pmk[0], dut->nan_pmk_len);
226 	}
227 
228 	send_resp(dut, conn, SIGMA_COMPLETE, NULL);
229 	return 0;
230 }
231 
232 
233 void nan_print_further_availability_chan(struct sigma_dut *dut,
234 					 u8 num_chans,
235 					 NanFurtherAvailabilityChannel *fachan)
236 {
237 	int idx;
238 
239 	sigma_dut_print(dut, DUT_MSG_INFO,
240 			"********Printing FurtherAvailabilityChan Info******");
241 	sigma_dut_print(dut, DUT_MSG_INFO, "Numchans:%d", num_chans);
242 	for (idx = 0; idx < num_chans; idx++) {
243 		sigma_dut_print(dut, DUT_MSG_INFO,
244 				"[%d]: NanAvailDuration:%d class_val:%02x channel:%d",
245 				idx, fachan->entry_control,
246 				fachan->class_val, fachan->channel);
247 		sigma_dut_print(dut, DUT_MSG_INFO,
248 				"[%d]: mapid:%d Availability bitmap:%08x",
249 				idx, fachan->mapid,
250 				fachan->avail_interval_bitmap);
251 	}
252 	sigma_dut_print(dut, DUT_MSG_INFO,
253 			"*********************Done**********************");
254 }
255 
256 
257 int sigma_nan_enable(struct sigma_dut *dut, struct sigma_conn *conn,
258 		     struct sigma_cmd *cmd)
259 {
260 	const char *master_pref = get_param(cmd, "MasterPref");
261 	const char *rand_fac = get_param(cmd, "RandFactor");
262 	const char *hop_count = get_param(cmd, "HopCount");
263 	const char *high_tsf = get_param(cmd, "HighTSF");
264 	const char *sdftx_band = get_param(cmd, "SDFTxBand");
265 	const char *oper_chan = get_param(cmd, "oper_chn");
266 	const char *further_avail_ind = get_param(cmd, "FurtherAvailInd");
267 	const char *band = get_param(cmd, "Band");
268 	const char *only_5g = get_param(cmd, "5GOnly");
269 	const char *nan_availability = get_param(cmd, "NANAvailability");
270 	struct timespec abstime;
271 	NanEnableRequest req;
272 
273 	memset(&req, 0, sizeof(NanEnableRequest));
274 	req.cluster_low = 0;
275 	req.cluster_high = 0xFFFF;
276 	req.master_pref = 100;
277 
278 	/* This is a debug hack to beacon in channel 11 */
279 	if (oper_chan) {
280 		req.config_2dot4g_support = 1;
281 		req.support_2dot4g_val = 111;
282 	}
283 
284 	if (master_pref) {
285 		int master_pref_val = strtoul(master_pref, NULL, 0);
286 
287 		req.master_pref = master_pref_val;
288 	}
289 
290 	if (rand_fac) {
291 		int rand_fac_val = strtoul(rand_fac, NULL, 0);
292 
293 		req.config_random_factor_force = 1;
294 		req.random_factor_force_val = rand_fac_val;
295 	}
296 
297 	if (hop_count) {
298 		int hop_count_val = strtoul(hop_count, NULL, 0);
299 
300 		req.config_hop_count_force = 1;
301 		req.hop_count_force_val = hop_count_val;
302 	}
303 
304 	if (sdftx_band) {
305 		if (strcasecmp(sdftx_band, "5G") == 0) {
306 			req.config_2dot4g_support = 1;
307 			req.support_2dot4g_val = 0;
308 		}
309 	}
310 
311 	sigma_dut_print(dut, DUT_MSG_INFO,
312 			"%s: Setting dual band 2.4 GHz and 5 GHz by default",
313 			__func__);
314 	/* Enable 2.4 GHz support */
315 	req.config_2dot4g_support = 1;
316 	req.support_2dot4g_val = 1;
317 	req.config_2dot4g_beacons = 1;
318 	req.beacon_2dot4g_val = 1;
319 	req.config_2dot4g_sdf = 1;
320 	req.sdf_2dot4g_val = 1;
321 
322 	/* Enable 5 GHz support */
323 	req.config_support_5g = 1;
324 	req.support_5g_val = 1;
325 	req.config_5g_beacons = 1;
326 	req.beacon_5g_val = 1;
327 	req.config_5g_sdf = 1;
328 	req.sdf_5g_val = 1;
329 
330 	if (band) {
331 		if (strcasecmp(band, "24G") == 0) {
332 			sigma_dut_print(dut, DUT_MSG_INFO,
333 					"Band 2.4 GHz selected, disable 5 GHz");
334 			/* Disable 5G support */
335 			req.config_support_5g = 1;
336 			req.support_5g_val = 0;
337 			req.config_5g_beacons = 1;
338 			req.beacon_5g_val = 0;
339 			req.config_5g_sdf = 1;
340 			req.sdf_5g_val = 0;
341 		}
342 	}
343 
344 	if (further_avail_ind) {
345 		sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled");
346 		if (strcasecmp(further_avail_ind, "tx") == 0) {
347 			is_fam = 1;
348 			nan_further_availability_tx(dut, conn, cmd);
349 			return 0;
350 		} else if (strcasecmp(further_avail_ind, "rx") == 0) {
351 			nan_further_availability_rx(dut, conn, cmd);
352 			return 0;
353 		}
354 	}
355 
356 	if (only_5g && atoi(only_5g)) {
357 		sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled");
358 		req.config_2dot4g_support = 1;
359 		req.support_2dot4g_val = 1;
360 		req.config_2dot4g_beacons = 1;
361 		req.beacon_2dot4g_val = 0;
362 		req.config_2dot4g_sdf = 1;
363 		req.sdf_2dot4g_val = 1;
364 	}
365 
366 	nan_enable_request(0, global_interface_handle, &req);
367 
368 	if (nan_availability) {
369 		int cmd_len, size;
370 		NanDebugParams cfg_debug;
371 
372 		sigma_dut_print(dut, DUT_MSG_INFO,
373 				"%s given string nan_availability: %s",
374 				__func__, nan_availability);
375 		memset(&cfg_debug, 0, sizeof(NanDebugParams));
376 		cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY;
377 		size = NAN_MAX_DEBUG_MESSAGE_DATA_LEN;
378 		nan_parse_hex_string(dut, &nan_availability[2],
379 				     &cfg_debug.debug_cmd_data[0], &size);
380 		sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex nan_availability",
381 				__func__);
382 		nan_hex_dump(dut, &cfg_debug.debug_cmd_data[0], size);
383 		cmd_len = size + sizeof(u32);
384 		nan_debug_command_config(0, global_interface_handle,
385 					 cfg_debug, cmd_len);
386 	}
387 
388 	/* To ensure sta_get_events to get the events
389 	 * only after joining the NAN cluster. */
390 	abstime.tv_sec = 30;
391 	abstime.tv_nsec = 0;
392 	wait(abstime);
393 
394 	return 0;
395 }
396 
397 
398 int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn,
399 		      struct sigma_cmd *cmd)
400 {
401 	struct timespec abstime;
402 
403 	nan_disable_request(0, global_interface_handle);
404 
405 	abstime.tv_sec = 4;
406 	abstime.tv_nsec = 0;
407 	wait(abstime);
408 
409 	return 0;
410 }
411 
412 
413 int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn,
414 			    struct sigma_cmd *cmd)
415 {
416 	const char *master_pref = get_param(cmd, "MasterPref");
417 	const char *rand_fac = get_param(cmd, "RandFactor");
418 	const char *hop_count = get_param(cmd, "HopCount");
419 	wifi_error ret;
420 	struct timespec abstime;
421 	NanConfigRequest req;
422 
423 	memset(&req, 0, sizeof(NanConfigRequest));
424 	req.config_rssi_proximity = 1;
425 	req.rssi_proximity = 70;
426 
427 	if (master_pref) {
428 		int master_pref_val = strtoul(master_pref, NULL, 0);
429 
430 		req.config_master_pref = 1;
431 		req.master_pref = master_pref_val;
432 	}
433 
434 	if (rand_fac) {
435 		int rand_fac_val = strtoul(rand_fac, NULL, 0);
436 
437 		req.config_random_factor_force = 1;
438 		req.random_factor_force_val = rand_fac_val;
439 	}
440 
441 	if (hop_count) {
442 		int hop_count_val = strtoul(hop_count, NULL, 0);
443 
444 		req.config_hop_count_force = 1;
445 		req.hop_count_force_val = hop_count_val;
446 	}
447 
448 	ret = nan_config_request(0, global_interface_handle, &req);
449 	if (ret != WIFI_SUCCESS)
450 		send_resp(dut, conn, SIGMA_ERROR, "NAN config request failed");
451 
452 	abstime.tv_sec = 4;
453 	abstime.tv_nsec = 0;
454 	wait(abstime);
455 
456 	return 0;
457 }
458 
459 
460 static int sigma_nan_subscribe_request(struct sigma_dut *dut,
461 				       struct sigma_conn *conn,
462 				       struct sigma_cmd *cmd)
463 {
464 	const char *subscribe_type = get_param(cmd, "SubscribeType");
465 	const char *service_name = get_param(cmd, "ServiceName");
466 	const char *disc_range = get_param(cmd, "DiscoveryRange");
467 	const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
468 	const char *tx_match_filter = get_param(cmd, "txMatchFilter");
469 	const char *sdftx_dw = get_param(cmd, "SDFTxDW");
470 	const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
471 	const char *include_bit = get_param(cmd, "IncludeBit");
472 	const char *mac = get_param(cmd, "MAC");
473 	const char *srf_type = get_param(cmd, "SRFType");
474 #if NAN_CERT_VERSION >= 3
475 	const char *awake_dw_interval = get_param(cmd, "awakeDWint");
476 #endif
477 	NanSubscribeRequest req;
478 	NanConfigRequest config_req;
479 	int filter_len_rx = 0, filter_len_tx = 0;
480 	u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
481 	u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
482 	wifi_error ret;
483 
484 	memset(&req, 0, sizeof(NanSubscribeRequest));
485 	memset(&config_req, 0, sizeof(NanConfigRequest));
486 	req.ttl = 0;
487 	req.period = 1;
488 	req.subscribe_type = 1;
489 	req.serviceResponseFilter = 1; /* MAC */
490 	req.serviceResponseInclude = 0;
491 	req.ssiRequiredForMatchIndication = 0;
492 	req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
493 	req.subscribe_count = 0;
494 
495 	if (global_subscribe_service_name_len &&
496 	    service_name &&
497 	    strcasecmp((char *) global_subscribe_service_name,
498 		       service_name) == 0 &&
499 	    global_subscribe_id) {
500 		req.subscribe_id = global_subscribe_id;
501 		sigma_dut_print(dut, DUT_MSG_INFO,
502 				"%s: updating subscribe_id = %d in subscribe request",
503 				__func__, req.subscribe_id);
504 	}
505 
506 	if (subscribe_type) {
507 		if (strcasecmp(subscribe_type, "Active") == 0) {
508 			req.subscribe_type = 1;
509 		} else if (strcasecmp(subscribe_type, "Passive") == 0) {
510 			req.subscribe_type = 0;
511 		} else if (strcasecmp(subscribe_type, "Cancel") == 0) {
512 			NanSubscribeCancelRequest req;
513 
514 			memset(&req, 0, sizeof(NanSubscribeCancelRequest));
515 			ret = nan_subscribe_cancel_request(
516 				0, global_interface_handle, &req);
517 			if (ret != WIFI_SUCCESS) {
518 				send_resp(dut, conn, SIGMA_ERROR,
519 					  "NAN subscribe cancel request failed");
520 			}
521 			return 0;
522 		}
523 	}
524 
525 	if (disc_range)
526 		req.rssi_threshold_flag = atoi(disc_range);
527 
528 	if (sdftx_dw)
529 		req.subscribe_count = atoi(sdftx_dw);
530 
531 	/* Check this once again if config can be called here (TBD) */
532 	if (discrange_ltd)
533 		req.rssi_threshold_flag = atoi(discrange_ltd);
534 
535 	if (include_bit) {
536 		int include_bit_val = atoi(include_bit);
537 
538 		req.serviceResponseInclude = include_bit_val;
539 		sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d",
540 				req.serviceResponseInclude);
541 	}
542 
543 	if (srf_type) {
544 		int srf_type_val = atoi(srf_type);
545 
546 		if (srf_type_val == 1)
547 			req.serviceResponseFilter = 0; /* Bloom */
548 		else
549 			req.serviceResponseFilter = 1; /* MAC */
550 		req.useServiceResponseFilter = 1;
551 		sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d",
552 				req.serviceResponseFilter);
553 	}
554 
555 	if (mac) {
556 		sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac);
557 		req.num_intf_addr_present = nan_parse_mac_address_list(
558 			dut, mac, &req.intf_addr[0][0],
559 			NAN_MAX_SUBSCRIBE_MAX_ADDRESS);
560 	}
561 
562 	memset(input_rx, 0, sizeof(input_rx));
563 	memset(input_tx, 0, sizeof(input_tx));
564 	if (rx_match_filter) {
565 		nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
566 		sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
567 				filter_len_rx);
568 	}
569 	if (tx_match_filter) {
570 		nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
571 		sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
572 				filter_len_tx);
573 	}
574 
575 	if (tx_match_filter) {
576 		req.tx_match_filter_len = filter_len_tx;
577 		memcpy(req.tx_match_filter, input_tx, filter_len_tx);
578 		nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
579 	}
580 	if (rx_match_filter) {
581 		req.rx_match_filter_len = filter_len_rx;
582 		memcpy(req.rx_match_filter, input_rx, filter_len_rx);
583 		nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
584 	}
585 
586 	if (service_name) {
587 		strlcpy((char *) req.service_name, service_name,
588 			strlen(service_name) + 1);
589 		req.service_name_len = strlen(service_name);
590 		strlcpy((char *) global_subscribe_service_name, service_name,
591 			sizeof(global_subscribe_service_name));
592 		global_subscribe_service_name_len =
593 			strlen((char *) global_subscribe_service_name);
594 	}
595 
596 #if NAN_CERT_VERSION >= 3
597 	if (awake_dw_interval) {
598 		int input_dw_interval_val = atoi(awake_dw_interval);
599 		int awake_dw_int = 0;
600 
601 		if (input_dw_interval_val > NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL) {
602 			sigma_dut_print(dut, DUT_MSG_INFO,
603 					"%s: input active dw interval = %d overwritting dw interval to Max allowed dw interval 16",
604 					__func__, input_dw_interval_val);
605 			input_dw_interval_val =
606 				NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL;
607 		}
608 		sigma_dut_print(dut, DUT_MSG_INFO,
609 				"%s: input active DW interval = %d",
610 				__func__, input_dw_interval_val);
611 		/*
612 		 * Indicates the interval for Sync beacons and SDF's in 2.4 GHz
613 		 * or 5 GHz band. Valid values of DW Interval are: 1, 2, 3, 4,
614 		 * and 5; 0 is reserved. The SDF includes in OTA when enabled.
615 		 * The publish/subscribe period values don't override the device
616 		 * level configurations.
617 		 * input_dw_interval_val is provided by the user are in the
618 		 * format 2^n-1 = 1/2/4/8/16. Internal implementation expects n
619 		 * to be passed to indicate the awake_dw_interval.
620 		 */
621 		if (input_dw_interval_val == 1 ||
622 		    input_dw_interval_val % 2 == 0) {
623 			while (input_dw_interval_val > 0) {
624 				input_dw_interval_val >>= 1;
625 				awake_dw_int++;
626 			}
627 		}
628 		sigma_dut_print(dut, DUT_MSG_INFO,
629 				"%s:converted active DW interval = %d",
630 				__func__, awake_dw_int);
631 		config_req.config_dw.config_2dot4g_dw_band = 1;
632 		config_req.config_dw.dw_2dot4g_interval_val = awake_dw_int;
633 		config_req.config_dw.config_5g_dw_band = 1;
634 		config_req.config_dw.dw_5g_interval_val = awake_dw_int;
635 		ret = nan_config_request(0, global_interface_handle,
636 					 &config_req);
637 		if (ret != WIFI_SUCCESS) {
638 			sigma_dut_print(dut, DUT_MSG_ERROR,
639 					"%s:NAN config request failed",
640 					__func__);
641 			return -2;
642 		}
643 	}
644 #endif
645 
646 	ret = nan_subscribe_request(0, global_interface_handle, &req);
647 	if (ret != WIFI_SUCCESS) {
648 		send_resp(dut, conn, SIGMA_ERROR,
649 			  "NAN subscribe request failed");
650 	}
651 
652 	return 0;
653 }
654 
655 
656 static int sigma_ndp_configure_band(struct sigma_dut *dut,
657 				    struct sigma_conn *conn,
658 				    struct sigma_cmd *cmd,
659 				    NdpSupportedBand band_config_val)
660 {
661 	wifi_error ret;
662 	NanDebugParams cfg_debug;
663 	int size;
664 
665 	memset(&cfg_debug, 0, sizeof(NanDebugParams));
666 	cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS;
667 	memcpy(cfg_debug.debug_cmd_data, &band_config_val, sizeof(int));
668 	sigma_dut_print(dut, DUT_MSG_INFO, "%s:setting debug cmd=0x%x",
669 			__func__, cfg_debug.cmd);
670 	size = sizeof(u32) + sizeof(int);
671 	ret = nan_debug_command_config(0, global_interface_handle, cfg_debug,
672 				       size);
673 	if (ret != WIFI_SUCCESS)
674 		send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
675 
676 	return 0;
677 }
678 
679 
680 static int sigma_nan_data_request(struct sigma_dut *dut,
681 				  struct sigma_conn *conn,
682 				  struct sigma_cmd *cmd)
683 {
684 	const char *ndp_security = get_param(cmd, "DataPathSecurity");
685 	const char *ndp_resp_mac = get_param(cmd, "RespNanMac");
686 	const char *include_immutable = get_param(cmd, "includeimmutable");
687 	const char *avoid_channel = get_param(cmd, "avoidchannel");
688 	const char *invalid_nan_schedule = get_param(cmd, "InvalidNANSchedule");
689 	const char *map_order = get_param(cmd, "maporder");
690 #if NAN_CERT_VERSION >= 3
691 	const char *qos_config = get_param(cmd, "QoS");
692 #endif
693 	wifi_error ret;
694 	NanDataPathInitiatorRequest init_req;
695 	NanDebugParams cfg_debug;
696 	int size;
697 
698 	memset(&init_req, 0, sizeof(NanDataPathInitiatorRequest));
699 
700 	if (ndp_security) {
701 		if (strcasecmp(ndp_security, "open") == 0)
702 			init_req.ndp_cfg.security_cfg =
703 				NAN_DP_CONFIG_NO_SECURITY;
704 		else if (strcasecmp(ndp_security, "secure") == 0)
705 			init_req.ndp_cfg.security_cfg = NAN_DP_CONFIG_SECURITY;
706 	}
707 
708 	if (include_immutable) {
709 		int include_immutable_val = 0;
710 
711 		memset(&cfg_debug, 0, sizeof(NanDebugParams));
712 		cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE;
713 		include_immutable_val = atoi(include_immutable);
714 		memcpy(cfg_debug.debug_cmd_data, &include_immutable_val,
715 		       sizeof(int));
716 		size = sizeof(u32) + sizeof(int);
717 		nan_debug_command_config(0, global_interface_handle,
718 		cfg_debug, size);
719 	}
720 
721 	if (avoid_channel) {
722 		int avoid_channel_freq = 0;
723 
724 		memset(&cfg_debug, 0, sizeof(NanDebugParams));
725 		avoid_channel_freq = channel_to_freq(atoi(avoid_channel));
726 		cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL;
727 		memcpy(cfg_debug.debug_cmd_data, &avoid_channel_freq,
728 		       sizeof(int));
729 		size = sizeof(u32) + sizeof(int);
730 		nan_debug_command_config(0, global_interface_handle,
731 					 cfg_debug, size);
732 	}
733 
734 	if (invalid_nan_schedule) {
735 		int invalid_nan_schedule_type = 0;
736 
737 		memset(&cfg_debug, 0, sizeof(NanDebugParams));
738 		invalid_nan_schedule_type = atoi(invalid_nan_schedule);
739 		cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_TYPE;
740 		memcpy(cfg_debug.debug_cmd_data,
741 		       &invalid_nan_schedule_type, sizeof(int));
742 		size = sizeof(u32) + sizeof(int);
743 		sigma_dut_print(dut, DUT_MSG_INFO,
744 				"%s: invalid schedule type: cmd type = %d and command data = %d",
745 				__func__, cfg_debug.cmd,
746 				invalid_nan_schedule_type);
747 		nan_debug_command_config(0, global_interface_handle,
748 					 cfg_debug, size);
749 	}
750 
751 	if (map_order) {
752 		int map_order_val = 0;
753 
754 		memset(&cfg_debug, 0, sizeof(NanDebugParams));
755 		cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER;
756 		map_order_val = atoi(map_order);
757 		memcpy(cfg_debug.debug_cmd_data, &map_order_val, sizeof(int));
758 		size = sizeof(u32) + sizeof(int);
759 		sigma_dut_print(dut, DUT_MSG_INFO,
760 				"%s: map order: cmd type = %d and command data = %d",
761 				__func__,
762 				cfg_debug.cmd, map_order_val);
763 		nan_debug_command_config(0, global_interface_handle,
764 					 cfg_debug, size);
765 	}
766 
767 #if NAN_CERT_VERSION >= 3
768 	if (qos_config) {
769 		u32 qos_config_val = 0;
770 
771 		memset(&cfg_debug, 0, sizeof(NanDebugParams));
772 		cfg_debug.cmd = NAN_TEST_MODE_CMD_CONFIG_QOS;
773 		qos_config_val = atoi(qos_config);
774 		memcpy(cfg_debug.debug_cmd_data, &qos_config_val, sizeof(u32));
775 		size = sizeof(u32) + sizeof(u32);
776 		sigma_dut_print(dut, DUT_MSG_INFO,
777 				"%s: qos config: cmd type = %d and command data = %d",
778 				__func__, cfg_debug.cmd, qos_config_val);
779 		nan_debug_command_config(0, global_interface_handle,
780 					 cfg_debug, size);
781 	}
782 #endif
783 
784 	/*
785 	 * Setting this flag, so that interface for ping6 command
786 	 * is set appropriately in traffic_send_ping().
787 	 */
788 	dut->ndp_enable = 1;
789 
790 	/*
791 	 * Intended sleep after NAN data interface create
792 	 * before the NAN data request
793 	 */
794 	sleep(4);
795 
796 	init_req.requestor_instance_id = global_match_handle;
797 	strlcpy((char *) init_req.ndp_iface, "nan0",
798 		sizeof(init_req.ndp_iface));
799 
800 	if (ndp_resp_mac) {
801 		nan_parse_mac_address(dut, ndp_resp_mac,
802 				      init_req.peer_disc_mac_addr);
803 		sigma_dut_print(
804 			dut, DUT_MSG_INFO, "PEER MAC ADDR: " MAC_ADDR_STR,
805 			MAC_ADDR_ARRAY(init_req.peer_disc_mac_addr));
806 	} else {
807 		memcpy(init_req.peer_disc_mac_addr, global_peer_mac_addr,
808 		       sizeof(init_req.peer_disc_mac_addr));
809 	}
810 
811 	/* Not requesting the channel and letting FW decide */
812 	if (dut->sta_channel == 0) {
813 		init_req.channel_request_type = NAN_DP_CHANNEL_NOT_REQUESTED;
814 		init_req.channel = 0;
815 	} else {
816 		init_req.channel_request_type = NAN_DP_FORCE_CHANNEL_SETUP;
817 		init_req.channel = channel_to_freq(dut->sta_channel);
818 	}
819 	sigma_dut_print(dut, DUT_MSG_INFO,
820 			"%s: Initiator Request: Channel = %d  Channel Request Type = %d",
821 			__func__, init_req.channel,
822 			init_req.channel_request_type);
823 
824 	if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) {
825 		init_req.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
826 		memcpy(&init_req.key_info.body.pmk_info.pmk[0],
827 		       &dut->nan_pmk[0], NAN_PMK_INFO_LEN);
828 		init_req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
829 		sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
830 				__func__,
831 				init_req.key_info.body.pmk_info.pmk_len);
832 	}
833 
834 	ret = nan_data_request_initiator(0, global_interface_handle, &init_req);
835 	if (ret != WIFI_SUCCESS) {
836 		send_resp(dut, conn, SIGMA_ERROR,
837 			  "Unable to initiate nan data request");
838 		return 0;
839 	}
840 
841 	return 0;
842 }
843 
844 
845 static int sigma_nan_data_response(struct sigma_dut *dut,
846 				   struct sigma_conn *conn,
847 				   struct sigma_cmd *cmd)
848 {
849 	const char *ndl_response = get_param(cmd, "NDLresponse");
850 	const char *m4_response_type = get_param(cmd, "M4ResponseType");
851 	wifi_error ret;
852 	NanDebugParams cfg_debug;
853 	int size;
854 
855 	if (ndl_response) {
856 		int auto_responder_mode_val = 0;
857 
858 		sigma_dut_print(dut, DUT_MSG_INFO,
859 				"%s: ndl_response = (%s) is passed",
860 				__func__, ndl_response);
861 		memset(&cfg_debug, 0, sizeof(NanDebugParams));
862 		cfg_debug.cmd = NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE;
863 		if (strcasecmp(ndl_response, "Auto") == 0) {
864 			auto_responder_mode_val = NAN_DATA_RESPONDER_MODE_AUTO;
865 		} else if (strcasecmp(ndl_response, "Reject") == 0) {
866 			auto_responder_mode_val =
867 				NAN_DATA_RESPONDER_MODE_REJECT;
868 		} else if (strcasecmp(ndl_response, "Accept") == 0) {
869 			auto_responder_mode_val =
870 				NAN_DATA_RESPONDER_MODE_ACCEPT;
871 		} else if (strcasecmp(ndl_response, "Counter") == 0) {
872 			auto_responder_mode_val =
873 				NAN_DATA_RESPONDER_MODE_COUNTER;
874 		} else {
875 			sigma_dut_print(dut, DUT_MSG_ERROR,
876 					"%s: Invalid ndl_response",
877 					__func__);
878 			return 0;
879 		}
880 		memcpy(cfg_debug.debug_cmd_data, &auto_responder_mode_val,
881 		       sizeof(int));
882 		size = sizeof(u32) + sizeof(int);
883 		ret = nan_debug_command_config(0, global_interface_handle,
884 					       cfg_debug, size);
885 		if (ret != WIFI_SUCCESS) {
886 			send_resp(dut, conn, SIGMA_ERROR,
887 				  "Nan config request failed");
888 		}
889 	}
890 
891 	if (m4_response_type) {
892 		int m4_response_type_val = 0;
893 
894 		sigma_dut_print(dut, DUT_MSG_INFO,
895 				"%s: m4_response_type = (%s) is passed",
896 				__func__, m4_response_type);
897 		memset(&cfg_debug, 0, sizeof(NanDebugParams));
898 		cfg_debug.cmd = NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE;
899 		if (strcasecmp(m4_response_type, "Accept") == 0)
900 			m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_ACCEPT;
901 		else if (strcasecmp(m4_response_type, "Reject") == 0)
902 			m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_REJECT;
903 		else if (strcasecmp(m4_response_type, "BadMic") == 0)
904 			m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_BADMIC;
905 
906 		memcpy(cfg_debug.debug_cmd_data, &m4_response_type_val,
907 		       sizeof(int));
908 		size = sizeof(u32) + sizeof(int);
909 		ret = nan_debug_command_config(0, global_interface_handle,
910 					       cfg_debug, size);
911 		if (ret != WIFI_SUCCESS) {
912 			send_resp(dut, conn, SIGMA_ERROR,
913 				  "Nan config request failed");
914 		}
915 	}
916 
917 	return 0;
918 }
919 
920 
921 static int sigma_nan_data_end(struct sigma_dut *dut, struct sigma_cmd *cmd)
922 {
923 	const char *nmf_security_config = get_param(cmd, "Security");
924 	NanDataPathEndRequest req;
925 	NanDebugParams cfg_debug;
926 	int size;
927 
928 	memset(&req, 0, sizeof(NanDataPathEndRequest));
929 	memset(&cfg_debug, 0, sizeof(NanDebugParams));
930 	if (nmf_security_config) {
931 		int nmf_security_config_val = 0;
932 
933 		cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_NMF_CLEAR_CONFIG;
934 		if (strcasecmp(nmf_security_config, "open") == 0)
935 			nmf_security_config_val = NAN_NMF_CLEAR_ENABLE;
936 		else if (strcasecmp(nmf_security_config, "secure") == 0)
937 			nmf_security_config_val = NAN_NMF_CLEAR_DISABLE;
938 		memcpy(cfg_debug.debug_cmd_data,
939 			&nmf_security_config_val, sizeof(int));
940 		size = sizeof(u32) + sizeof(int);
941 		sigma_dut_print(dut, DUT_MSG_INFO,
942 				"%s: nmf_security_config_val -- cmd type = %d and command data = %d",
943 				__func__, cfg_debug.cmd,
944 				nmf_security_config_val);
945 		nan_debug_command_config(0, global_interface_handle,
946 					 cfg_debug, size);
947 	}
948 
949 	req.num_ndp_instances = 1;
950 	req.ndp_instance_id[0] = global_ndp_instance_id;
951 
952 	nan_data_end(0, global_interface_handle, &req);
953 	return 0;
954 }
955 
956 
957 static int sigma_nan_range_request(struct sigma_dut *dut,
958 				   struct sigma_cmd *cmd)
959 {
960 	const char *dest_mac = get_param(cmd, "destmac");
961 	NanSubscribeRequest req;
962 
963 	memset(&req, 0, sizeof(NanSubscribeRequest));
964 	req.period = 1;
965 	req.subscribe_type = NAN_SUBSCRIBE_TYPE_PASSIVE;
966 	req.serviceResponseFilter = NAN_SRF_ATTR_BLOOM_FILTER;
967 	req.serviceResponseInclude = NAN_SRF_INCLUDE_RESPOND;
968 	req.ssiRequiredForMatchIndication = NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
969 	req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
970 	req.subscribe_count = 0;
971 	strlcpy((char *) req.service_name, DEFAULT_SVC,
972 		NAN_MAX_SERVICE_NAME_LEN);
973 	req.service_name_len = strlen((char *) req.service_name);
974 
975 	req.subscribe_id = global_subscribe_id;
976 	req.sdea_params.ranging_state = 1;
977 	req.sdea_params.range_report = NAN_ENABLE_RANGE_REPORT;
978 	req.range_response_cfg.requestor_instance_id = global_match_handle;
979 	req.range_response_cfg.ranging_response = NAN_RANGE_REQUEST_ACCEPT;
980 	req.ranging_cfg.config_ranging_indications =
981 		NAN_RANGING_INDICATE_CONTINUOUS_MASK;
982 	if (dest_mac) {
983 		nan_parse_mac_address(dut, dest_mac,
984 				      req.range_response_cfg.peer_addr);
985 		sigma_dut_print(
986 			dut, DUT_MSG_INFO, "peer mac addr: " MAC_ADDR_STR,
987 			MAC_ADDR_ARRAY(req.range_response_cfg.peer_addr));
988 	}
989 	nan_subscribe_request(0, global_interface_handle, &req);
990 
991 	return 0;
992 }
993 
994 
995 static int sigma_nan_cancel_range(struct sigma_dut *dut,
996 				  struct sigma_cmd *cmd)
997 {
998 	const char *dest_mac = get_param(cmd, "destmac");
999 	NanPublishRequest req;
1000 
1001 	memset(&req, 0, sizeof(NanPublishRequest));
1002 	req.ttl = 0;
1003 	req.period = 1;
1004 	req.publish_match_indicator = 1;
1005 	req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
1006 	req.tx_type = NAN_TX_TYPE_BROADCAST;
1007 	req.publish_count = 0;
1008 	strlcpy((char *) req.service_name, DEFAULT_SVC,
1009 		NAN_MAX_SERVICE_NAME_LEN);
1010 	req.service_name_len = strlen((char *) req.service_name);
1011 	req.publish_id = global_publish_id;
1012 	req.range_response_cfg.ranging_response = NAN_RANGE_REQUEST_CANCEL;
1013 	if (dest_mac) {
1014 		nan_parse_mac_address(dut, dest_mac,
1015 				      req.range_response_cfg.peer_addr);
1016 		sigma_dut_print(
1017 			dut, DUT_MSG_INFO, "peer mac addr: " MAC_ADDR_STR,
1018 			MAC_ADDR_ARRAY(req.range_response_cfg.peer_addr));
1019 	}
1020 	nan_publish_request(0, global_interface_handle, &req);
1021 
1022 	return 0;
1023 }
1024 
1025 
1026 static int sigma_nan_schedule_update(struct sigma_dut *dut,
1027 				     struct sigma_cmd *cmd)
1028 {
1029 	const char *schedule_update_type = get_param(cmd, "type");
1030 	const char *channel_availability = get_param(cmd,
1031 						     "ChannelAvailability");
1032 	const char *responder_nmi_mac = get_param(cmd, "ResponderNMI");
1033 	NanDebugParams cfg_debug;
1034 	int size = 0;
1035 
1036 	memset(&cfg_debug, 0, sizeof(NanDebugParams));
1037 
1038 	if (!schedule_update_type)
1039 		return 0;
1040 
1041 	if (strcasecmp(schedule_update_type, "ULWnotify") == 0) {
1042 		cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY;
1043 		size = sizeof(u32);
1044 		sigma_dut_print(dut, DUT_MSG_INFO,
1045 				"%s: Schedule Update cmd type = %d", __func__,
1046 				cfg_debug.cmd);
1047 		if (channel_availability) {
1048 			int channel_availability_val;
1049 
1050 			channel_availability_val = atoi(channel_availability);
1051 			size += sizeof(int);
1052 			memcpy(cfg_debug.debug_cmd_data,
1053 			       &channel_availability_val, sizeof(int));
1054 			sigma_dut_print(dut, DUT_MSG_INFO,
1055 					"%s: Schedule Update cmd data = %d size = %d",
1056 					__func__, channel_availability_val,
1057 					size);
1058 		}
1059 	} else if (strcasecmp(schedule_update_type, "NDLnegotiate") == 0) {
1060 		cfg_debug.cmd =
1061 			NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE;
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 		if (responder_nmi_mac) {
1067 			u8 responder_nmi_mac_addr[NAN_MAC_ADDR_LEN];
1068 
1069 			nan_parse_mac_address(dut, responder_nmi_mac,
1070 					      responder_nmi_mac_addr);
1071 			size += NAN_MAC_ADDR_LEN;
1072 			memcpy(cfg_debug.debug_cmd_data, responder_nmi_mac_addr,
1073 			       NAN_MAC_ADDR_LEN);
1074 			sigma_dut_print(dut, DUT_MSG_INFO,
1075 					"%s: RESPONDER NMI MAC: "MAC_ADDR_STR,
1076 					__func__,
1077 					MAC_ADDR_ARRAY(responder_nmi_mac_addr));
1078 			sigma_dut_print(dut, DUT_MSG_INFO,
1079 					"%s: Schedule Update: cmd size = %d",
1080 					__func__, size);
1081 		}
1082 	} else if (strcasecmp(schedule_update_type, "NDLnotify") == 0) {
1083 		cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY;
1084 		size = sizeof(u32);
1085 		sigma_dut_print(dut, DUT_MSG_INFO,
1086 				"%s: Schedule Update cmd type = %d", __func__,
1087 				cfg_debug.cmd);
1088 	}
1089 
1090 	nan_debug_command_config(0, global_interface_handle, cfg_debug, size);
1091 
1092 	return 0;
1093 }
1094 
1095 
1096 int config_post_disc_attr(void)
1097 {
1098 	wifi_error ret;
1099 	NanConfigRequest configReq;
1100 
1101 	memset(&configReq, 0, sizeof(NanConfigRequest));
1102 
1103 	/* Configure Post disc attr */
1104 	/* Make these defines and use correct enum */
1105 	configReq.num_config_discovery_attr = 1;
1106 	configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */
1107 	configReq.discovery_attr_val[0].role = 0;
1108 	configReq.discovery_attr_val[0].transmit_freq = 1;
1109 	configReq.discovery_attr_val[0].duration = 0;
1110 	configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008;
1111 
1112 	ret = nan_config_request(0, global_interface_handle, &configReq);
1113 	if (ret != WIFI_SUCCESS) {
1114 		sigma_dut_print(global_dut, DUT_MSG_INFO,
1115 				"NAN config request failed while configuring post discovery attribute");
1116 	}
1117 
1118 	return 0;
1119 }
1120 
1121 
1122 int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn,
1123 			      struct sigma_cmd *cmd)
1124 {
1125 	const char *publish_type = get_param(cmd, "PublishType");
1126 	const char *service_name = get_param(cmd, "ServiceName");
1127 	const char *disc_range = get_param(cmd, "DiscoveryRange");
1128 	const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
1129 	const char *tx_match_filter = get_param(cmd, "txMatchFilter");
1130 	const char *sdftx_dw = get_param(cmd, "SDFTxDW");
1131 	const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
1132 	const char *ndp_enable = get_param(cmd, "DataPathFlag");
1133 	const char *ndp_type = get_param(cmd, "DataPathType");
1134 	const char *data_path_security = get_param(cmd, "datapathsecurity");
1135 	const char *range_required = get_param(cmd, "rangerequired");
1136 #if NAN_CERT_VERSION >= 3
1137 	const char *awake_dw_interval = get_param(cmd, "awakeDWint");
1138 	const char *qos_config = get_param(cmd, "QoS");
1139 #endif
1140 	NanPublishRequest req;
1141 	NanConfigRequest config_req;
1142 	int filter_len_rx = 0, filter_len_tx = 0;
1143 	u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
1144 	u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
1145 	wifi_error ret;
1146 
1147 	memset(&req, 0, sizeof(NanPublishRequest));
1148 	memset(&config_req, 0, sizeof(NanConfigRequest));
1149 	req.ttl = 0;
1150 	req.period = 1;
1151 	req.publish_match_indicator = 1;
1152 	req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
1153 	req.tx_type = NAN_TX_TYPE_BROADCAST;
1154 	req.publish_count = 0;
1155 	req.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_ALL;
1156 
1157 	if (global_publish_service_name_len &&
1158 	    service_name &&
1159 	    strcasecmp((char *) global_publish_service_name,
1160 		       service_name) == 0 &&
1161 	    global_publish_id) {
1162 		req.publish_id = global_publish_id;
1163 		sigma_dut_print(dut, DUT_MSG_INFO,
1164 				"%s: updating publish_id = %d in publish request",
1165 				__func__, req.publish_id);
1166 	}
1167 
1168 	if (service_name) {
1169 		strlcpy((char *) req.service_name, service_name,
1170 			sizeof(req.service_name));
1171 		req.service_name_len = strlen((char *) req.service_name);
1172 		strlcpy((char *) global_publish_service_name, service_name,
1173 			sizeof(global_publish_service_name));
1174 		global_publish_service_name_len =
1175 			strlen((char *) global_publish_service_name);
1176 	}
1177 
1178 	if (publish_type) {
1179 		if (strcasecmp(publish_type, "Solicited") == 0) {
1180 			req.publish_type = NAN_PUBLISH_TYPE_SOLICITED;
1181 		} else if (strcasecmp(publish_type, "Unsolicited") == 0) {
1182 			req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
1183 		} else if (strcasecmp(publish_type, "Cancel") == 0) {
1184 			NanPublishCancelRequest req;
1185 
1186 			memset(&req, 0, sizeof(NanPublishCancelRequest));
1187 			ret = nan_publish_cancel_request(
1188 				0, global_interface_handle, &req);
1189 			if (ret != WIFI_SUCCESS) {
1190 				send_resp(dut, conn, SIGMA_ERROR,
1191 					  "Unable to cancel nan publish request");
1192 			}
1193 			return 0;
1194 		}
1195 	}
1196 
1197 	if (disc_range)
1198 		req.rssi_threshold_flag = atoi(disc_range);
1199 
1200 	if (sdftx_dw)
1201 		req.publish_count = atoi(sdftx_dw);
1202 
1203 	if (discrange_ltd)
1204 		req.rssi_threshold_flag = atoi(discrange_ltd);
1205 
1206 	memset(input_rx, 0, sizeof(input_rx));
1207 	memset(input_tx, 0, sizeof(input_tx));
1208 	if (rx_match_filter) {
1209 		nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
1210 		sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
1211 				filter_len_rx);
1212 	}
1213 	if (tx_match_filter) {
1214 		nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
1215 		sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
1216 				filter_len_tx);
1217 	}
1218 
1219 	if (is_fam == 1) {
1220 		config_post_disc_attr();
1221 		/*
1222 		 * 8-bit bitmap which allows the Host to associate this publish
1223 		 * with a particular Post-NAN Connectivity attribute which has
1224 		 * been sent down in a NanConfigureRequest/NanEnableRequest
1225 		 * message. If the DE fails to find a configured Post-NAN
1226 		 * connectivity attributes referenced by the bitmap, the DE will
1227 		 * return an error code to the Host. If the Publish is
1228 		 * configured to use a Post-NAN Connectivity attribute and the
1229 		 * Host does not refresh the Post-NAN Connectivity attribute the
1230 		 * Publish will be canceled and the Host will be sent a
1231 		 * PublishTerminatedIndication message.
1232 		 */
1233 		req.connmap = 0x10;
1234 	}
1235 
1236 	if (tx_match_filter) {
1237 		req.tx_match_filter_len = filter_len_tx;
1238 		memcpy(req.tx_match_filter, input_tx, filter_len_tx);
1239 		nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
1240 	}
1241 
1242 	if (rx_match_filter) {
1243 		req.rx_match_filter_len = filter_len_rx;
1244 		memcpy(req.rx_match_filter, input_rx, filter_len_rx);
1245 		nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
1246 	}
1247 
1248 	if (service_name) {
1249 		strlcpy((char *) req.service_name, service_name,
1250 			strlen(service_name) + 1);
1251 		req.service_name_len = strlen(service_name);
1252 	}
1253 
1254 	if (ndp_enable) {
1255 		if (strcasecmp(ndp_enable, "enable") == 0)
1256 			req.sdea_params.config_nan_data_path = 1;
1257 		else
1258 			req.sdea_params.config_nan_data_path = 0;
1259 
1260 		if (ndp_type)
1261 			req.sdea_params.ndp_type = atoi(ndp_type);
1262 
1263 		if (data_path_security) {
1264 			if (strcasecmp(data_path_security, "secure") == 0) {
1265 				req.sdea_params.security_cfg =
1266 					NAN_DP_CONFIG_SECURITY;
1267 			} else if (strcasecmp(data_path_security, "open") ==
1268 				   0) {
1269 				req.sdea_params.security_cfg =
1270 					NAN_DP_CONFIG_NO_SECURITY;
1271 			}
1272 		}
1273 
1274 		if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) {
1275 			req.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
1276 			memcpy(&req.key_info.body.pmk_info.pmk[0],
1277 				&dut->nan_pmk[0], NAN_PMK_INFO_LEN);
1278 			req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
1279 			sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
1280 			__func__, req.key_info.body.pmk_info.pmk_len);
1281 		}
1282 	}
1283 	if (range_required && strcasecmp(range_required, "enable") == 0) {
1284 		req.sdea_params.ranging_state = NAN_RANGING_ENABLE;
1285 		req.sdea_params.range_report = NAN_ENABLE_RANGE_REPORT;
1286 	}
1287 
1288 #if NAN_CERT_VERSION >= 3
1289 	if (awake_dw_interval) {
1290 		int input_dw_interval_val = atoi(awake_dw_interval);
1291 		int awake_dw_int = 0;
1292 
1293 		if (input_dw_interval_val > NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL) {
1294 			sigma_dut_print(dut, DUT_MSG_INFO,
1295 					"%s: input active dw interval = %d overwritting dw interval to Max allowed dw interval 16",
1296 					__func__, input_dw_interval_val);
1297 			input_dw_interval_val =
1298 				NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL;
1299 		}
1300 		sigma_dut_print(dut, DUT_MSG_INFO,
1301 				"%s: input active DW interval = %d",
1302 				__func__, input_dw_interval_val);
1303 		/*
1304 		 * Indicates the interval for Sync beacons and SDF's in 2.4 GHz
1305 		 * or 5 GHz band. Valid values of DW Interval are: 1, 2, 3, 4,
1306 		 * and 5; 0 is reserved. The SDF includes in OTA when enabled.
1307 		 * The publish/subscribe period. values don't override the
1308 		 * device level configurations.
1309 		 * input_dw_interval_val is provided by the user are in the
1310 		 * format 2^n-1 = 1/2/4/8/16. Internal implementation expects n
1311 		 * to be passed to indicate the awake_dw_interval.
1312 		 */
1313 		if (input_dw_interval_val == 1 ||
1314 		    input_dw_interval_val % 2 == 0) {
1315 			while (input_dw_interval_val > 0) {
1316 				input_dw_interval_val >>= 1;
1317 				awake_dw_int++;
1318 			}
1319 		}
1320 		sigma_dut_print(dut, DUT_MSG_INFO,
1321 				"%s:converted active DW interval = %d",
1322 				__func__, awake_dw_int);
1323 		config_req.config_dw.config_2dot4g_dw_band = 1;
1324 		config_req.config_dw.dw_2dot4g_interval_val = awake_dw_int;
1325 		config_req.config_dw.config_5g_dw_band = 1;
1326 		config_req.config_dw.dw_5g_interval_val = awake_dw_int;
1327 		ret = nan_config_request(0, global_interface_handle,
1328 					 &config_req);
1329 		if (ret != WIFI_SUCCESS) {
1330 			sigma_dut_print(dut, DUT_MSG_ERROR,
1331 					"%s:NAN config request failed",
1332 					__func__);
1333 			return -2;
1334 		}
1335 	}
1336 
1337 	if (qos_config)
1338 		req.sdea_params.qos_cfg = (NanQosCfgStatus) atoi(qos_config);
1339 #endif
1340 
1341 	ret = nan_publish_request(0, global_interface_handle, &req);
1342 	if (ret != WIFI_SUCCESS)
1343 		send_resp(dut, conn, SIGMA_ERROR, "Unable to publish");
1344 
1345 	if (ndp_enable)
1346 		dut->ndp_enable = 1;
1347 
1348 	return 0;
1349 }
1350 
1351 
1352 static int nan_further_availability_rx(struct sigma_dut *dut,
1353 				       struct sigma_conn *conn,
1354 				       struct sigma_cmd *cmd)
1355 {
1356 	const char *master_pref = get_param(cmd, "MasterPref");
1357 	const char *rand_fac = get_param(cmd, "RandFactor");
1358 	const char *hop_count = get_param(cmd, "HopCount");
1359 	wifi_error ret;
1360 	struct timespec abstime;
1361 
1362 	NanEnableRequest req;
1363 
1364 	memset(&req, 0, sizeof(NanEnableRequest));
1365 	req.cluster_low = 0;
1366 	req.cluster_high = 0xFFFF;
1367 	req.master_pref = 30;
1368 
1369 	if (master_pref)
1370 		req.master_pref = strtoul(master_pref, NULL, 0);
1371 
1372 	if (rand_fac) {
1373 		int rand_fac_val = strtoul(rand_fac, NULL, 0);
1374 
1375 		req.config_random_factor_force = 1;
1376 		req.random_factor_force_val = rand_fac_val;
1377 	}
1378 
1379 	if (hop_count) {
1380 		int hop_count_val = strtoul(hop_count, NULL, 0);
1381 
1382 		req.config_hop_count_force = 1;
1383 		req.hop_count_force_val = hop_count_val;
1384 	}
1385 
1386 	ret = nan_enable_request(0, global_interface_handle, &req);
1387 	if (ret != WIFI_SUCCESS) {
1388 		send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
1389 		return 0;
1390 	}
1391 
1392 	abstime.tv_sec = 4;
1393 	abstime.tv_nsec = 0;
1394 	wait(abstime);
1395 
1396 	return 0;
1397 }
1398 
1399 
1400 static int nan_further_availability_tx(struct sigma_dut *dut,
1401 				       struct sigma_conn *conn,
1402 				       struct sigma_cmd *cmd)
1403 {
1404 	const char *master_pref = get_param(cmd, "MasterPref");
1405 	const char *rand_fac = get_param(cmd, "RandFactor");
1406 	const char *hop_count = get_param(cmd, "HopCount");
1407 	wifi_error ret;
1408 
1409 	NanEnableRequest req;
1410 	NanConfigRequest configReq;
1411 
1412 	memset(&req, 0, sizeof(NanEnableRequest));
1413 	req.cluster_low = 0;
1414 	req.cluster_high = 0xFFFF;
1415 	req.master_pref = 30;
1416 
1417 	if (master_pref)
1418 		req.master_pref = strtoul(master_pref, NULL, 0);
1419 
1420 	if (rand_fac) {
1421 		int rand_fac_val = strtoul(rand_fac, NULL, 0);
1422 
1423 		req.config_random_factor_force = 1;
1424 		req.random_factor_force_val = rand_fac_val;
1425 	}
1426 
1427 	if (hop_count) {
1428 		int hop_count_val = strtoul(hop_count, NULL, 0);
1429 
1430 		req.config_hop_count_force = 1;
1431 		req.hop_count_force_val = hop_count_val;
1432 	}
1433 
1434 	ret = nan_enable_request(0, global_interface_handle, &req);
1435 	if (ret != WIFI_SUCCESS) {
1436 		send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
1437 		return 0;
1438 	}
1439 
1440 	/* Start the config of fam */
1441 
1442 	memset(&configReq, 0, sizeof(NanConfigRequest));
1443 
1444 	configReq.config_fam = 1;
1445 	configReq.fam_val.numchans = 1;
1446 	configReq.fam_val.famchan[0].entry_control = 0;
1447 	configReq.fam_val.famchan[0].class_val = 81;
1448 	configReq.fam_val.famchan[0].channel = 6;
1449 	configReq.fam_val.famchan[0].mapid = 0;
1450 	configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe;
1451 
1452 	ret = nan_config_request(0, global_interface_handle, &configReq);
1453 	if (ret != WIFI_SUCCESS)
1454 		send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
1455 
1456 	return 0;
1457 }
1458 
1459 
1460 int sigma_nan_transmit_followup(struct sigma_dut *dut,
1461 				struct sigma_conn *conn,
1462 				struct sigma_cmd *cmd)
1463 {
1464 	const char *mac = get_param(cmd, "mac");
1465 	const char *requestor_id = get_param(cmd, "RemoteInstanceId");
1466 	const char *local_id = get_param(cmd, "LocalInstanceId");
1467 	const char *service_name = get_param(cmd, "servicename");
1468 	wifi_error ret;
1469 	NanTransmitFollowupRequest req;
1470 
1471 	memset(&req, 0, sizeof(NanTransmitFollowupRequest));
1472 	req.requestor_instance_id = global_match_handle;
1473 	req.addr[0] = 0xFF;
1474 	req.addr[1] = 0xFF;
1475 	req.addr[2] = 0xFF;
1476 	req.addr[3] = 0xFF;
1477 	req.addr[4] = 0xFF;
1478 	req.addr[5] = 0xFF;
1479 	req.priority = NAN_TX_PRIORITY_NORMAL;
1480 	req.dw_or_faw = 0;
1481 
1482 	if (service_name)
1483 		req.service_specific_info_len = strlen(service_name);
1484 
1485 	if (requestor_id) {
1486 		/* int requestor_id_val = atoi(requestor_id); */
1487 		if (global_match_handle != 0) {
1488 			req.requestor_instance_id = global_match_handle;
1489 		} else {
1490 			u32 requestor_id_val = atoi(requestor_id);
1491 			requestor_id_val =
1492 					(requestor_id_val << 24) | 0x0000FFFF;
1493 			req.requestor_instance_id = requestor_id_val;
1494 		}
1495 	}
1496 	if (local_id) {
1497 		/* int local_id_val = atoi(local_id); */
1498 		if (global_header_handle != 0)
1499 			req.publish_subscribe_id = global_header_handle;
1500 		else
1501 			req.publish_subscribe_id = atoi(local_id);
1502 	}
1503 
1504 	if (mac == NULL) {
1505 		sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address");
1506 		return -1;
1507 	}
1508 	nan_parse_mac_address(dut, mac, req.addr);
1509 
1510 	ret = nan_transmit_followup_request(0, global_interface_handle, &req);
1511 	if (ret != WIFI_SUCCESS) {
1512 		send_resp(dut, conn, SIGMA_ERROR,
1513 			  "Unable to complete nan transmit followup");
1514 	}
1515 
1516 	return 0;
1517 }
1518 
1519 
1520 /* NotifyResponse invoked to notify the status of the Request */
1521 void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data)
1522 {
1523 	sigma_dut_print(global_dut, DUT_MSG_INFO,
1524 			"%s: status %d response_type %d",
1525 			__func__, rsp_data->status, rsp_data->response_type);
1526 	if (rsp_data->response_type == NAN_RESPONSE_STATS &&
1527 	    rsp_data->body.stats_response.stats_type ==
1528 	    NAN_STATS_ID_DE_TIMING_SYNC) {
1529 		NanSyncStats *pSyncStats;
1530 
1531 		sigma_dut_print(global_dut, DUT_MSG_INFO,
1532 				"%s: stats_type %d", __func__,
1533 				rsp_data->body.stats_response.stats_type);
1534 		pSyncStats = &rsp_data->body.stats_response.data.sync_stats;
1535 		memcpy(&global_nan_sync_stats, pSyncStats,
1536 		       sizeof(NanSyncStats));
1537 		pthread_cond_signal(&gCondition);
1538 	} else if (rsp_data->response_type == NAN_RESPONSE_PUBLISH) {
1539 		sigma_dut_print(global_dut, DUT_MSG_INFO,
1540 				"%s: publish_id %d\n",
1541 				__func__,
1542 				rsp_data->body.publish_response.publish_id);
1543 		global_publish_id = rsp_data->body.publish_response.publish_id;
1544 	} else if (rsp_data->response_type == NAN_RESPONSE_SUBSCRIBE) {
1545 		sigma_dut_print(global_dut, DUT_MSG_INFO,
1546 				"%s: subscribe_id %d\n",
1547 				__func__,
1548 				rsp_data->body.subscribe_response.subscribe_id);
1549 		global_subscribe_id =
1550 			rsp_data->body.subscribe_response.subscribe_id;
1551 	}
1552 }
1553 
1554 
1555 /* Events Callback */
1556 void nan_event_publish_replied(NanPublishRepliedInd *event)
1557 {
1558 	sigma_dut_print(global_dut, DUT_MSG_INFO,
1559 			"%s: handle %d " MAC_ADDR_STR " rssi:%d",
1560 			__func__, event->requestor_instance_id,
1561 			MAC_ADDR_ARRAY(event->addr), event->rssi_value);
1562 	event_anyresponse = 1;
1563 	snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1564 		 "EventName,Replied,RemoteInstanceID,%d,LocalInstanceID,%d,mac," MAC_ADDR_STR" ",
1565 		 (event->requestor_instance_id >> 24),
1566 		 (event->requestor_instance_id & 0xFFFF),
1567 		 MAC_ADDR_ARRAY(event->addr));
1568 }
1569 
1570 
1571 /* Events Callback */
1572 void nan_event_publish_terminated(NanPublishTerminatedInd *event)
1573 {
1574 	sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d",
1575 			__func__, event->publish_id, event->reason);
1576 }
1577 
1578 
1579 /* Events Callback */
1580 void nan_event_match(NanMatchInd *event)
1581 {
1582 	sigma_dut_print(global_dut, DUT_MSG_INFO,
1583 			"%s: Pub/Sub Id %d remote_requestor_id %08x "
1584 			MAC_ADDR_STR
1585 			" rssi:%d",
1586 			__func__,
1587 			event->publish_subscribe_id,
1588 			event->requestor_instance_id,
1589 			MAC_ADDR_ARRAY(event->addr),
1590 			event->rssi_value);
1591 	event_anyresponse = 1;
1592 	global_header_handle = event->publish_subscribe_id;
1593 	global_match_handle = event->requestor_instance_id;
1594 	memcpy(global_peer_mac_addr, event->addr, sizeof(global_peer_mac_addr));
1595 
1596 	/* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */
1597 	/* global_pub_sub_handle = event->header.handle; */
1598 	/* Print the SSI */
1599 	sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:");
1600 	nan_hex_dump(global_dut, event->service_specific_info,
1601 		event->service_specific_info_len);
1602 	snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1603 		 "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
1604 		 MAC_ADDR_STR " ", (event->requestor_instance_id >> 24),
1605 		 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
1606 
1607 	/* Print the match filter */
1608 	sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:");
1609 	nan_hex_dump(global_dut, event->sdf_match_filter,
1610 		     event->sdf_match_filter_len);
1611 
1612 	/* Print the conn_capability */
1613 	sigma_dut_print(global_dut, DUT_MSG_INFO,
1614 			"Printing PostConnectivity Capability");
1615 	if (event->is_conn_capability_valid) {
1616 		sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s",
1617 				event->conn_capability.is_wfd_supported ?
1618 				"yes" : "no");
1619 		sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s",
1620 				(event->conn_capability.is_wfds_supported ?
1621 				 "yes" : "no"));
1622 		sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s",
1623 				(event->conn_capability.is_tdls_supported ?
1624 				 "yes" : "no"));
1625 		sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s",
1626 				(event->conn_capability.is_ibss_supported ?
1627 				 "yes" : "no"));
1628 		sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s",
1629 				(event->conn_capability.is_mesh_supported ?
1630 				 "yes" : "no"));
1631 		sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d",
1632 				event->conn_capability.wlan_infra_field);
1633 	} else {
1634 		sigma_dut_print(global_dut, DUT_MSG_INFO,
1635 				"PostConnectivity Capability not present");
1636 	}
1637 
1638 	/* Print the discovery_attr */
1639 	sigma_dut_print(global_dut, DUT_MSG_INFO,
1640 			"Printing PostDiscovery Attribute");
1641 	if (event->num_rx_discovery_attr) {
1642 		int idx;
1643 
1644 		for (idx = 0; idx < event->num_rx_discovery_attr; idx++) {
1645 			sigma_dut_print(global_dut, DUT_MSG_INFO,
1646 					"PostDiscovery Attribute - %d", idx);
1647 			sigma_dut_print(global_dut, DUT_MSG_INFO,
1648 					"Conn Type:%d Device Role:%d"
1649 					MAC_ADDR_STR,
1650 					event->discovery_attr[idx].type,
1651 					event->discovery_attr[idx].role,
1652 					MAC_ADDR_ARRAY(event->discovery_attr[idx].addr));
1653 			sigma_dut_print(global_dut, DUT_MSG_INFO,
1654 					"Duration:%d MapId:%d "
1655 					"avail_interval_bitmap:%04x",
1656 					event->discovery_attr[idx].duration,
1657 					event->discovery_attr[idx].mapid,
1658 					event->discovery_attr[idx].avail_interval_bitmap);
1659 			sigma_dut_print(global_dut, DUT_MSG_INFO,
1660 					"Printing Mesh Id:");
1661 			nan_hex_dump(global_dut,
1662 				     event->discovery_attr[idx].mesh_id,
1663 				     event->discovery_attr[idx].mesh_id_len);
1664 			sigma_dut_print(global_dut, DUT_MSG_INFO,
1665 					"Printing Infrastructure Ssid:");
1666 			nan_hex_dump(global_dut,
1667 				     event->discovery_attr[idx].infrastructure_ssid_val,
1668 				     event->discovery_attr[idx].infrastructure_ssid_len);
1669 		}
1670 	} else {
1671 		sigma_dut_print(global_dut, DUT_MSG_INFO,
1672 				"PostDiscovery attribute not present");
1673 	}
1674 
1675 	/* Print the fam */
1676 	if (event->num_chans) {
1677 		nan_print_further_availability_chan(global_dut,
1678 						    event->num_chans,
1679 						    &event->famchan[0]);
1680 	} else {
1681 		sigma_dut_print(global_dut, DUT_MSG_INFO,
1682 				"Further Availability Map not present");
1683 	}
1684 	if (event->cluster_attribute_len) {
1685 		sigma_dut_print(global_dut, DUT_MSG_INFO,
1686 				"Printing Cluster Attribute:");
1687 		nan_hex_dump(global_dut, event->cluster_attribute,
1688 			     event->cluster_attribute_len);
1689 	} else {
1690 		sigma_dut_print(global_dut, DUT_MSG_INFO,
1691 				"Cluster Attribute not present");
1692 	}
1693 }
1694 
1695 
1696 /* Events Callback */
1697 void nan_event_match_expired(NanMatchExpiredInd *event)
1698 {
1699 	sigma_dut_print(global_dut, DUT_MSG_INFO,
1700 			"%s: publish_subscribe_id %d match_handle %08x",
1701 			__func__, event->publish_subscribe_id,
1702 			event->requestor_instance_id);
1703 }
1704 
1705 
1706 /* Events Callback */
1707 void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event)
1708 {
1709 	sigma_dut_print(global_dut, DUT_MSG_INFO,
1710 			"%s: Subscribe Id %d reason %d",
1711 			__func__, event->subscribe_id, event->reason);
1712 }
1713 
1714 
1715 /* Events Callback */
1716 void nan_event_followup(NanFollowupInd *event)
1717 {
1718 	sigma_dut_print(global_dut, DUT_MSG_INFO,
1719 			"%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d "
1720 			MAC_ADDR_STR, __func__, event->publish_subscribe_id,
1721 			event->requestor_instance_id, event->dw_or_faw,
1722 			MAC_ADDR_ARRAY(event->addr));
1723 
1724 	global_match_handle = event->requestor_instance_id;
1725 	global_header_handle = event->publish_subscribe_id;
1726 	sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__);
1727 	nan_hex_dump(global_dut, event->service_specific_info,
1728 		     event->service_specific_info_len);
1729 	event_anyresponse = 1;
1730 	snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1731 		 "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
1732 		 MAC_ADDR_STR " ", event->requestor_instance_id >> 24,
1733 		 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
1734 }
1735 
1736 
1737 /* Events Callback */
1738 void nan_event_disceng_event(NanDiscEngEventInd *event)
1739 {
1740 	sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d",
1741 			__func__, event->event_type);
1742 
1743 	if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) {
1744 		sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster "
1745 				MAC_ADDR_STR,
1746 				__func__,
1747 				MAC_ADDR_ARRAY(event->data.cluster.addr));
1748 		/* To ensure sta_get_events to get the events
1749 		 * only after joining the NAN cluster. */
1750 		pthread_cond_signal(&gCondition);
1751 	}
1752 	if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
1753 		sigma_dut_print(global_dut, DUT_MSG_INFO,
1754 				"%s: Started cluster " MAC_ADDR_STR,
1755 				__func__,
1756 				MAC_ADDR_ARRAY(event->data.cluster.addr));
1757 	}
1758 	if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) {
1759 		sigma_dut_print(global_dut, DUT_MSG_INFO,
1760 				"%s: Discovery Mac Address "
1761 				MAC_ADDR_STR,
1762 				__func__,
1763 				MAC_ADDR_ARRAY(event->data.mac_addr.addr));
1764 		memcpy(global_nan_mac_addr, event->data.mac_addr.addr,
1765 		       sizeof(global_nan_mac_addr));
1766 	}
1767 }
1768 
1769 
1770 /* Events Callback */
1771 void nan_event_disabled(NanDisabledInd *event)
1772 {
1773 	sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d",
1774 			__func__, event->reason);
1775 	/* pthread_cond_signal(&gCondition); */
1776 }
1777 
1778 
1779 /* Events callback */
1780 static void ndp_event_data_indication(NanDataPathRequestInd *event)
1781 {
1782 	sigma_dut_print(global_dut, DUT_MSG_INFO,
1783 			"%s: Service Instance Id: %d  Peer Discovery MAC ADDR "
1784 			MAC_ADDR_STR
1785 			" NDP Instance Id: %d App Info  len %d App Info %s",
1786 			__func__,
1787 			event->service_instance_id,
1788 			MAC_ADDR_ARRAY(event->peer_disc_mac_addr),
1789 			event->ndp_instance_id,
1790 			event->app_info.ndp_app_info_len,
1791 			event->app_info.ndp_app_info);
1792 
1793 	global_ndp_instance_id = event->ndp_instance_id;
1794 }
1795 
1796 
1797 /* Events callback */
1798 static void ndp_event_data_confirm(NanDataPathConfirmInd *event)
1799 {
1800 	char cmd[200];
1801 	char ipv6_buf[100];
1802 
1803 	sigma_dut_print(global_dut, DUT_MSG_INFO,
1804 			"Received NDP Confirm Indication");
1805 
1806 	memset(cmd, 0, sizeof(cmd));
1807 	memset(ipv6_buf, 0, sizeof(ipv6_buf));
1808 
1809 	global_ndp_instance_id = event->ndp_instance_id;
1810 
1811 	if (event->rsp_code == NAN_DP_REQUEST_ACCEPT) {
1812 		if (system("ifconfig nan0 up") != 0) {
1813 			sigma_dut_print(global_dut, DUT_MSG_ERROR,
1814 					"Failed to set nan interface up");
1815 			return;
1816 		}
1817 		if (system("ip -6 route add fe80::/64 dev nan0 table local") !=
1818 		    0) {
1819 			sigma_dut_print(global_dut, DUT_MSG_ERROR,
1820 					"Failed to run:ip -6 route replace fe80::/64 dev nan0 table local");
1821 		}
1822 		convert_mac_addr_to_ipv6_lladdr(event->peer_ndi_mac_addr,
1823 						ipv6_buf, sizeof(ipv6_buf));
1824 		snprintf(cmd, sizeof(cmd),
1825 			 "ip -6 neighbor replace %s lladdr %02x:%02x:%02x:%02x:%02x:%02x nud permanent dev nan0",
1826 			 ipv6_buf, event->peer_ndi_mac_addr[0],
1827 			 event->peer_ndi_mac_addr[1],
1828 			 event->peer_ndi_mac_addr[2],
1829 			 event->peer_ndi_mac_addr[3],
1830 			 event->peer_ndi_mac_addr[4],
1831 			 event->peer_ndi_mac_addr[5]);
1832 		sigma_dut_print(global_dut, DUT_MSG_INFO,
1833 				"neighbor replace cmd = %s", cmd);
1834 		if (system(cmd) != 0) {
1835 			sigma_dut_print(global_dut, DUT_MSG_ERROR,
1836 					"Failed to run: ip -6 neighbor replace");
1837 			return;
1838 		}
1839 	}
1840 }
1841 
1842 
1843 void * my_thread_function(void *ptr)
1844 {
1845 	wifi_event_loop(global_wifi_handle);
1846 	pthread_exit(0);
1847 	return (void *) NULL;
1848 }
1849 
1850 
1851 static NanCallbackHandler callbackHandler = {
1852 	.NotifyResponse = nan_notify_response,
1853 	.EventPublishReplied = nan_event_publish_replied,
1854 	.EventPublishTerminated = nan_event_publish_terminated,
1855 	.EventMatch = nan_event_match,
1856 	.EventMatchExpired = nan_event_match_expired,
1857 	.EventSubscribeTerminated = nan_event_subscribe_terminated,
1858 	.EventFollowup = nan_event_followup,
1859 	.EventDiscEngEvent = nan_event_disceng_event,
1860 	.EventDisabled = nan_event_disabled,
1861 	.EventDataRequest = ndp_event_data_indication,
1862 	.EventDataConfirm = ndp_event_data_confirm,
1863 };
1864 
1865 
1866 void nan_init(struct sigma_dut *dut)
1867 {
1868 	pthread_t thread1;	/* thread variables */
1869 	wifi_error err = wifi_initialize(&global_wifi_handle);
1870 
1871 	if (err) {
1872 		printf("wifi hal initialize failed\n");
1873 		return;
1874 	}
1875 
1876 	global_interface_handle = wifi_get_iface_handle(global_wifi_handle,
1877 							(char *) "wlan0");
1878 	/* create threads 1 */
1879 	pthread_create(&thread1, NULL, &my_thread_function, NULL);
1880 
1881 	pthread_mutex_init(&gMutex, NULL);
1882 	pthread_cond_init(&gCondition, NULL);
1883 	if (global_interface_handle)
1884 		nan_register_handler(global_interface_handle, callbackHandler);
1885 }
1886 
1887 
1888 void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1889 			       struct sigma_cmd *cmd)
1890 {
1891 	sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default");
1892 
1893 	if (nan_state == 0) {
1894 		nan_init(dut);
1895 		nan_state = 1;
1896 	}
1897 	is_fam = 0;
1898 	event_anyresponse = 0;
1899 	global_dut = dut;
1900 	memset(&dut->nan_pmk[0], 0, NAN_PMK_INFO_LEN);
1901 	dut->nan_pmk_len = 0;
1902 	dut->sta_channel = 0;
1903 	memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1904 	memset(&global_nan_sync_stats, 0, sizeof(global_nan_sync_stats));
1905 	memset(global_publish_service_name, 0,
1906 	       sizeof(global_publish_service_name));
1907 	global_publish_service_name_len = 0;
1908 	global_publish_id = 0;
1909 	global_subscribe_id = 0;
1910 
1911 	sigma_nan_data_end(dut, cmd);
1912 	nan_data_interface_delete(0, global_interface_handle, (char *) "nan0");
1913 	sigma_nan_disable(dut, conn, cmd);
1914 	global_header_handle = 0;
1915 	global_match_handle = 0;
1916 }
1917 
1918 
1919 int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1920 			    struct sigma_cmd *cmd)
1921 {
1922 	const char *program = get_param(cmd, "Prog");
1923 	const char *nan_op = get_param(cmd, "NANOp");
1924 	const char *method_type = get_param(cmd, "MethodType");
1925 	const char *band = get_param(cmd, "band");
1926 	char resp_buf[100];
1927 	wifi_error ret;
1928 
1929 	if (program == NULL)
1930 		return -1;
1931 
1932 	if (strcasecmp(program, "NAN") != 0) {
1933 		send_resp(dut, conn, SIGMA_ERROR,
1934 			  "ErrorCode,Unsupported program");
1935 		return 0;
1936 	}
1937 
1938 	if (nan_op) {
1939 #if NAN_CERT_VERSION >= 3
1940 		int size = 0;
1941 		u32 device_type_val = 0;
1942 		NanDebugParams cfg_debug;
1943 
1944 		memset(&cfg_debug, 0, sizeof(NanDebugParams));
1945 		cfg_debug.cmd = NAN_TEST_MODE_CMD_DEVICE_TYPE;
1946 		if (dut->device_type == STA_testbed)
1947 			device_type_val = NAN_DEVICE_TYPE_TEST_BED;
1948 		else if (dut->device_type == STA_dut)
1949 			device_type_val = NAN_DEVICE_TYPE_DUT;
1950 
1951 		memcpy(cfg_debug.debug_cmd_data, &device_type_val, sizeof(u32));
1952 		size = sizeof(u32) + sizeof(u32);
1953 		sigma_dut_print(dut, DUT_MSG_INFO,
1954 				"%s: Device Type: cmd type = %d and command data = %u",
1955 				__func__, cfg_debug.cmd, device_type_val);
1956 		nan_debug_command_config(0, global_interface_handle,
1957 					 cfg_debug, size);
1958 #endif
1959 		/*
1960 		 * NANOp has been specified.
1961 		 * We will build a nan_enable or nan_disable command.
1962 		*/
1963 		if (strcasecmp(nan_op, "On") == 0) {
1964 			if (sigma_nan_enable(dut, conn, cmd) == 0) {
1965 				ret = nan_data_interface_create(
1966 					0, global_interface_handle,
1967 					(char *) "nan0");
1968 				if (ret != WIFI_SUCCESS) {
1969 					sigma_dut_print(
1970 						global_dut, DUT_MSG_ERROR,
1971 						"Unable to create NAN data interface");
1972 				}
1973 				snprintf(resp_buf, sizeof(resp_buf), "mac,"
1974 					 MAC_ADDR_STR,
1975 					 MAC_ADDR_ARRAY(global_nan_mac_addr));
1976 				send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1977 			} else {
1978 				send_resp(dut, conn, SIGMA_ERROR,
1979 					  "NAN_ENABLE_FAILED");
1980 				return -1;
1981 			}
1982 
1983 			if (band && strcasecmp(band, "24g") == 0) {
1984 				sigma_dut_print(dut, DUT_MSG_INFO,
1985 						"%s: Setting band to 2G Only",
1986 						__func__);
1987 				sigma_ndp_configure_band(
1988 					dut, conn, cmd,
1989 					NAN_DATA_PATH_SUPPORTED_BAND_2G);
1990 			} else if (band && dut->sta_channel > 12) {
1991 				sigma_ndp_configure_band(
1992 					dut, conn, cmd,
1993 					NAN_DATA_PATH_SUPPORT_DUAL_BAND);
1994 			}
1995 		} else if (strcasecmp(nan_op, "Off") == 0) {
1996 			nan_data_interface_delete(0,
1997 				global_interface_handle, (char *) "nan0");
1998 			sigma_nan_disable(dut, conn, cmd);
1999 			memset(global_publish_service_name, 0,
2000 			       sizeof(global_publish_service_name));
2001 			global_publish_service_name_len = 0;
2002 			global_publish_id = 0;
2003 			global_subscribe_id = 0;
2004 			global_header_handle = 0;
2005 			global_match_handle = 0;
2006 			send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2007 		}
2008 	}
2009 	if (nan_state && nan_op == NULL) {
2010 		if (method_type) {
2011 			if (strcasecmp(method_type, "Publish") == 0) {
2012 				sigma_nan_publish_request(dut, conn, cmd);
2013 				send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2014 			}
2015 			if (strcasecmp(method_type, "Subscribe") == 0) {
2016 				sigma_nan_subscribe_request(dut, conn, cmd);
2017 				send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2018 			}
2019 			if (strcasecmp(method_type, "Followup") == 0) {
2020 				sigma_nan_transmit_followup(dut, conn, cmd);
2021 				send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2022 			}
2023 			if (strcasecmp(method_type, "DataRequest") == 0) {
2024 				sigma_nan_data_request(dut, conn, cmd);
2025 				send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2026 			}
2027 			if (strcasecmp(method_type, "DataResponse") == 0) {
2028 				sigma_dut_print(dut, DUT_MSG_INFO,
2029 						"%s: method_type is DataResponse",
2030 						__func__);
2031 				sigma_nan_data_response(dut, conn, cmd);
2032 				send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2033 			}
2034 			if (strcasecmp(method_type, "DataEnd") == 0) {
2035 				sigma_nan_data_end(dut, cmd);
2036 				send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2037 			}
2038 			if (strcasecmp(method_type, "rangerequest") == 0) {
2039 				sigma_dut_print(dut, DUT_MSG_INFO,
2040 						"%s: method_type is rangerequest",
2041 						__func__);
2042 				sigma_nan_range_request(dut, cmd);
2043 				send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2044 			}
2045 			if (strcasecmp(method_type, "cancelrange") == 0) {
2046 				sigma_dut_print(dut, DUT_MSG_INFO,
2047 						"%s: method_type is cancelrange",
2048 						__func__);
2049 				sigma_nan_cancel_range(dut, cmd);
2050 				send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2051 			}
2052 			if (strcasecmp(method_type, "SchedUpdate") == 0) {
2053 				sigma_dut_print(dut, DUT_MSG_INFO,
2054 						"%s: method_type is SchedUpdate",
2055 						__func__);
2056 				sigma_nan_schedule_update(dut, cmd);
2057 				send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2058 			}
2059 		} else {
2060 			sigma_nan_config_enable(dut, conn, cmd);
2061 			snprintf(resp_buf, sizeof(resp_buf), "mac,"
2062 				 MAC_ADDR_STR,
2063 				 MAC_ADDR_ARRAY(global_nan_mac_addr));
2064 			send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
2065 		}
2066 	}
2067 
2068 	return 0;
2069 }
2070 
2071 
2072 int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
2073 			      struct sigma_cmd *cmd)
2074 {
2075 
2076 	const char *program = get_param(cmd, "Program");
2077 	const char *parameter = get_param(cmd, "Parameter");
2078 	char resp_buf[100];
2079 	NanStatsRequest req;
2080 	struct timespec abstime;
2081 	u64 master_rank;
2082 	u8 master_pref;
2083 	u8 random_factor;
2084 	u8 hop_count;
2085 	u32 beacon_transmit_time;
2086 	u32 ndp_channel_freq;
2087 	u32 ndp_channel_freq2;
2088 #if NAN_CERT_VERSION >= 3
2089 	u32 sched_update_channel_freq;
2090 #endif
2091 
2092 	if (program == NULL) {
2093 		sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name");
2094 		return -1;
2095 	}
2096 	if (strcasecmp(program, "NAN") != 0) {
2097 		send_resp(dut, conn, SIGMA_ERROR,
2098 			  "ErrorCode,Unsupported program");
2099 		return 0;
2100 	}
2101 
2102 	if (parameter == NULL) {
2103 		sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter");
2104 		return -1;
2105 	}
2106 
2107 	memset(&req, 0, sizeof(NanStatsRequest));
2108 	memset(resp_buf, 0, sizeof(resp_buf));
2109 	req.stats_type = (NanStatsType) NAN_STATS_ID_DE_TIMING_SYNC;
2110 	nan_stats_request(0, global_interface_handle, &req);
2111 	/*
2112 	 * To ensure sta_get_events to get the events
2113 	 * only after joining the NAN cluster
2114 	 */
2115 	abstime.tv_sec = 4;
2116 	abstime.tv_nsec = 0;
2117 	wait(abstime);
2118 
2119 	master_rank = global_nan_sync_stats.myRank;
2120 	master_pref = (global_nan_sync_stats.myRank & 0xFF00000000000000) >> 56;
2121 	random_factor = (global_nan_sync_stats.myRank & 0x00FF000000000000) >>
2122 		48;
2123 	hop_count = global_nan_sync_stats.currAmHopCount;
2124 	beacon_transmit_time = global_nan_sync_stats.currAmBTT;
2125 	ndp_channel_freq = global_nan_sync_stats.ndpChannelFreq;
2126 	ndp_channel_freq2 = global_nan_sync_stats.ndpChannelFreq2;
2127 #if NAN_CERT_VERSION >= 3
2128 	sched_update_channel_freq =
2129 		global_nan_sync_stats.schedUpdateChannelFreq;
2130 
2131 	sigma_dut_print(dut, DUT_MSG_INFO,
2132 			"%s: NanStatsRequest Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d ndp_channel_freq:%d ndp_channel_freq2:%d sched_update_channel_freq:%d",
2133 			__func__, master_pref, random_factor,
2134 			hop_count, beacon_transmit_time,
2135 			ndp_channel_freq, ndp_channel_freq2,
2136 			sched_update_channel_freq);
2137 #else /* #if NAN_CERT_VERSION >= 3 */
2138 	sigma_dut_print(dut, DUT_MSG_INFO,
2139 			"%s: NanStatsRequest Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d ndp_channel_freq:%d ndp_channel_freq2:%d",
2140 			__func__, master_pref, random_factor,
2141 			hop_count, beacon_transmit_time,
2142 			ndp_channel_freq, ndp_channel_freq2);
2143 #endif /* #if NAN_CERT_VERSION >= 3 */
2144 
2145 	if (strcasecmp(parameter, "MasterPref") == 0) {
2146 		snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x",
2147 			 master_pref);
2148 	} else if (strcasecmp(parameter, "MasterRank") == 0) {
2149 		snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx",
2150 			 master_rank);
2151 	} else if (strcasecmp(parameter, "RandFactor") == 0) {
2152 		snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x",
2153 			 random_factor);
2154 	} else if (strcasecmp(parameter, "HopCount") == 0) {
2155 		snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x",
2156 			 hop_count);
2157 	} else if (strcasecmp(parameter, "BeaconTransTime") == 0) {
2158 		snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x",
2159 			 beacon_transmit_time);
2160 	} else if (strcasecmp(parameter, "NANStatus") == 0) {
2161 		if (nan_state == 1)
2162 			snprintf(resp_buf, sizeof(resp_buf), "On");
2163 		else
2164 			snprintf(resp_buf, sizeof(resp_buf), "Off");
2165 	} else if (strcasecmp(parameter, "NDPChannel") == 0) {
2166 		if (ndp_channel_freq != 0 && ndp_channel_freq2 != 0) {
2167 			snprintf(resp_buf, sizeof(resp_buf),
2168 				 "ndpchannel,%d,ndpchannel,%d",
2169 				 freq_to_channel(ndp_channel_freq),
2170 				 freq_to_channel(ndp_channel_freq2));
2171 		} else if (ndp_channel_freq != 0) {
2172 			snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
2173 				 freq_to_channel(ndp_channel_freq));
2174 		} else if (ndp_channel_freq2 != 0) {
2175 			snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
2176 				 freq_to_channel(ndp_channel_freq2));
2177 		} else {
2178 			sigma_dut_print(dut, DUT_MSG_ERROR,
2179 				"%s: No Negotiated NDP Channels", __func__);
2180 		}
2181 #if NAN_CERT_VERSION >= 3
2182 	} else if (strcasecmp(parameter, "SchedUpdateChannel") == 0) {
2183 		snprintf(resp_buf, sizeof(resp_buf), "schedupdatechannel,%d",
2184 			 freq_to_channel(sched_update_channel_freq));
2185 #endif
2186 	} else {
2187 		send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
2188 		return 0;
2189 	}
2190 
2191 	send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
2192 	return 0;
2193 }
2194 
2195 
2196 int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
2197 			   struct sigma_cmd *cmd)
2198 {
2199 	const char *action = get_param(cmd, "Action");
2200 
2201 	if (!action)
2202 		return 0;
2203 
2204 	/* Check action for start, stop and get events. */
2205 	if (strcasecmp(action, "Start") == 0) {
2206 		memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
2207 		send_resp(dut, conn, SIGMA_COMPLETE, NULL);
2208 	} else if (strcasecmp(action, "Stop") == 0) {
2209 		event_anyresponse = 0;
2210 		memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
2211 		send_resp(dut, conn, SIGMA_COMPLETE, NULL);
2212 	} else if (strcasecmp(action, "Get") == 0) {
2213 		if (event_anyresponse == 1) {
2214 			send_resp(dut, conn, SIGMA_COMPLETE,
2215 				  global_event_resp_buf);
2216 		} else {
2217 			send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE");
2218 		}
2219 	}
2220 	return 0;
2221 }
2222 
2223 #else /* #if NAN_CERT_VERSION */
2224 
2225 int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
2226 				      struct sigma_conn *conn,
2227 				      struct sigma_cmd *cmd)
2228 {
2229 	return 1;
2230 }
2231 
2232 
2233 int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
2234 			      struct sigma_cmd *cmd)
2235 {
2236 	return 0;
2237 
2238 }
2239 
2240 
2241 void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
2242 			       struct sigma_cmd *cmd)
2243 {
2244 	return;
2245 }
2246 
2247 
2248 int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
2249 			   struct sigma_cmd *cmd)
2250 {
2251 	return 0;
2252 }
2253 
2254 
2255 int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
2256 			    struct sigma_cmd *cmd)
2257 {
2258 	return 0;
2259 }
2260 
2261 #endif /* #if NAN_CERT_VERSION */
2262