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