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