blob: d184019bd4c1f7a58e93ba3dc71d80f4b31b33a4 [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (NAN functionality)
Rakesh Sunki4b75f962017-03-30 14:47:55 -07003 * Copyright (c) 2014-2017, Qualcomm Atheros, Inc.
Peng Xu8863ec72018-08-06 11:50:37 -07004 * Copyright (c) 2018, The Linux Foundation
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005 * 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 "wifi_hal.h"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -070014#include "nan_cert.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015
Rakesh Sunki4b75f962017-03-30 14:47:55 -070016#if NAN_CERT_VERSION >= 2
17
Jouni Malinencd4e3c32015-10-29 12:39:56 +020018pthread_cond_t gCondition;
19pthread_mutex_t gMutex;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -070020wifi_handle global_wifi_handle;
21wifi_interface_handle global_interface_handle;
Rakesh Sunkid51e8982017-03-30 14:47:55 -070022static NanSyncStats global_nan_sync_stats;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020023static int nan_state = 0;
24static int event_anyresponse = 0;
25static int is_fam = 0;
26
Rakesh Sunki4c086672017-03-30 14:47:55 -070027static uint16_t global_ndp_instance_id = 0;
Rakesh Sunki4d5912d2017-03-30 14:47:55 -070028static uint16_t global_publish_id = 0;
29static uint16_t global_subscribe_id = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020030uint16_t global_header_handle = 0;
31uint32_t global_match_handle = 0;
32
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -070033#define DEFAULT_SVC "QNanCluster"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020034#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
35#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
36#ifndef ETH_ALEN
37#define ETH_ALEN 6
38#endif
39
40struct sigma_dut *global_dut = NULL;
41static char global_nan_mac_addr[ETH_ALEN];
Rakesh Sunki14cfcd22017-03-30 14:47:55 -070042static char global_peer_mac_addr[ETH_ALEN];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020043static char global_event_resp_buf[1024];
Rakesh Sunki42363682017-05-16 15:00:42 -070044static u8 global_publish_service_name[NAN_MAX_SERVICE_NAME_LEN];
45static u32 global_publish_service_name_len = 0;
Rakesh Sunki74f4f992017-08-16 15:21:52 -070046static u8 global_subscribe_service_name[NAN_MAX_SERVICE_NAME_LEN];
47static u32 global_subscribe_service_name_len = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020048
49static int nan_further_availability_tx(struct sigma_dut *dut,
50 struct sigma_conn *conn,
51 struct sigma_cmd *cmd);
52static int nan_further_availability_rx(struct sigma_dut *dut,
53 struct sigma_conn *conn,
54 struct sigma_cmd *cmd);
55
56
57void nan_hex_dump(struct sigma_dut *dut, uint8_t *data, size_t len)
58{
59 char buf[512];
60 uint16_t index;
61 uint8_t *ptr;
62 int pos;
63
64 memset(buf, 0, sizeof(buf));
65 ptr = data;
66 pos = 0;
67 for (index = 0; index < len; index++) {
Peng Xu6734e232017-10-04 10:10:33 -070068 pos += snprintf(&(buf[pos]), sizeof(buf) - pos,
69 "%02x ", *ptr++);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020070 if (pos > 508)
71 break;
72 }
73 sigma_dut_print(dut, DUT_MSG_INFO, "HEXDUMP len=[%d]", (int) len);
74 sigma_dut_print(dut, DUT_MSG_INFO, "buf:%s", buf);
75}
76
77
78int nan_parse_hex(unsigned char c)
79{
80 if (c >= '0' && c <= '9')
81 return c - '0';
82 if (c >= 'a' && c <= 'f')
83 return c - 'a' + 10;
84 if (c >= 'A' && c <= 'F')
85 return c - 'A' + 10;
86 return 0;
87}
88
89
90int nan_parse_token(const char *tokenIn, u8 *tokenOut, int *filterLen)
91{
92 int total_len = 0, len = 0;
93 char *saveptr = NULL;
94
95 tokenIn = strtok_r((char *) tokenIn, ":", &saveptr);
96 while (tokenIn != NULL) {
97 len = strlen(tokenIn);
98 if (len == 1 && *tokenIn == '*')
99 len = 0;
100 tokenOut[total_len++] = (u8) len;
101 if (len != 0)
102 memcpy((u8 *) tokenOut + total_len, tokenIn, len);
103 total_len += len;
104 tokenIn = strtok_r(NULL, ":", &saveptr);
105 }
106 *filterLen = total_len;
107 return 0;
108}
109
110
111int nan_parse_mac_address(struct sigma_dut *dut, const char *arg, u8 *addr)
112{
113 if (strlen(arg) != 17) {
114 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid mac address %s",
115 arg);
116 sigma_dut_print(dut, DUT_MSG_ERROR,
117 "expected format xx:xx:xx:xx:xx:xx");
118 return -1;
119 }
120
121 addr[0] = nan_parse_hex(arg[0]) << 4 | nan_parse_hex(arg[1]);
122 addr[1] = nan_parse_hex(arg[3]) << 4 | nan_parse_hex(arg[4]);
123 addr[2] = nan_parse_hex(arg[6]) << 4 | nan_parse_hex(arg[7]);
124 addr[3] = nan_parse_hex(arg[9]) << 4 | nan_parse_hex(arg[10]);
125 addr[4] = nan_parse_hex(arg[12]) << 4 | nan_parse_hex(arg[13]);
126 addr[5] = nan_parse_hex(arg[15]) << 4 | nan_parse_hex(arg[16]);
127
128 return 0;
129}
130
131
132int nan_parse_mac_address_list(struct sigma_dut *dut, const char *input,
133 u8 *output, u16 max_addr_allowed)
134{
135 /*
136 * Reads a list of mac address separated by space. Each MAC address
137 * should have the format of aa:bb:cc:dd:ee:ff.
138 */
139 char *saveptr;
140 char *token;
141 int i = 0;
142
143 for (i = 0; i < max_addr_allowed; i++) {
144 token = strtok_r((i == 0) ? (char *) input : NULL,
145 " ", &saveptr);
146 if (token) {
147 nan_parse_mac_address(dut, token, output);
148 output += NAN_MAC_ADDR_LEN;
149 } else
150 break;
151 }
152
153 sigma_dut_print(dut, DUT_MSG_INFO, "Num MacAddress:%d", i);
154
155 return i;
156}
157
158
159int nan_parse_hex_string(struct sigma_dut *dut, const char *input,
160 u8 *output, int *outputlen)
161{
162 int i = 0;
163 int j = 0;
164
165 for (i = 0; i < (int) strlen(input) && j < *outputlen; i += 2) {
166 output[j] = nan_parse_hex(input[i]);
167 if (i + 1 < (int) strlen(input)) {
168 output[j] = ((output[j] << 4) |
169 nan_parse_hex(input[i + 1]));
170 }
171 j++;
172 }
173 *outputlen = j;
174 sigma_dut_print(dut, DUT_MSG_INFO, "Input:%s inputlen:%d outputlen:%d",
175 input, (int) strlen(input), (int) *outputlen);
176 return 0;
177}
178
179
180int wait(struct timespec abstime)
181{
182 struct timeval now;
183
184 gettimeofday(&now, NULL);
185
186 abstime.tv_sec += now.tv_sec;
187 if (((abstime.tv_nsec + now.tv_usec * 1000) > 1000 * 1000 * 1000) ||
188 (abstime.tv_nsec + now.tv_usec * 1000 < 0)) {
189 abstime.tv_sec += 1;
190 abstime.tv_nsec += now.tv_usec * 1000;
191 abstime.tv_nsec -= 1000 * 1000 * 1000;
192 } else {
193 abstime.tv_nsec += now.tv_usec * 1000;
194 }
195
196 return pthread_cond_timedwait(&gCondition, &gMutex, &abstime);
197}
198
199
200int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
201 struct sigma_conn *conn,
202 struct sigma_cmd *cmd)
203{
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700204 const char *oper_chan = get_param(cmd, "oper_chn");
Rakesh Sunki7d37f412017-03-30 14:47:55 -0700205 const char *pmk = get_param(cmd, "PMK");
Peng Xu7be50b12018-10-11 15:50:13 -0700206#if ((NAN_MAJOR_VERSION > 2) || \
207 (NAN_MAJOR_VERSION == 2 && NAN_MINOR_VERSION >= 1)) && \
208 NAN_CERT_VERSION >= 5
Peng Xu57d7ead2018-08-06 11:53:47 -0700209 const char *ndpe = get_param(cmd, "NDPE");
210 const char *trans_proto = get_param(cmd, "TransProtoType");
211 const char *ndp_attr = get_param(cmd, "ndpAttr");
212#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200213
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700214 if (oper_chan) {
215 sigma_dut_print(dut, DUT_MSG_INFO, "Operating Channel: %s",
216 oper_chan);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700217 dut->sta_channel = atoi(oper_chan);
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700218 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200219
Rakesh Sunki7d37f412017-03-30 14:47:55 -0700220 if (pmk) {
221 int pmk_len;
222
223 sigma_dut_print(dut, DUT_MSG_INFO, "%s given string pmk: %s",
224 __func__, pmk);
225 memset(dut->nan_pmk, 0, NAN_PMK_INFO_LEN);
226 dut->nan_pmk_len = 0;
227 pmk_len = NAN_PMK_INFO_LEN;
228 nan_parse_hex_string(dut, &pmk[2], &dut->nan_pmk[0], &pmk_len);
229 dut->nan_pmk_len = pmk_len;
230 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
231 __func__, dut->nan_pmk_len);
232 sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex pmk", __func__);
233 nan_hex_dump(dut, &dut->nan_pmk[0], dut->nan_pmk_len);
234 }
235
Peng Xu7be50b12018-10-11 15:50:13 -0700236#if ((NAN_MAJOR_VERSION > 2) || \
237 (NAN_MAJOR_VERSION == 2 && NAN_MINOR_VERSION >= 1)) && \
238 NAN_CERT_VERSION >= 5
Peng Xu57d7ead2018-08-06 11:53:47 -0700239 if (ndpe) {
240 NanConfigRequest req;
241 wifi_error ret;
242
243 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: NDPE: %s",
244 __func__, ndpe);
245 memset(&req, 0, sizeof(NanConfigRequest));
246 dut->ndpe = strcasecmp(ndpe, "Enable") == 0;
247 req.config_ndpe_attr = 1;
248 req.use_ndpe_attr = dut->ndpe;
249 ret = nan_config_request(0, global_interface_handle, &req);
250 if (ret != WIFI_SUCCESS) {
251 send_resp(dut, conn, SIGMA_ERROR,
252 "NAN config request failed");
253 return 0;
254 }
255 }
256
257 if (trans_proto) {
258 sigma_dut_print(dut, DUT_MSG_INFO, "%s: Transport protocol: %s",
259 __func__, trans_proto);
260 if (strcasecmp(trans_proto, "TCP") == 0) {
261 dut->trans_proto = TRANSPORT_PROTO_TYPE_TCP;
262 } else if (strcasecmp(trans_proto, "UDP") == 0) {
263 dut->trans_proto = TRANSPORT_PROTO_TYPE_UDP;
264 } else {
265 sigma_dut_print(dut, DUT_MSG_ERROR,
266 "%s: Invalid protocol %s, set to TCP",
267 __func__, trans_proto);
268 dut->trans_proto = TRANSPORT_PROTO_TYPE_TCP;
269 }
270 }
271
272 if (dut->ndpe && ndp_attr) {
273 NanDebugParams cfg_debug;
274 int ndp_attr_val;
275 int ret, size;
276
277 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: NDP Attr: %s",
278 __func__, ndp_attr);
279
280 memset(&cfg_debug, 0, sizeof(NanDebugParams));
281 cfg_debug.cmd = NAN_TEST_MODE_CMD_ENABLE_NDP;
282 if (strcasecmp(ndp_attr, "Absent") == 0)
283 ndp_attr_val = NAN_NDP_ATTR_ABSENT;
284 else
285 ndp_attr_val = NAN_NDP_ATTR_PRESENT;
286 memcpy(cfg_debug.debug_cmd_data, &ndp_attr_val, sizeof(int));
287 size = sizeof(u32) + sizeof(int);
288 ret = nan_debug_command_config(0, global_interface_handle,
289 cfg_debug, size);
290 if (ret != WIFI_SUCCESS) {
291 send_resp(dut, conn, SIGMA_ERROR,
292 "NAN config ndpAttr failed");
293 return 0;
294 }
295 }
296#endif
297
Rakesh Sunki14bff1d2017-03-30 14:47:55 -0700298 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200299 return 0;
300}
301
302
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700303void nan_print_further_availability_chan(struct sigma_dut *dut,
304 u8 num_chans,
305 NanFurtherAvailabilityChannel *fachan)
306{
307 int idx;
308
309 sigma_dut_print(dut, DUT_MSG_INFO,
310 "********Printing FurtherAvailabilityChan Info******");
311 sigma_dut_print(dut, DUT_MSG_INFO, "Numchans:%d", num_chans);
312 for (idx = 0; idx < num_chans; idx++) {
313 sigma_dut_print(dut, DUT_MSG_INFO,
314 "[%d]: NanAvailDuration:%d class_val:%02x channel:%d",
315 idx, fachan->entry_control,
316 fachan->class_val, fachan->channel);
317 sigma_dut_print(dut, DUT_MSG_INFO,
318 "[%d]: mapid:%d Availability bitmap:%08x",
319 idx, fachan->mapid,
320 fachan->avail_interval_bitmap);
321 }
322 sigma_dut_print(dut, DUT_MSG_INFO,
323 "*********************Done**********************");
324}
325
326
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200327int sigma_nan_enable(struct sigma_dut *dut, struct sigma_conn *conn,
328 struct sigma_cmd *cmd)
329{
330 const char *master_pref = get_param(cmd, "MasterPref");
331 const char *rand_fac = get_param(cmd, "RandFactor");
332 const char *hop_count = get_param(cmd, "HopCount");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200333 const char *sdftx_band = get_param(cmd, "SDFTxBand");
334 const char *oper_chan = get_param(cmd, "oper_chn");
335 const char *further_avail_ind = get_param(cmd, "FurtherAvailInd");
336 const char *band = get_param(cmd, "Band");
337 const char *only_5g = get_param(cmd, "5GOnly");
Rakesh Sunki38dd72e2017-03-30 14:47:55 -0700338 const char *nan_availability = get_param(cmd, "NANAvailability");
Peng Xu7be50b12018-10-11 15:50:13 -0700339#if ((NAN_MAJOR_VERSION > 2) || \
340 (NAN_MAJOR_VERSION == 2 && NAN_MINOR_VERSION >= 1)) && \
341 NAN_CERT_VERSION >= 5
Peng Xu8863ec72018-08-06 11:50:37 -0700342 const char *ndpe = get_param(cmd, "NDPE");
343#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200344 struct timespec abstime;
345 NanEnableRequest req;
346
347 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200348 req.cluster_low = 0;
349 req.cluster_high = 0xFFFF;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700350 req.master_pref = 100;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200351
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700352 /* This is a debug hack to beacon in channel 11 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200353 if (oper_chan) {
354 req.config_2dot4g_support = 1;
355 req.support_2dot4g_val = 111;
356 }
357
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200358 if (master_pref) {
359 int master_pref_val = strtoul(master_pref, NULL, 0);
360
361 req.master_pref = master_pref_val;
362 }
363
364 if (rand_fac) {
365 int rand_fac_val = strtoul(rand_fac, NULL, 0);
366
367 req.config_random_factor_force = 1;
368 req.random_factor_force_val = rand_fac_val;
369 }
370
371 if (hop_count) {
372 int hop_count_val = strtoul(hop_count, NULL, 0);
373
374 req.config_hop_count_force = 1;
375 req.hop_count_force_val = hop_count_val;
376 }
377
378 if (sdftx_band) {
379 if (strcasecmp(sdftx_band, "5G") == 0) {
380 req.config_2dot4g_support = 1;
381 req.support_2dot4g_val = 0;
382 }
383 }
384
Peng Xu7be50b12018-10-11 15:50:13 -0700385#if ((NAN_MAJOR_VERSION > 2) || \
386 (NAN_MAJOR_VERSION == 2 && NAN_MINOR_VERSION >= 1)) && \
387 NAN_CERT_VERSION >= 5
Peng Xu8863ec72018-08-06 11:50:37 -0700388 if (ndpe) {
389 if (strcasecmp(ndpe, "Enable") == 0) {
390 dut->ndpe = 1;
391 req.config_ndpe_attr = 1;
392 req.use_ndpe_attr = 1;
393 } else {
394 dut->ndpe = 0;
395 req.config_ndpe_attr = 1;
396 req.use_ndpe_attr = 0;
397 }
398 req.config_disc_mac_addr_randomization = 1;
399 req.disc_mac_addr_rand_interval_sec = 0;
400 }
401#endif
402
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700403 sigma_dut_print(dut, DUT_MSG_INFO,
404 "%s: Setting dual band 2.4 GHz and 5 GHz by default",
405 __func__);
406 /* Enable 2.4 GHz support */
407 req.config_2dot4g_support = 1;
408 req.support_2dot4g_val = 1;
409 req.config_2dot4g_beacons = 1;
410 req.beacon_2dot4g_val = 1;
411 req.config_2dot4g_sdf = 1;
412 req.sdf_2dot4g_val = 1;
413
414 /* Enable 5 GHz support */
415 req.config_support_5g = 1;
416 req.support_5g_val = 1;
417 req.config_5g_beacons = 1;
418 req.beacon_5g_val = 1;
419 req.config_5g_sdf = 1;
420 req.sdf_5g_val = 1;
421
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200422 if (band) {
423 if (strcasecmp(band, "24G") == 0) {
424 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700425 "Band 2.4 GHz selected, disable 5 GHz");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200426 /* Disable 5G support */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700427 req.config_support_5g = 1;
428 req.support_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200429 req.config_5g_beacons = 1;
430 req.beacon_5g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700431 req.config_5g_sdf = 1;
432 req.sdf_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200433 }
434 }
435
436 if (further_avail_ind) {
437 sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled");
438 if (strcasecmp(further_avail_ind, "tx") == 0) {
439 is_fam = 1;
440 nan_further_availability_tx(dut, conn, cmd);
441 return 0;
442 } else if (strcasecmp(further_avail_ind, "rx") == 0) {
443 nan_further_availability_rx(dut, conn, cmd);
444 return 0;
445 }
446 }
447
448 if (only_5g && atoi(only_5g)) {
449 sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled");
450 req.config_2dot4g_support = 1;
451 req.support_2dot4g_val = 1;
452 req.config_2dot4g_beacons = 1;
453 req.beacon_2dot4g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700454 req.config_2dot4g_sdf = 1;
455 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200456 }
457
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700458 nan_enable_request(0, global_interface_handle, &req);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700459
Rakesh Sunki38dd72e2017-03-30 14:47:55 -0700460 if (nan_availability) {
461 int cmd_len, size;
462 NanDebugParams cfg_debug;
463
464 sigma_dut_print(dut, DUT_MSG_INFO,
465 "%s given string nan_availability: %s",
466 __func__, nan_availability);
467 memset(&cfg_debug, 0, sizeof(NanDebugParams));
468 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY;
469 size = NAN_MAX_DEBUG_MESSAGE_DATA_LEN;
470 nan_parse_hex_string(dut, &nan_availability[2],
471 &cfg_debug.debug_cmd_data[0], &size);
472 sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex nan_availability",
473 __func__);
474 nan_hex_dump(dut, &cfg_debug.debug_cmd_data[0], size);
475 cmd_len = size + sizeof(u32);
476 nan_debug_command_config(0, global_interface_handle,
477 cfg_debug, cmd_len);
478 }
479
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700480 /* To ensure sta_get_events to get the events
481 * only after joining the NAN cluster. */
482 abstime.tv_sec = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200483 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700484 wait(abstime);
485
486 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200487}
488
489
490int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn,
491 struct sigma_cmd *cmd)
492{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200493 struct timespec abstime;
494
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700495 nan_disable_request(0, global_interface_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200496
497 abstime.tv_sec = 4;
498 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700499 wait(abstime);
500
501 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200502}
503
504
505int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn,
506 struct sigma_cmd *cmd)
507{
508 const char *master_pref = get_param(cmd, "MasterPref");
509 const char *rand_fac = get_param(cmd, "RandFactor");
510 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700511 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200512 struct timespec abstime;
513 NanConfigRequest req;
514
515 memset(&req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200516 req.config_rssi_proximity = 1;
517 req.rssi_proximity = 70;
518
519 if (master_pref) {
520 int master_pref_val = strtoul(master_pref, NULL, 0);
521
522 req.config_master_pref = 1;
523 req.master_pref = master_pref_val;
524 }
525
526 if (rand_fac) {
527 int rand_fac_val = strtoul(rand_fac, NULL, 0);
528
529 req.config_random_factor_force = 1;
530 req.random_factor_force_val = rand_fac_val;
531 }
532
533 if (hop_count) {
534 int hop_count_val = strtoul(hop_count, NULL, 0);
535
536 req.config_hop_count_force = 1;
537 req.hop_count_force_val = hop_count_val;
538 }
539
Rakesh Sunki107356c2017-03-30 14:47:55 -0700540 ret = nan_config_request(0, global_interface_handle, &req);
541 if (ret != WIFI_SUCCESS)
542 send_resp(dut, conn, SIGMA_ERROR, "NAN config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200543
544 abstime.tv_sec = 4;
545 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700546 wait(abstime);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200547
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700548 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200549}
550
551
552static int sigma_nan_subscribe_request(struct sigma_dut *dut,
553 struct sigma_conn *conn,
554 struct sigma_cmd *cmd)
555{
556 const char *subscribe_type = get_param(cmd, "SubscribeType");
557 const char *service_name = get_param(cmd, "ServiceName");
558 const char *disc_range = get_param(cmd, "DiscoveryRange");
559 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
560 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
561 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
562 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
563 const char *include_bit = get_param(cmd, "IncludeBit");
564 const char *mac = get_param(cmd, "MAC");
565 const char *srf_type = get_param(cmd, "SRFType");
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -0700566#if NAN_CERT_VERSION >= 3
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700567 const char *awake_dw_interval = get_param(cmd, "awakeDWint");
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -0700568#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200569 NanSubscribeRequest req;
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700570 NanConfigRequest config_req;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200571 int filter_len_rx = 0, filter_len_tx = 0;
572 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
573 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700574 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200575
576 memset(&req, 0, sizeof(NanSubscribeRequest));
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700577 memset(&config_req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200578 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -0700579 req.period = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200580 req.subscribe_type = 1;
581 req.serviceResponseFilter = 1; /* MAC */
582 req.serviceResponseInclude = 0;
583 req.ssiRequiredForMatchIndication = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700584 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200585 req.subscribe_count = 0;
586
Rakesh Sunki74f4f992017-08-16 15:21:52 -0700587 if (global_subscribe_service_name_len &&
588 service_name &&
589 strcasecmp((char *) global_subscribe_service_name,
590 service_name) == 0 &&
591 global_subscribe_id) {
592 req.subscribe_id = global_subscribe_id;
593 sigma_dut_print(dut, DUT_MSG_INFO,
594 "%s: updating subscribe_id = %d in subscribe request",
595 __func__, req.subscribe_id);
596 }
597
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200598 if (subscribe_type) {
599 if (strcasecmp(subscribe_type, "Active") == 0) {
600 req.subscribe_type = 1;
601 } else if (strcasecmp(subscribe_type, "Passive") == 0) {
602 req.subscribe_type = 0;
603 } else if (strcasecmp(subscribe_type, "Cancel") == 0) {
604 NanSubscribeCancelRequest req;
605
606 memset(&req, 0, sizeof(NanSubscribeCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700607 ret = nan_subscribe_cancel_request(
608 0, global_interface_handle, &req);
609 if (ret != WIFI_SUCCESS) {
610 send_resp(dut, conn, SIGMA_ERROR,
611 "NAN subscribe cancel request failed");
612 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200613 return 0;
614 }
615 }
616
617 if (disc_range)
618 req.rssi_threshold_flag = atoi(disc_range);
619
620 if (sdftx_dw)
621 req.subscribe_count = atoi(sdftx_dw);
622
623 /* Check this once again if config can be called here (TBD) */
624 if (discrange_ltd)
625 req.rssi_threshold_flag = atoi(discrange_ltd);
626
627 if (include_bit) {
628 int include_bit_val = atoi(include_bit);
629
630 req.serviceResponseInclude = include_bit_val;
631 sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d",
632 req.serviceResponseInclude);
633 }
634
635 if (srf_type) {
636 int srf_type_val = atoi(srf_type);
637
638 if (srf_type_val == 1)
639 req.serviceResponseFilter = 0; /* Bloom */
640 else
641 req.serviceResponseFilter = 1; /* MAC */
642 req.useServiceResponseFilter = 1;
643 sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d",
644 req.serviceResponseFilter);
645 }
646
647 if (mac) {
648 sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac);
649 req.num_intf_addr_present = nan_parse_mac_address_list(
650 dut, mac, &req.intf_addr[0][0],
651 NAN_MAX_SUBSCRIBE_MAX_ADDRESS);
652 }
653
654 memset(input_rx, 0, sizeof(input_rx));
655 memset(input_tx, 0, sizeof(input_tx));
656 if (rx_match_filter) {
657 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
658 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
659 filter_len_rx);
660 }
661 if (tx_match_filter) {
662 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
663 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
664 filter_len_tx);
665 }
666
667 if (tx_match_filter) {
668 req.tx_match_filter_len = filter_len_tx;
669 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
670 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
671 }
672 if (rx_match_filter) {
673 req.rx_match_filter_len = filter_len_rx;
674 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
675 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
676 }
677
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700678 if (service_name) {
679 strlcpy((char *) req.service_name, service_name,
680 strlen(service_name) + 1);
681 req.service_name_len = strlen(service_name);
Rakesh Sunki74f4f992017-08-16 15:21:52 -0700682 strlcpy((char *) global_subscribe_service_name, service_name,
683 sizeof(global_subscribe_service_name));
684 global_subscribe_service_name_len =
685 strlen((char *) global_subscribe_service_name);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700686 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200687
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -0700688#if NAN_CERT_VERSION >= 3
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700689 if (awake_dw_interval) {
690 int input_dw_interval_val = atoi(awake_dw_interval);
691 int awake_dw_int = 0;
692
693 if (input_dw_interval_val > NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL) {
694 sigma_dut_print(dut, DUT_MSG_INFO,
695 "%s: input active dw interval = %d overwritting dw interval to Max allowed dw interval 16",
696 __func__, input_dw_interval_val);
697 input_dw_interval_val =
698 NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL;
699 }
700 sigma_dut_print(dut, DUT_MSG_INFO,
701 "%s: input active DW interval = %d",
702 __func__, input_dw_interval_val);
703 /*
704 * Indicates the interval for Sync beacons and SDF's in 2.4 GHz
705 * or 5 GHz band. Valid values of DW Interval are: 1, 2, 3, 4,
706 * and 5; 0 is reserved. The SDF includes in OTA when enabled.
707 * The publish/subscribe period values don't override the device
708 * level configurations.
709 * input_dw_interval_val is provided by the user are in the
710 * format 2^n-1 = 1/2/4/8/16. Internal implementation expects n
711 * to be passed to indicate the awake_dw_interval.
712 */
713 if (input_dw_interval_val == 1 ||
714 input_dw_interval_val % 2 == 0) {
715 while (input_dw_interval_val > 0) {
716 input_dw_interval_val >>= 1;
717 awake_dw_int++;
718 }
719 }
720 sigma_dut_print(dut, DUT_MSG_INFO,
721 "%s:converted active DW interval = %d",
722 __func__, awake_dw_int);
723 config_req.config_dw.config_2dot4g_dw_band = 1;
724 config_req.config_dw.dw_2dot4g_interval_val = awake_dw_int;
725 config_req.config_dw.config_5g_dw_band = 1;
726 config_req.config_dw.dw_5g_interval_val = awake_dw_int;
727 ret = nan_config_request(0, global_interface_handle,
728 &config_req);
729 if (ret != WIFI_SUCCESS) {
730 sigma_dut_print(dut, DUT_MSG_ERROR,
731 "%s:NAN config request failed",
732 __func__);
733 return -2;
734 }
735 }
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -0700736#endif
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700737
Rakesh Sunki107356c2017-03-30 14:47:55 -0700738 ret = nan_subscribe_request(0, global_interface_handle, &req);
739 if (ret != WIFI_SUCCESS) {
740 send_resp(dut, conn, SIGMA_ERROR,
741 "NAN subscribe request failed");
742 }
743
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200744 return 0;
745}
746
747
Rakesh Sunkid7344c02017-03-30 14:47:55 -0700748static int sigma_ndp_configure_band(struct sigma_dut *dut,
749 struct sigma_conn *conn,
750 struct sigma_cmd *cmd,
751 NdpSupportedBand band_config_val)
752{
753 wifi_error ret;
754 NanDebugParams cfg_debug;
755 int size;
756
757 memset(&cfg_debug, 0, sizeof(NanDebugParams));
758 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS;
759 memcpy(cfg_debug.debug_cmd_data, &band_config_val, sizeof(int));
760 sigma_dut_print(dut, DUT_MSG_INFO, "%s:setting debug cmd=0x%x",
761 __func__, cfg_debug.cmd);
762 size = sizeof(u32) + sizeof(int);
763 ret = nan_debug_command_config(0, global_interface_handle, cfg_debug,
764 size);
765 if (ret != WIFI_SUCCESS)
766 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
767
768 return 0;
769}
770
771
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700772static int sigma_nan_data_request(struct sigma_dut *dut,
773 struct sigma_conn *conn,
774 struct sigma_cmd *cmd)
775{
776 const char *ndp_security = get_param(cmd, "DataPathSecurity");
777 const char *ndp_resp_mac = get_param(cmd, "RespNanMac");
778 const char *include_immutable = get_param(cmd, "includeimmutable");
779 const char *avoid_channel = get_param(cmd, "avoidchannel");
780 const char *invalid_nan_schedule = get_param(cmd, "InvalidNANSchedule");
781 const char *map_order = get_param(cmd, "maporder");
Rakesh Sunki8a4845d2017-05-16 15:27:13 -0700782#if NAN_CERT_VERSION >= 3
783 const char *qos_config = get_param(cmd, "QoS");
784#endif
Peng Xu7be50b12018-10-11 15:50:13 -0700785#if ((NAN_MAJOR_VERSION > 2) || \
786 (NAN_MAJOR_VERSION == 2 && NAN_MINOR_VERSION >= 1)) && \
787 NAN_CERT_VERSION >= 5
Peng Xub0c682c2018-06-27 14:36:07 -0700788 const char *ndpe_enable = get_param(cmd, "Ndpe");
789 const char *ndpe_attr = get_param(cmd, "ndpeAttr");
Peng Xu2486bbe2018-07-19 14:37:22 -0700790 const char *ndp_attr = get_param(cmd, "ndpAttr");
Peng Xu7b1b9e12018-07-19 16:24:55 -0700791 const char *tlv_list = get_param(cmd, "TLVList");
Peng Xub0c682c2018-06-27 14:36:07 -0700792#endif
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700793 wifi_error ret;
794 NanDataPathInitiatorRequest init_req;
795 NanDebugParams cfg_debug;
796 int size;
797
798 memset(&init_req, 0, sizeof(NanDataPathInitiatorRequest));
799
800 if (ndp_security) {
801 if (strcasecmp(ndp_security, "open") == 0)
802 init_req.ndp_cfg.security_cfg =
803 NAN_DP_CONFIG_NO_SECURITY;
804 else if (strcasecmp(ndp_security, "secure") == 0)
805 init_req.ndp_cfg.security_cfg = NAN_DP_CONFIG_SECURITY;
806 }
807
808 if (include_immutable) {
809 int include_immutable_val = 0;
810
811 memset(&cfg_debug, 0, sizeof(NanDebugParams));
812 cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE;
813 include_immutable_val = atoi(include_immutable);
814 memcpy(cfg_debug.debug_cmd_data, &include_immutable_val,
815 sizeof(int));
816 size = sizeof(u32) + sizeof(int);
817 nan_debug_command_config(0, global_interface_handle,
818 cfg_debug, size);
819 }
820
821 if (avoid_channel) {
822 int avoid_channel_freq = 0;
823
824 memset(&cfg_debug, 0, sizeof(NanDebugParams));
825 avoid_channel_freq = channel_to_freq(atoi(avoid_channel));
826 cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL;
827 memcpy(cfg_debug.debug_cmd_data, &avoid_channel_freq,
828 sizeof(int));
829 size = sizeof(u32) + sizeof(int);
830 nan_debug_command_config(0, global_interface_handle,
831 cfg_debug, size);
832 }
833
834 if (invalid_nan_schedule) {
835 int invalid_nan_schedule_type = 0;
836
837 memset(&cfg_debug, 0, sizeof(NanDebugParams));
838 invalid_nan_schedule_type = atoi(invalid_nan_schedule);
839 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_TYPE;
840 memcpy(cfg_debug.debug_cmd_data,
841 &invalid_nan_schedule_type, sizeof(int));
842 size = sizeof(u32) + sizeof(int);
843 sigma_dut_print(dut, DUT_MSG_INFO,
844 "%s: invalid schedule type: cmd type = %d and command data = %d",
845 __func__, cfg_debug.cmd,
846 invalid_nan_schedule_type);
847 nan_debug_command_config(0, global_interface_handle,
848 cfg_debug, size);
849 }
850
851 if (map_order) {
852 int map_order_val = 0;
853
854 memset(&cfg_debug, 0, sizeof(NanDebugParams));
855 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER;
856 map_order_val = atoi(map_order);
857 memcpy(cfg_debug.debug_cmd_data, &map_order_val, sizeof(int));
858 size = sizeof(u32) + sizeof(int);
859 sigma_dut_print(dut, DUT_MSG_INFO,
860 "%s: map order: cmd type = %d and command data = %d",
861 __func__,
Rakesh Sunki9eaa6772017-04-04 11:37:03 -0700862 cfg_debug.cmd, map_order_val);
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700863 nan_debug_command_config(0, global_interface_handle,
864 cfg_debug, size);
865 }
866
Rakesh Sunki8a4845d2017-05-16 15:27:13 -0700867#if NAN_CERT_VERSION >= 3
868 if (qos_config) {
869 u32 qos_config_val = 0;
870
871 memset(&cfg_debug, 0, sizeof(NanDebugParams));
872 cfg_debug.cmd = NAN_TEST_MODE_CMD_CONFIG_QOS;
873 qos_config_val = atoi(qos_config);
874 memcpy(cfg_debug.debug_cmd_data, &qos_config_val, sizeof(u32));
875 size = sizeof(u32) + sizeof(u32);
876 sigma_dut_print(dut, DUT_MSG_INFO,
877 "%s: qos config: cmd type = %d and command data = %d",
878 __func__, cfg_debug.cmd, qos_config_val);
879 nan_debug_command_config(0, global_interface_handle,
880 cfg_debug, size);
881 }
882#endif
883
Peng Xu7be50b12018-10-11 15:50:13 -0700884#if ((NAN_MAJOR_VERSION > 2) || \
885 (NAN_MAJOR_VERSION == 2 && NAN_MINOR_VERSION >= 1)) && \
886 NAN_CERT_VERSION >= 5
Peng Xub0c682c2018-06-27 14:36:07 -0700887 if (ndpe_enable &&
888 strcasecmp(ndpe_enable, "Enable") == 0)
889 dut->ndpe = 1;
890
Peng Xu2486bbe2018-07-19 14:37:22 -0700891 if (dut->ndpe && ndp_attr) {
892 NanDebugParams cfg_debug;
893 int ndp_attr_val;
894
895 memset(&cfg_debug, 0, sizeof(NanDebugParams));
896 cfg_debug.cmd = NAN_TEST_MODE_CMD_ENABLE_NDP;
897 if (strcasecmp(ndp_attr, "Absent") == 0)
898 ndp_attr_val = NAN_NDP_ATTR_ABSENT;
899 else
900 ndp_attr_val = NAN_NDP_ATTR_PRESENT;
901 memcpy(cfg_debug.debug_cmd_data, &ndp_attr_val, sizeof(int));
902 size = sizeof(u32) + sizeof(int);
903 ret = nan_debug_command_config(0, global_interface_handle,
904 cfg_debug, size);
905 if (ret != WIFI_SUCCESS) {
906 send_resp(dut, conn, SIGMA_ERROR,
907 "NAN config ndpAttr failed");
908 return 0;
909 }
910 }
911
Peng Xub0c682c2018-06-27 14:36:07 -0700912 if (dut->ndpe && ndpe_attr) {
913 NanDebugParams cfg_debug;
914 int ndpe_attr_val;
915
916 memset(&cfg_debug, 0, sizeof(NanDebugParams));
917 cfg_debug.cmd = NAN_TEST_MODE_CMD_DISABLE_NDPE;
918 if (strcasecmp(ndpe_attr, "Absent") == 0)
919 ndpe_attr_val = NAN_NDPE_ATTR_ABSENT;
920 else
921 ndpe_attr_val = NAN_NDPE_ATTR_PRESENT;
922 memcpy(cfg_debug.debug_cmd_data, &ndpe_attr_val, sizeof(int));
923 size = sizeof(u32) + sizeof(int);
924 ret = nan_debug_command_config(0, global_interface_handle,
925 cfg_debug, size);
926 if (ret != WIFI_SUCCESS) {
927 send_resp(dut, conn, SIGMA_ERROR,
928 "NAN config ndpeAttr failed");
929 return 0;
930 }
931 }
Peng Xu7b1b9e12018-07-19 16:24:55 -0700932
933 if (dut->ndpe && dut->device_type == STA_testbed && !tlv_list) {
934 NanDebugParams cfg_debug;
935 int implicit_ipv6_val;
936
937 sigma_dut_print(dut, DUT_MSG_INFO,
938 "%s: In test bed mode IPv6 is implicit in data request",
939 __func__);
940 memset(&cfg_debug, 0, sizeof(NanDebugParams));
941 cfg_debug.cmd = NAN_TEST_MODE_CMD_DISABLE_IPV6_LINK_LOCAL;
942 implicit_ipv6_val = NAN_IPV6_IMPLICIT;
943 memcpy(cfg_debug.debug_cmd_data, &implicit_ipv6_val,
944 sizeof(int));
945 size = sizeof(u32) + sizeof(int);
946 ret = nan_debug_command_config(0, global_interface_handle,
947 cfg_debug, size);
948 if (ret != WIFI_SUCCESS) {
949 send_resp(dut, conn, SIGMA_ERROR,
950 "errorCode,NAN config implicit IPv6 failed");
951 return 0;
952 }
953 sigma_dut_print(dut, DUT_MSG_INFO,
954 "%s: config command for implicit IPv6 sent",
955 __func__);
956 }
Peng Xub0c682c2018-06-27 14:36:07 -0700957#endif
958
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700959 /*
960 * Setting this flag, so that interface for ping6 command
961 * is set appropriately in traffic_send_ping().
962 */
963 dut->ndp_enable = 1;
964
965 /*
966 * Intended sleep after NAN data interface create
967 * before the NAN data request
968 */
969 sleep(4);
970
971 init_req.requestor_instance_id = global_match_handle;
972 strlcpy((char *) init_req.ndp_iface, "nan0",
973 sizeof(init_req.ndp_iface));
974
975 if (ndp_resp_mac) {
976 nan_parse_mac_address(dut, ndp_resp_mac,
977 init_req.peer_disc_mac_addr);
978 sigma_dut_print(
979 dut, DUT_MSG_INFO, "PEER MAC ADDR: " MAC_ADDR_STR,
980 MAC_ADDR_ARRAY(init_req.peer_disc_mac_addr));
981 } else {
982 memcpy(init_req.peer_disc_mac_addr, global_peer_mac_addr,
983 sizeof(init_req.peer_disc_mac_addr));
984 }
985
986 /* Not requesting the channel and letting FW decide */
987 if (dut->sta_channel == 0) {
988 init_req.channel_request_type = NAN_DP_CHANNEL_NOT_REQUESTED;
989 init_req.channel = 0;
990 } else {
991 init_req.channel_request_type = NAN_DP_FORCE_CHANNEL_SETUP;
992 init_req.channel = channel_to_freq(dut->sta_channel);
993 }
994 sigma_dut_print(dut, DUT_MSG_INFO,
995 "%s: Initiator Request: Channel = %d Channel Request Type = %d",
996 __func__, init_req.channel,
997 init_req.channel_request_type);
998
999 if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) {
Rakesh Sunki395b0152017-05-16 15:30:36 -07001000 init_req.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07001001 memcpy(&init_req.key_info.body.pmk_info.pmk[0],
1002 &dut->nan_pmk[0], NAN_PMK_INFO_LEN);
1003 init_req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
1004 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
1005 __func__,
1006 init_req.key_info.body.pmk_info.pmk_len);
1007 }
1008
Peng Xu7be50b12018-10-11 15:50:13 -07001009#if ((NAN_MAJOR_VERSION > 2) || \
1010 (NAN_MAJOR_VERSION == 2 && NAN_MINOR_VERSION >= 1)) && \
1011 NAN_CERT_VERSION >= 5
Peng Xub0c682c2018-06-27 14:36:07 -07001012 if (dut->ndpe) {
1013 unsigned char nan_mac_addr[ETH_ALEN];
1014 size_t addr_len = 0;
1015
1016 get_hwaddr("nan0", nan_mac_addr);
1017 addr_len = convert_mac_addr_to_ipv6_linklocal(
1018 nan_mac_addr, &init_req.nan_ipv6_intf_addr[0]);
1019 init_req.nan_ipv6_addr_present = 1;
1020 sigma_dut_print(dut, DUT_MSG_DEBUG,
1021 "%s: Initiator Request: IPv6:", __func__);
1022 nan_hex_dump(dut, &init_req.nan_ipv6_intf_addr[0],
1023 NAN_IPV6_ADDR_LEN);
1024 }
1025#endif
1026
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07001027 ret = nan_data_request_initiator(0, global_interface_handle, &init_req);
1028 if (ret != WIFI_SUCCESS) {
1029 send_resp(dut, conn, SIGMA_ERROR,
1030 "Unable to initiate nan data request");
1031 return 0;
1032 }
1033
1034 return 0;
1035}
1036
1037
Rakesh Sunkia5cc2842017-03-30 14:47:55 -07001038static int sigma_nan_data_response(struct sigma_dut *dut,
1039 struct sigma_conn *conn,
1040 struct sigma_cmd *cmd)
1041{
1042 const char *ndl_response = get_param(cmd, "NDLresponse");
1043 const char *m4_response_type = get_param(cmd, "M4ResponseType");
Peng Xu7be50b12018-10-11 15:50:13 -07001044#if ((NAN_MAJOR_VERSION > 2) || \
1045 (NAN_MAJOR_VERSION == 2 && NAN_MINOR_VERSION >= 1)) && \
1046 NAN_CERT_VERSION >= 5
Peng Xub0c682c2018-06-27 14:36:07 -07001047 const char *ndpe_attr = get_param(cmd, "ndpeAttr");
Peng Xu2486bbe2018-07-19 14:37:22 -07001048 const char *ndp_attr = get_param(cmd, "ndpAttr");
Peng Xub0c682c2018-06-27 14:36:07 -07001049#endif
Rakesh Sunkia5cc2842017-03-30 14:47:55 -07001050 wifi_error ret;
1051 NanDebugParams cfg_debug;
1052 int size;
1053
1054 if (ndl_response) {
1055 int auto_responder_mode_val = 0;
1056
1057 sigma_dut_print(dut, DUT_MSG_INFO,
1058 "%s: ndl_response = (%s) is passed",
1059 __func__, ndl_response);
1060 memset(&cfg_debug, 0, sizeof(NanDebugParams));
1061 cfg_debug.cmd = NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE;
1062 if (strcasecmp(ndl_response, "Auto") == 0) {
1063 auto_responder_mode_val = NAN_DATA_RESPONDER_MODE_AUTO;
1064 } else if (strcasecmp(ndl_response, "Reject") == 0) {
1065 auto_responder_mode_val =
1066 NAN_DATA_RESPONDER_MODE_REJECT;
1067 } else if (strcasecmp(ndl_response, "Accept") == 0) {
1068 auto_responder_mode_val =
1069 NAN_DATA_RESPONDER_MODE_ACCEPT;
1070 } else if (strcasecmp(ndl_response, "Counter") == 0) {
1071 auto_responder_mode_val =
1072 NAN_DATA_RESPONDER_MODE_COUNTER;
1073 } else {
1074 sigma_dut_print(dut, DUT_MSG_ERROR,
1075 "%s: Invalid ndl_response",
1076 __func__);
1077 return 0;
1078 }
1079 memcpy(cfg_debug.debug_cmd_data, &auto_responder_mode_val,
1080 sizeof(int));
1081 size = sizeof(u32) + sizeof(int);
1082 ret = nan_debug_command_config(0, global_interface_handle,
1083 cfg_debug, size);
1084 if (ret != WIFI_SUCCESS) {
1085 send_resp(dut, conn, SIGMA_ERROR,
1086 "Nan config request failed");
1087 }
1088 }
1089
1090 if (m4_response_type) {
1091 int m4_response_type_val = 0;
1092
1093 sigma_dut_print(dut, DUT_MSG_INFO,
1094 "%s: m4_response_type = (%s) is passed",
1095 __func__, m4_response_type);
1096 memset(&cfg_debug, 0, sizeof(NanDebugParams));
1097 cfg_debug.cmd = NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE;
1098 if (strcasecmp(m4_response_type, "Accept") == 0)
1099 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_ACCEPT;
1100 else if (strcasecmp(m4_response_type, "Reject") == 0)
1101 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_REJECT;
1102 else if (strcasecmp(m4_response_type, "BadMic") == 0)
1103 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_BADMIC;
1104
1105 memcpy(cfg_debug.debug_cmd_data, &m4_response_type_val,
1106 sizeof(int));
1107 size = sizeof(u32) + sizeof(int);
1108 ret = nan_debug_command_config(0, global_interface_handle,
1109 cfg_debug, size);
1110 if (ret != WIFI_SUCCESS) {
1111 send_resp(dut, conn, SIGMA_ERROR,
1112 "Nan config request failed");
1113 }
1114 }
1115
Peng Xu7be50b12018-10-11 15:50:13 -07001116#if ((NAN_MAJOR_VERSION > 2) || \
1117 (NAN_MAJOR_VERSION == 2 && NAN_MINOR_VERSION >= 1)) && \
1118 NAN_CERT_VERSION >= 5
Peng Xu2486bbe2018-07-19 14:37:22 -07001119 if (dut->ndpe && ndp_attr) {
1120 NanDebugParams cfg_debug;
1121 int ndp_attr_val;
1122
1123 memset(&cfg_debug, 0, sizeof(NanDebugParams));
1124 cfg_debug.cmd = NAN_TEST_MODE_CMD_ENABLE_NDP;
1125 if (strcasecmp(ndp_attr, "Absent") == 0)
1126 ndp_attr_val = NAN_NDP_ATTR_ABSENT;
1127 else
1128 ndp_attr_val = NAN_NDP_ATTR_PRESENT;
1129 memcpy(cfg_debug.debug_cmd_data, &ndp_attr_val, sizeof(int));
1130 size = sizeof(u32) + sizeof(int);
1131 ret = nan_debug_command_config(0, global_interface_handle,
1132 cfg_debug, size);
1133 if (ret != WIFI_SUCCESS) {
1134 send_resp(dut, conn, SIGMA_ERROR,
1135 "NAN config ndpAttr failed");
1136 return 0;
1137 }
1138 }
1139
Peng Xub0c682c2018-06-27 14:36:07 -07001140 if (ndpe_attr && dut->ndpe) {
1141 int ndpe_attr_val;
1142
1143 memset(&cfg_debug, 0, sizeof(NanDebugParams));
1144 cfg_debug.cmd = NAN_TEST_MODE_CMD_DISABLE_NDPE;
1145 if (strcasecmp(ndpe_attr, "Absent") == 0)
1146 ndpe_attr_val = NAN_NDPE_ATTR_ABSENT;
1147 else
1148 ndpe_attr_val = NAN_NDPE_ATTR_PRESENT;
1149 memcpy(cfg_debug.debug_cmd_data, &ndpe_attr_val, sizeof(int));
1150 size = sizeof(u32) + sizeof(int);
1151 ret = nan_debug_command_config(0, global_interface_handle,
1152 cfg_debug, size);
1153 if (ret != WIFI_SUCCESS) {
1154 send_resp(dut, conn, SIGMA_ERROR,
1155 "NAN config ndpeAttr failed");
1156 return 0;
1157 }
1158 }
1159#endif
1160
Rakesh Sunkia5cc2842017-03-30 14:47:55 -07001161 return 0;
1162}
1163
1164
Rakesh Sunki8a630b82017-03-30 14:47:55 -07001165static int sigma_nan_data_end(struct sigma_dut *dut, struct sigma_cmd *cmd)
1166{
1167 const char *nmf_security_config = get_param(cmd, "Security");
1168 NanDataPathEndRequest req;
1169 NanDebugParams cfg_debug;
1170 int size;
1171
1172 memset(&req, 0, sizeof(NanDataPathEndRequest));
1173 memset(&cfg_debug, 0, sizeof(NanDebugParams));
1174 if (nmf_security_config) {
1175 int nmf_security_config_val = 0;
1176
1177 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_NMF_CLEAR_CONFIG;
1178 if (strcasecmp(nmf_security_config, "open") == 0)
1179 nmf_security_config_val = NAN_NMF_CLEAR_ENABLE;
1180 else if (strcasecmp(nmf_security_config, "secure") == 0)
1181 nmf_security_config_val = NAN_NMF_CLEAR_DISABLE;
1182 memcpy(cfg_debug.debug_cmd_data,
1183 &nmf_security_config_val, sizeof(int));
1184 size = sizeof(u32) + sizeof(int);
1185 sigma_dut_print(dut, DUT_MSG_INFO,
1186 "%s: nmf_security_config_val -- cmd type = %d and command data = %d",
1187 __func__, cfg_debug.cmd,
1188 nmf_security_config_val);
1189 nan_debug_command_config(0, global_interface_handle,
1190 cfg_debug, size);
1191 }
1192
1193 req.num_ndp_instances = 1;
1194 req.ndp_instance_id[0] = global_ndp_instance_id;
1195
1196 nan_data_end(0, global_interface_handle, &req);
1197 return 0;
1198}
1199
1200
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -07001201static int sigma_nan_range_request(struct sigma_dut *dut,
1202 struct sigma_cmd *cmd)
1203{
1204 const char *dest_mac = get_param(cmd, "destmac");
1205 NanSubscribeRequest req;
1206
1207 memset(&req, 0, sizeof(NanSubscribeRequest));
1208 req.period = 1;
Rakesh Sunki3834be52017-08-16 15:27:36 -07001209 req.subscribe_type = NAN_SUBSCRIBE_TYPE_PASSIVE;
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -07001210 req.serviceResponseFilter = NAN_SRF_ATTR_BLOOM_FILTER;
1211 req.serviceResponseInclude = NAN_SRF_INCLUDE_RESPOND;
1212 req.ssiRequiredForMatchIndication = NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
1213 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
1214 req.subscribe_count = 0;
1215 strlcpy((char *) req.service_name, DEFAULT_SVC,
1216 NAN_MAX_SERVICE_NAME_LEN);
1217 req.service_name_len = strlen((char *) req.service_name);
1218
1219 req.subscribe_id = global_subscribe_id;
1220 req.sdea_params.ranging_state = 1;
1221 req.sdea_params.range_report = NAN_ENABLE_RANGE_REPORT;
1222 req.range_response_cfg.requestor_instance_id = global_match_handle;
1223 req.range_response_cfg.ranging_response = NAN_RANGE_REQUEST_ACCEPT;
1224 req.ranging_cfg.config_ranging_indications =
1225 NAN_RANGING_INDICATE_CONTINUOUS_MASK;
1226 if (dest_mac) {
1227 nan_parse_mac_address(dut, dest_mac,
1228 req.range_response_cfg.peer_addr);
1229 sigma_dut_print(
1230 dut, DUT_MSG_INFO, "peer mac addr: " MAC_ADDR_STR,
1231 MAC_ADDR_ARRAY(req.range_response_cfg.peer_addr));
1232 }
1233 nan_subscribe_request(0, global_interface_handle, &req);
1234
1235 return 0;
1236}
1237
1238
1239static int sigma_nan_cancel_range(struct sigma_dut *dut,
1240 struct sigma_cmd *cmd)
1241{
1242 const char *dest_mac = get_param(cmd, "destmac");
1243 NanPublishRequest req;
1244
1245 memset(&req, 0, sizeof(NanPublishRequest));
1246 req.ttl = 0;
1247 req.period = 1;
1248 req.publish_match_indicator = 1;
1249 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
1250 req.tx_type = NAN_TX_TYPE_BROADCAST;
1251 req.publish_count = 0;
1252 strlcpy((char *) req.service_name, DEFAULT_SVC,
1253 NAN_MAX_SERVICE_NAME_LEN);
1254 req.service_name_len = strlen((char *) req.service_name);
1255 req.publish_id = global_publish_id;
1256 req.range_response_cfg.ranging_response = NAN_RANGE_REQUEST_CANCEL;
1257 if (dest_mac) {
1258 nan_parse_mac_address(dut, dest_mac,
1259 req.range_response_cfg.peer_addr);
1260 sigma_dut_print(
1261 dut, DUT_MSG_INFO, "peer mac addr: " MAC_ADDR_STR,
1262 MAC_ADDR_ARRAY(req.range_response_cfg.peer_addr));
1263 }
1264 nan_publish_request(0, global_interface_handle, &req);
1265
1266 return 0;
1267}
1268
1269
Rakesh Sunkib2b65162017-03-30 14:47:55 -07001270static int sigma_nan_schedule_update(struct sigma_dut *dut,
1271 struct sigma_cmd *cmd)
1272{
1273 const char *schedule_update_type = get_param(cmd, "type");
1274 const char *channel_availability = get_param(cmd,
1275 "ChannelAvailability");
1276 const char *responder_nmi_mac = get_param(cmd, "ResponderNMI");
1277 NanDebugParams cfg_debug;
1278 int size = 0;
1279
1280 memset(&cfg_debug, 0, sizeof(NanDebugParams));
1281
1282 if (!schedule_update_type)
1283 return 0;
1284
1285 if (strcasecmp(schedule_update_type, "ULWnotify") == 0) {
1286 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY;
1287 size = sizeof(u32);
1288 sigma_dut_print(dut, DUT_MSG_INFO,
1289 "%s: Schedule Update cmd type = %d", __func__,
1290 cfg_debug.cmd);
1291 if (channel_availability) {
1292 int channel_availability_val;
1293
1294 channel_availability_val = atoi(channel_availability);
1295 size += sizeof(int);
1296 memcpy(cfg_debug.debug_cmd_data,
1297 &channel_availability_val, sizeof(int));
1298 sigma_dut_print(dut, DUT_MSG_INFO,
1299 "%s: Schedule Update cmd data = %d size = %d",
1300 __func__, channel_availability_val,
1301 size);
1302 }
1303 } else if (strcasecmp(schedule_update_type, "NDLnegotiate") == 0) {
1304 cfg_debug.cmd =
1305 NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE;
1306 size = sizeof(u32);
1307 sigma_dut_print(dut, DUT_MSG_INFO,
1308 "%s: Schedule Update cmd type = %d", __func__,
1309 cfg_debug.cmd);
1310 if (responder_nmi_mac) {
1311 u8 responder_nmi_mac_addr[NAN_MAC_ADDR_LEN];
1312
1313 nan_parse_mac_address(dut, responder_nmi_mac,
1314 responder_nmi_mac_addr);
1315 size += NAN_MAC_ADDR_LEN;
1316 memcpy(cfg_debug.debug_cmd_data, responder_nmi_mac_addr,
1317 NAN_MAC_ADDR_LEN);
1318 sigma_dut_print(dut, DUT_MSG_INFO,
1319 "%s: RESPONDER NMI MAC: "MAC_ADDR_STR,
1320 __func__,
1321 MAC_ADDR_ARRAY(responder_nmi_mac_addr));
1322 sigma_dut_print(dut, DUT_MSG_INFO,
1323 "%s: Schedule Update: cmd size = %d",
1324 __func__, size);
1325 }
1326 } else if (strcasecmp(schedule_update_type, "NDLnotify") == 0) {
1327 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY;
1328 size = sizeof(u32);
1329 sigma_dut_print(dut, DUT_MSG_INFO,
1330 "%s: Schedule Update cmd type = %d", __func__,
1331 cfg_debug.cmd);
1332 }
1333
1334 nan_debug_command_config(0, global_interface_handle, cfg_debug, size);
1335
1336 return 0;
1337}
1338
1339
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001340int config_post_disc_attr(void)
1341{
Rakesh Sunki107356c2017-03-30 14:47:55 -07001342 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001343 NanConfigRequest configReq;
1344
1345 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001346
1347 /* Configure Post disc attr */
1348 /* Make these defines and use correct enum */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001349 configReq.num_config_discovery_attr = 1;
1350 configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */
1351 configReq.discovery_attr_val[0].role = 0;
1352 configReq.discovery_attr_val[0].transmit_freq = 1;
1353 configReq.discovery_attr_val[0].duration = 0;
1354 configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001355
Rakesh Sunki107356c2017-03-30 14:47:55 -07001356 ret = nan_config_request(0, global_interface_handle, &configReq);
1357 if (ret != WIFI_SUCCESS) {
1358 sigma_dut_print(global_dut, DUT_MSG_INFO,
1359 "NAN config request failed while configuring post discovery attribute");
1360 }
1361
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001362 return 0;
1363}
1364
1365
1366int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn,
1367 struct sigma_cmd *cmd)
1368{
1369 const char *publish_type = get_param(cmd, "PublishType");
1370 const char *service_name = get_param(cmd, "ServiceName");
1371 const char *disc_range = get_param(cmd, "DiscoveryRange");
1372 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
1373 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
1374 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
1375 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001376 const char *ndp_enable = get_param(cmd, "DataPathFlag");
1377 const char *ndp_type = get_param(cmd, "DataPathType");
1378 const char *data_path_security = get_param(cmd, "datapathsecurity");
Rakesh Sunki48060402017-03-30 14:47:55 -07001379 const char *range_required = get_param(cmd, "rangerequired");
Rakesh Sunki8a4845d2017-05-16 15:27:13 -07001380#if NAN_CERT_VERSION >= 3
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -07001381 const char *awake_dw_interval = get_param(cmd, "awakeDWint");
Rakesh Sunki8a4845d2017-05-16 15:27:13 -07001382 const char *qos_config = get_param(cmd, "QoS");
1383#endif
Peng Xu8863ec72018-08-06 11:50:37 -07001384 const char *ndpe = get_param(cmd, "NDPE");
1385 const char *trans_proto = get_param(cmd, "TransProtoType");
Peng Xu7be50b12018-10-11 15:50:13 -07001386#if ((NAN_MAJOR_VERSION > 2) || \
1387 (NAN_MAJOR_VERSION == 2 && NAN_MINOR_VERSION >= 1)) && \
1388 NAN_CERT_VERSION >= 5
Peng Xu2486bbe2018-07-19 14:37:22 -07001389 const char *ndp_attr = get_param(cmd, "ndpAttr");
1390#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001391 NanPublishRequest req;
Rakesh Sunkie6f66832017-05-16 15:22:48 -07001392 NanConfigRequest config_req;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001393 int filter_len_rx = 0, filter_len_tx = 0;
1394 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
1395 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -07001396 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001397
1398 memset(&req, 0, sizeof(NanPublishRequest));
Rakesh Sunkie6f66832017-05-16 15:22:48 -07001399 memset(&config_req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001400 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -07001401 req.period = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001402 req.publish_match_indicator = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001403 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
1404 req.tx_type = NAN_TX_TYPE_BROADCAST;
1405 req.publish_count = 0;
Rakesh Sunki0a0eea82017-03-30 14:47:55 -07001406 req.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_ALL;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001407
Rakesh Sunki42363682017-05-16 15:00:42 -07001408 if (global_publish_service_name_len &&
1409 service_name &&
1410 strcasecmp((char *) global_publish_service_name,
1411 service_name) == 0 &&
1412 global_publish_id) {
1413 req.publish_id = global_publish_id;
1414 sigma_dut_print(dut, DUT_MSG_INFO,
1415 "%s: updating publish_id = %d in publish request",
1416 __func__, req.publish_id);
1417 }
1418
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001419 if (service_name) {
1420 strlcpy((char *) req.service_name, service_name,
Rakesh Sunki42363682017-05-16 15:00:42 -07001421 sizeof(req.service_name));
1422 req.service_name_len = strlen((char *) req.service_name);
1423 strlcpy((char *) global_publish_service_name, service_name,
1424 sizeof(global_publish_service_name));
1425 global_publish_service_name_len =
1426 strlen((char *) global_publish_service_name);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001427 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001428
1429 if (publish_type) {
1430 if (strcasecmp(publish_type, "Solicited") == 0) {
1431 req.publish_type = NAN_PUBLISH_TYPE_SOLICITED;
Rakesh Sunki62644ab2017-03-30 14:47:55 -07001432 } else if (strcasecmp(publish_type, "Unsolicited") == 0) {
1433 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001434 } else if (strcasecmp(publish_type, "Cancel") == 0) {
1435 NanPublishCancelRequest req;
1436
1437 memset(&req, 0, sizeof(NanPublishCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -07001438 ret = nan_publish_cancel_request(
1439 0, global_interface_handle, &req);
1440 if (ret != WIFI_SUCCESS) {
1441 send_resp(dut, conn, SIGMA_ERROR,
1442 "Unable to cancel nan publish request");
1443 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001444 return 0;
1445 }
1446 }
1447
1448 if (disc_range)
1449 req.rssi_threshold_flag = atoi(disc_range);
1450
1451 if (sdftx_dw)
1452 req.publish_count = atoi(sdftx_dw);
1453
1454 if (discrange_ltd)
1455 req.rssi_threshold_flag = atoi(discrange_ltd);
1456
1457 memset(input_rx, 0, sizeof(input_rx));
1458 memset(input_tx, 0, sizeof(input_tx));
1459 if (rx_match_filter) {
1460 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
1461 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
1462 filter_len_rx);
1463 }
1464 if (tx_match_filter) {
1465 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
1466 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
1467 filter_len_tx);
1468 }
1469
1470 if (is_fam == 1) {
1471 config_post_disc_attr();
Rakesh Sunkif680e0f2017-03-30 14:47:55 -07001472 /*
1473 * 8-bit bitmap which allows the Host to associate this publish
1474 * with a particular Post-NAN Connectivity attribute which has
1475 * been sent down in a NanConfigureRequest/NanEnableRequest
1476 * message. If the DE fails to find a configured Post-NAN
1477 * connectivity attributes referenced by the bitmap, the DE will
1478 * return an error code to the Host. If the Publish is
1479 * configured to use a Post-NAN Connectivity attribute and the
1480 * Host does not refresh the Post-NAN Connectivity attribute the
1481 * Publish will be canceled and the Host will be sent a
1482 * PublishTerminatedIndication message.
1483 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001484 req.connmap = 0x10;
1485 }
1486
1487 if (tx_match_filter) {
1488 req.tx_match_filter_len = filter_len_tx;
1489 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
1490 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
1491 }
1492
1493 if (rx_match_filter) {
1494 req.rx_match_filter_len = filter_len_rx;
1495 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
1496 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
1497 }
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001498
1499 if (service_name) {
1500 strlcpy((char *) req.service_name, service_name,
1501 strlen(service_name) + 1);
1502 req.service_name_len = strlen(service_name);
1503 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001504
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001505 if (ndp_enable) {
1506 if (strcasecmp(ndp_enable, "enable") == 0)
1507 req.sdea_params.config_nan_data_path = 1;
1508 else
1509 req.sdea_params.config_nan_data_path = 0;
1510
1511 if (ndp_type)
1512 req.sdea_params.ndp_type = atoi(ndp_type);
1513
1514 if (data_path_security) {
1515 if (strcasecmp(data_path_security, "secure") == 0) {
1516 req.sdea_params.security_cfg =
1517 NAN_DP_CONFIG_SECURITY;
1518 } else if (strcasecmp(data_path_security, "open") ==
1519 0) {
1520 req.sdea_params.security_cfg =
1521 NAN_DP_CONFIG_NO_SECURITY;
1522 }
1523 }
1524
1525 if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) {
Rakesh Sunki395b0152017-05-16 15:30:36 -07001526 req.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001527 memcpy(&req.key_info.body.pmk_info.pmk[0],
1528 &dut->nan_pmk[0], NAN_PMK_INFO_LEN);
1529 req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
1530 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
1531 __func__, req.key_info.body.pmk_info.pmk_len);
1532 }
1533 }
Rakesh Sunki48060402017-03-30 14:47:55 -07001534 if (range_required && strcasecmp(range_required, "enable") == 0) {
1535 req.sdea_params.ranging_state = NAN_RANGING_ENABLE;
1536 req.sdea_params.range_report = NAN_ENABLE_RANGE_REPORT;
1537 }
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001538
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -07001539#if NAN_CERT_VERSION >= 3
Rakesh Sunkie6f66832017-05-16 15:22:48 -07001540 if (awake_dw_interval) {
1541 int input_dw_interval_val = atoi(awake_dw_interval);
1542 int awake_dw_int = 0;
1543
1544 if (input_dw_interval_val > NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL) {
1545 sigma_dut_print(dut, DUT_MSG_INFO,
1546 "%s: input active dw interval = %d overwritting dw interval to Max allowed dw interval 16",
1547 __func__, input_dw_interval_val);
1548 input_dw_interval_val =
1549 NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL;
1550 }
1551 sigma_dut_print(dut, DUT_MSG_INFO,
1552 "%s: input active DW interval = %d",
1553 __func__, input_dw_interval_val);
1554 /*
1555 * Indicates the interval for Sync beacons and SDF's in 2.4 GHz
1556 * or 5 GHz band. Valid values of DW Interval are: 1, 2, 3, 4,
1557 * and 5; 0 is reserved. The SDF includes in OTA when enabled.
1558 * The publish/subscribe period. values don't override the
1559 * device level configurations.
1560 * input_dw_interval_val is provided by the user are in the
1561 * format 2^n-1 = 1/2/4/8/16. Internal implementation expects n
1562 * to be passed to indicate the awake_dw_interval.
1563 */
1564 if (input_dw_interval_val == 1 ||
1565 input_dw_interval_val % 2 == 0) {
1566 while (input_dw_interval_val > 0) {
1567 input_dw_interval_val >>= 1;
1568 awake_dw_int++;
1569 }
1570 }
1571 sigma_dut_print(dut, DUT_MSG_INFO,
1572 "%s:converted active DW interval = %d",
1573 __func__, awake_dw_int);
1574 config_req.config_dw.config_2dot4g_dw_band = 1;
1575 config_req.config_dw.dw_2dot4g_interval_val = awake_dw_int;
1576 config_req.config_dw.config_5g_dw_band = 1;
1577 config_req.config_dw.dw_5g_interval_val = awake_dw_int;
1578 ret = nan_config_request(0, global_interface_handle,
1579 &config_req);
1580 if (ret != WIFI_SUCCESS) {
1581 sigma_dut_print(dut, DUT_MSG_ERROR,
1582 "%s:NAN config request failed",
1583 __func__);
1584 return -2;
1585 }
1586 }
1587
Rakesh Sunki8a4845d2017-05-16 15:27:13 -07001588 if (qos_config)
1589 req.sdea_params.qos_cfg = (NanQosCfgStatus) atoi(qos_config);
1590#endif
1591
Peng Xu8863ec72018-08-06 11:50:37 -07001592 if (ndpe &&
1593 strcasecmp(ndpe, "Enable") == 0)
1594 dut->ndpe = 1;
1595
1596 if (trans_proto) {
1597 if (strcasecmp(trans_proto, "TCP") == 0) {
1598 dut->trans_proto = TRANSPORT_PROTO_TYPE_TCP;
1599 } else if (strcasecmp(trans_proto, "UDP") == 0) {
1600 dut->trans_proto = TRANSPORT_PROTO_TYPE_UDP;
1601 } else {
1602 sigma_dut_print(dut, DUT_MSG_ERROR,
1603 "%s: Invalid protocol %s",
1604 __func__, trans_proto);
1605 return -1;
1606 }
1607 }
1608
Peng Xu7be50b12018-10-11 15:50:13 -07001609#if ((NAN_MAJOR_VERSION > 2) || \
1610 (NAN_MAJOR_VERSION == 2 && NAN_MINOR_VERSION >= 1)) && \
1611 NAN_CERT_VERSION >= 5
Peng Xu2486bbe2018-07-19 14:37:22 -07001612 if (dut->ndpe && ndp_attr) {
1613 NanDebugParams cfg_debug;
1614 int ndp_attr_val, size;
1615
1616 memset(&cfg_debug, 0, sizeof(NanDebugParams));
1617 cfg_debug.cmd = NAN_TEST_MODE_CMD_ENABLE_NDP;
1618 if (strcasecmp(ndp_attr, "Absent") == 0)
1619 ndp_attr_val = NAN_NDP_ATTR_ABSENT;
1620 else
1621 ndp_attr_val = NAN_NDP_ATTR_PRESENT;
1622 memcpy(cfg_debug.debug_cmd_data, &ndp_attr_val, sizeof(int));
1623 size = sizeof(u32) + sizeof(int);
1624 ret = nan_debug_command_config(0, global_interface_handle,
1625 cfg_debug, size);
1626 if (ret != WIFI_SUCCESS) {
1627 send_resp(dut, conn, SIGMA_ERROR,
1628 "NAN config ndpAttr failed");
1629 return 0;
1630 }
1631 }
1632
Peng Xu8863ec72018-08-06 11:50:37 -07001633 if (dut->ndpe) {
1634 unsigned char nan_mac_addr[ETH_ALEN];
1635 size_t addr_len = 0;
1636 NanDebugParams cfg_debug;
1637 NdpIpTransParams ndp_ip_trans_param;
1638
1639 get_hwaddr("nan0", nan_mac_addr);
1640 addr_len = convert_mac_addr_to_ipv6_linklocal(
1641 nan_mac_addr, ndp_ip_trans_param.ipv6_intf_addr);
1642 ndp_ip_trans_param.ipv6_addr_present = 1;
1643
1644 ndp_ip_trans_param.trans_port_present = 1;
1645 ndp_ip_trans_param.transport_port = dut->trans_port;
1646
1647 ndp_ip_trans_param.trans_proto_present = 1;
1648 ndp_ip_trans_param.transport_protocol = dut->trans_proto;
1649
1650 cfg_debug.cmd = NAN_TEST_MODE_CMD_TRANSPORT_IP_PARAM;
1651 memcpy(cfg_debug.debug_cmd_data, &ndp_ip_trans_param,
1652 sizeof(NdpIpTransParams));
1653 nan_debug_command_config(0, global_interface_handle, cfg_debug,
1654 sizeof(u32) +
1655 sizeof(NdpIpTransParams));
1656 }
1657#endif
1658
Rakesh Sunki107356c2017-03-30 14:47:55 -07001659 ret = nan_publish_request(0, global_interface_handle, &req);
1660 if (ret != WIFI_SUCCESS)
1661 send_resp(dut, conn, SIGMA_ERROR, "Unable to publish");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001662
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001663 if (ndp_enable)
1664 dut->ndp_enable = 1;
1665
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001666 return 0;
1667}
1668
1669
1670static int nan_further_availability_rx(struct sigma_dut *dut,
1671 struct sigma_conn *conn,
1672 struct sigma_cmd *cmd)
1673{
1674 const char *master_pref = get_param(cmd, "MasterPref");
1675 const char *rand_fac = get_param(cmd, "RandFactor");
1676 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001677 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001678 struct timespec abstime;
1679
1680 NanEnableRequest req;
1681
1682 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001683 req.cluster_low = 0;
1684 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001685 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001686
1687 if (master_pref)
1688 req.master_pref = strtoul(master_pref, NULL, 0);
1689
1690 if (rand_fac) {
1691 int rand_fac_val = strtoul(rand_fac, NULL, 0);
1692
1693 req.config_random_factor_force = 1;
1694 req.random_factor_force_val = rand_fac_val;
1695 }
1696
1697 if (hop_count) {
1698 int hop_count_val = strtoul(hop_count, NULL, 0);
1699
1700 req.config_hop_count_force = 1;
1701 req.hop_count_force_val = hop_count_val;
1702 }
1703
Rakesh Sunki107356c2017-03-30 14:47:55 -07001704 ret = nan_enable_request(0, global_interface_handle, &req);
1705 if (ret != WIFI_SUCCESS) {
1706 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
1707 return 0;
1708 }
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001709
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001710 abstime.tv_sec = 4;
1711 abstime.tv_nsec = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001712 wait(abstime);
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001713
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001714 return 0;
1715}
1716
1717
1718static int nan_further_availability_tx(struct sigma_dut *dut,
1719 struct sigma_conn *conn,
1720 struct sigma_cmd *cmd)
1721{
1722 const char *master_pref = get_param(cmd, "MasterPref");
1723 const char *rand_fac = get_param(cmd, "RandFactor");
1724 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001725 wifi_error ret;
1726
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001727 NanEnableRequest req;
1728 NanConfigRequest configReq;
1729
1730 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001731 req.cluster_low = 0;
1732 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001733 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001734
1735 if (master_pref)
1736 req.master_pref = strtoul(master_pref, NULL, 0);
1737
1738 if (rand_fac) {
1739 int rand_fac_val = strtoul(rand_fac, NULL, 0);
1740
1741 req.config_random_factor_force = 1;
1742 req.random_factor_force_val = rand_fac_val;
1743 }
1744
1745 if (hop_count) {
1746 int hop_count_val = strtoul(hop_count, NULL, 0);
1747
1748 req.config_hop_count_force = 1;
1749 req.hop_count_force_val = hop_count_val;
1750 }
1751
Rakesh Sunki107356c2017-03-30 14:47:55 -07001752 ret = nan_enable_request(0, global_interface_handle, &req);
1753 if (ret != WIFI_SUCCESS) {
1754 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
1755 return 0;
1756 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001757
1758 /* Start the config of fam */
1759
1760 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001761
1762 configReq.config_fam = 1;
1763 configReq.fam_val.numchans = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001764 configReq.fam_val.famchan[0].entry_control = 0;
1765 configReq.fam_val.famchan[0].class_val = 81;
1766 configReq.fam_val.famchan[0].channel = 6;
1767 configReq.fam_val.famchan[0].mapid = 0;
1768 configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe;
1769
Rakesh Sunki107356c2017-03-30 14:47:55 -07001770 ret = nan_config_request(0, global_interface_handle, &configReq);
1771 if (ret != WIFI_SUCCESS)
1772 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001773
1774 return 0;
1775}
1776
1777
1778int sigma_nan_transmit_followup(struct sigma_dut *dut,
1779 struct sigma_conn *conn,
1780 struct sigma_cmd *cmd)
1781{
1782 const char *mac = get_param(cmd, "mac");
1783 const char *requestor_id = get_param(cmd, "RemoteInstanceId");
1784 const char *local_id = get_param(cmd, "LocalInstanceId");
1785 const char *service_name = get_param(cmd, "servicename");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001786 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001787 NanTransmitFollowupRequest req;
1788
1789 memset(&req, 0, sizeof(NanTransmitFollowupRequest));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001790 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001791 req.addr[0] = 0xFF;
1792 req.addr[1] = 0xFF;
1793 req.addr[2] = 0xFF;
1794 req.addr[3] = 0xFF;
1795 req.addr[4] = 0xFF;
1796 req.addr[5] = 0xFF;
1797 req.priority = NAN_TX_PRIORITY_NORMAL;
1798 req.dw_or_faw = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001799
1800 if (service_name)
1801 req.service_specific_info_len = strlen(service_name);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001802
1803 if (requestor_id) {
1804 /* int requestor_id_val = atoi(requestor_id); */
Rakesh Sunkifa417332017-08-16 15:41:32 -07001805 if (global_match_handle != 0) {
1806 req.requestor_instance_id = global_match_handle;
1807 } else {
1808 u32 requestor_id_val = atoi(requestor_id);
1809 requestor_id_val =
1810 (requestor_id_val << 24) | 0x0000FFFF;
1811 req.requestor_instance_id = requestor_id_val;
1812 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001813 }
1814 if (local_id) {
1815 /* int local_id_val = atoi(local_id); */
Rakesh Sunkifa417332017-08-16 15:41:32 -07001816 if (global_header_handle != 0)
1817 req.publish_subscribe_id = global_header_handle;
1818 else
1819 req.publish_subscribe_id = atoi(local_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001820 }
1821
1822 if (mac == NULL) {
1823 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address");
1824 return -1;
1825 }
1826 nan_parse_mac_address(dut, mac, req.addr);
1827
Rakesh Sunki107356c2017-03-30 14:47:55 -07001828 ret = nan_transmit_followup_request(0, global_interface_handle, &req);
1829 if (ret != WIFI_SUCCESS) {
1830 send_resp(dut, conn, SIGMA_ERROR,
1831 "Unable to complete nan transmit followup");
1832 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001833
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001834 return 0;
1835}
1836
Rakesh Sunki107356c2017-03-30 14:47:55 -07001837
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001838/* NotifyResponse invoked to notify the status of the Request */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001839void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001840{
1841 sigma_dut_print(global_dut, DUT_MSG_INFO,
Rakesh Sunkifdbd60b2017-03-30 14:47:55 -07001842 "%s: status %d response_type %d",
1843 __func__, rsp_data->status, rsp_data->response_type);
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001844 if (rsp_data->response_type == NAN_RESPONSE_STATS &&
1845 rsp_data->body.stats_response.stats_type ==
1846 NAN_STATS_ID_DE_TIMING_SYNC) {
1847 NanSyncStats *pSyncStats;
1848
1849 sigma_dut_print(global_dut, DUT_MSG_INFO,
1850 "%s: stats_type %d", __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001851 rsp_data->body.stats_response.stats_type);
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001852 pSyncStats = &rsp_data->body.stats_response.data.sync_stats;
1853 memcpy(&global_nan_sync_stats, pSyncStats,
1854 sizeof(NanSyncStats));
1855 pthread_cond_signal(&gCondition);
Rakesh Sunki4d5912d2017-03-30 14:47:55 -07001856 } else if (rsp_data->response_type == NAN_RESPONSE_PUBLISH) {
1857 sigma_dut_print(global_dut, DUT_MSG_INFO,
1858 "%s: publish_id %d\n",
1859 __func__,
1860 rsp_data->body.publish_response.publish_id);
1861 global_publish_id = rsp_data->body.publish_response.publish_id;
1862 } else if (rsp_data->response_type == NAN_RESPONSE_SUBSCRIBE) {
1863 sigma_dut_print(global_dut, DUT_MSG_INFO,
1864 "%s: subscribe_id %d\n",
1865 __func__,
1866 rsp_data->body.subscribe_response.subscribe_id);
1867 global_subscribe_id =
1868 rsp_data->body.subscribe_response.subscribe_id;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001869 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001870}
1871
1872
1873/* Events Callback */
1874void nan_event_publish_replied(NanPublishRepliedInd *event)
1875{
1876 sigma_dut_print(global_dut, DUT_MSG_INFO,
1877 "%s: handle %d " MAC_ADDR_STR " rssi:%d",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001878 __func__, event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001879 MAC_ADDR_ARRAY(event->addr), event->rssi_value);
1880 event_anyresponse = 1;
1881 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
Rakesh Sunkifa417332017-08-16 15:41:32 -07001882 "EventName,Replied,RemoteInstanceID,%d,LocalInstanceID,%d,mac," MAC_ADDR_STR" ",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001883 (event->requestor_instance_id >> 24),
Rakesh Sunkifa417332017-08-16 15:41:32 -07001884 (event->requestor_instance_id & 0xFFFF),
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001885 MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001886}
1887
1888
1889/* Events Callback */
1890void nan_event_publish_terminated(NanPublishTerminatedInd *event)
1891{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001892 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d",
1893 __func__, event->publish_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001894}
1895
1896
1897/* Events Callback */
1898void nan_event_match(NanMatchInd *event)
1899{
1900 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001901 "%s: Pub/Sub Id %d remote_requestor_id %08x "
1902 MAC_ADDR_STR
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001903 " rssi:%d",
1904 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001905 event->publish_subscribe_id,
1906 event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001907 MAC_ADDR_ARRAY(event->addr),
1908 event->rssi_value);
1909 event_anyresponse = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001910 global_header_handle = event->publish_subscribe_id;
1911 global_match_handle = event->requestor_instance_id;
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07001912 memcpy(global_peer_mac_addr, event->addr, sizeof(global_peer_mac_addr));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001913
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001914 /* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */
1915 /* global_pub_sub_handle = event->header.handle; */
1916 /* Print the SSI */
1917 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001918 nan_hex_dump(global_dut, event->service_specific_info,
1919 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001920 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1921 "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001922 MAC_ADDR_STR " ", (event->requestor_instance_id >> 24),
1923 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001924
1925 /* Print the match filter */
1926 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001927 nan_hex_dump(global_dut, event->sdf_match_filter,
1928 event->sdf_match_filter_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001929
1930 /* Print the conn_capability */
1931 sigma_dut_print(global_dut, DUT_MSG_INFO,
1932 "Printing PostConnectivity Capability");
1933 if (event->is_conn_capability_valid) {
1934 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s",
1935 event->conn_capability.is_wfd_supported ?
1936 "yes" : "no");
1937 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s",
1938 (event->conn_capability.is_wfds_supported ?
1939 "yes" : "no"));
1940 sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s",
1941 (event->conn_capability.is_tdls_supported ?
1942 "yes" : "no"));
1943 sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s",
1944 (event->conn_capability.is_ibss_supported ?
1945 "yes" : "no"));
1946 sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s",
1947 (event->conn_capability.is_mesh_supported ?
1948 "yes" : "no"));
1949 sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d",
1950 event->conn_capability.wlan_infra_field);
1951 } else {
1952 sigma_dut_print(global_dut, DUT_MSG_INFO,
1953 "PostConnectivity Capability not present");
1954 }
1955
1956 /* Print the discovery_attr */
1957 sigma_dut_print(global_dut, DUT_MSG_INFO,
1958 "Printing PostDiscovery Attribute");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001959 if (event->num_rx_discovery_attr) {
1960 int idx;
1961
1962 for (idx = 0; idx < event->num_rx_discovery_attr; idx++) {
1963 sigma_dut_print(global_dut, DUT_MSG_INFO,
1964 "PostDiscovery Attribute - %d", idx);
1965 sigma_dut_print(global_dut, DUT_MSG_INFO,
1966 "Conn Type:%d Device Role:%d"
1967 MAC_ADDR_STR,
1968 event->discovery_attr[idx].type,
1969 event->discovery_attr[idx].role,
1970 MAC_ADDR_ARRAY(event->discovery_attr[idx].addr));
1971 sigma_dut_print(global_dut, DUT_MSG_INFO,
1972 "Duration:%d MapId:%d "
1973 "avail_interval_bitmap:%04x",
1974 event->discovery_attr[idx].duration,
1975 event->discovery_attr[idx].mapid,
1976 event->discovery_attr[idx].avail_interval_bitmap);
1977 sigma_dut_print(global_dut, DUT_MSG_INFO,
1978 "Printing Mesh Id:");
1979 nan_hex_dump(global_dut,
1980 event->discovery_attr[idx].mesh_id,
1981 event->discovery_attr[idx].mesh_id_len);
1982 sigma_dut_print(global_dut, DUT_MSG_INFO,
1983 "Printing Infrastructure Ssid:");
1984 nan_hex_dump(global_dut,
1985 event->discovery_attr[idx].infrastructure_ssid_val,
1986 event->discovery_attr[idx].infrastructure_ssid_len);
1987 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001988 } else {
1989 sigma_dut_print(global_dut, DUT_MSG_INFO,
1990 "PostDiscovery attribute not present");
1991 }
1992
1993 /* Print the fam */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001994 if (event->num_chans) {
1995 nan_print_further_availability_chan(global_dut,
1996 event->num_chans,
1997 &event->famchan[0]);
1998 } else {
1999 sigma_dut_print(global_dut, DUT_MSG_INFO,
2000 "Further Availability Map not present");
2001 }
2002 if (event->cluster_attribute_len) {
2003 sigma_dut_print(global_dut, DUT_MSG_INFO,
2004 "Printing Cluster Attribute:");
2005 nan_hex_dump(global_dut, event->cluster_attribute,
2006 event->cluster_attribute_len);
2007 } else {
2008 sigma_dut_print(global_dut, DUT_MSG_INFO,
2009 "Cluster Attribute not present");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002010 }
2011}
2012
2013
2014/* Events Callback */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002015void nan_event_match_expired(NanMatchExpiredInd *event)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002016{
2017 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002018 "%s: publish_subscribe_id %d match_handle %08x",
2019 __func__, event->publish_subscribe_id,
2020 event->requestor_instance_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002021}
2022
2023
2024/* Events Callback */
2025void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event)
2026{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002027 sigma_dut_print(global_dut, DUT_MSG_INFO,
2028 "%s: Subscribe Id %d reason %d",
2029 __func__, event->subscribe_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002030}
2031
2032
2033/* Events Callback */
2034void nan_event_followup(NanFollowupInd *event)
2035{
2036 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002037 "%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d "
2038 MAC_ADDR_STR, __func__, event->publish_subscribe_id,
2039 event->requestor_instance_id, event->dw_or_faw,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002040 MAC_ADDR_ARRAY(event->addr));
2041
Rakesh Sunkifa417332017-08-16 15:41:32 -07002042 global_match_handle = event->requestor_instance_id;
2043 global_header_handle = event->publish_subscribe_id;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002044 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__);
2045 nan_hex_dump(global_dut, event->service_specific_info,
2046 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002047 event_anyresponse = 1;
2048 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
2049 "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002050 MAC_ADDR_STR " ", event->requestor_instance_id >> 24,
2051 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002052}
2053
2054
2055/* Events Callback */
2056void nan_event_disceng_event(NanDiscEngEventInd *event)
2057{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002058 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d",
2059 __func__, event->event_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002060
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002061 if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002062 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster "
2063 MAC_ADDR_STR,
2064 __func__,
2065 MAC_ADDR_ARRAY(event->data.cluster.addr));
Kantesh Mundaragi116be192016-10-19 17:10:52 -07002066 /* To ensure sta_get_events to get the events
2067 * only after joining the NAN cluster. */
2068 pthread_cond_signal(&gCondition);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002069 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002070 if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002071 sigma_dut_print(global_dut, DUT_MSG_INFO,
2072 "%s: Started cluster " MAC_ADDR_STR,
2073 __func__,
2074 MAC_ADDR_ARRAY(event->data.cluster.addr));
2075 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002076 if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) {
2077 sigma_dut_print(global_dut, DUT_MSG_INFO,
2078 "%s: Discovery Mac Address "
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002079 MAC_ADDR_STR,
2080 __func__,
2081 MAC_ADDR_ARRAY(event->data.mac_addr.addr));
2082 memcpy(global_nan_mac_addr, event->data.mac_addr.addr,
2083 sizeof(global_nan_mac_addr));
2084 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002085}
2086
2087
2088/* Events Callback */
2089void nan_event_disabled(NanDisabledInd *event)
2090{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002091 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d",
2092 __func__, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002093 /* pthread_cond_signal(&gCondition); */
2094}
2095
2096
Rakesh Sunki4c086672017-03-30 14:47:55 -07002097/* Events callback */
2098static void ndp_event_data_indication(NanDataPathRequestInd *event)
2099{
2100 sigma_dut_print(global_dut, DUT_MSG_INFO,
2101 "%s: Service Instance Id: %d Peer Discovery MAC ADDR "
2102 MAC_ADDR_STR
2103 " NDP Instance Id: %d App Info len %d App Info %s",
2104 __func__,
2105 event->service_instance_id,
2106 MAC_ADDR_ARRAY(event->peer_disc_mac_addr),
2107 event->ndp_instance_id,
2108 event->app_info.ndp_app_info_len,
2109 event->app_info.ndp_app_info);
2110
2111 global_ndp_instance_id = event->ndp_instance_id;
2112}
2113
2114
2115/* Events callback */
2116static void ndp_event_data_confirm(NanDataPathConfirmInd *event)
2117{
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07002118 char cmd[200];
2119 char ipv6_buf[100];
2120
Rakesh Sunki4c086672017-03-30 14:47:55 -07002121 sigma_dut_print(global_dut, DUT_MSG_INFO,
2122 "Received NDP Confirm Indication");
2123
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07002124 memset(cmd, 0, sizeof(cmd));
2125 memset(ipv6_buf, 0, sizeof(ipv6_buf));
2126
Rakesh Sunki4c086672017-03-30 14:47:55 -07002127 global_ndp_instance_id = event->ndp_instance_id;
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07002128
2129 if (event->rsp_code == NAN_DP_REQUEST_ACCEPT) {
2130 if (system("ifconfig nan0 up") != 0) {
2131 sigma_dut_print(global_dut, DUT_MSG_ERROR,
2132 "Failed to set nan interface up");
2133 return;
2134 }
Peng Xu78a3cbd2018-07-27 14:05:34 -07002135 if (system("ip -6 route replace fe80::/64 dev nan0 table local") !=
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07002136 0) {
2137 sigma_dut_print(global_dut, DUT_MSG_ERROR,
2138 "Failed to run:ip -6 route replace fe80::/64 dev nan0 table local");
2139 }
Peng Xu7be50b12018-10-11 15:50:13 -07002140#if ((NAN_MAJOR_VERSION > 2) || \
2141 (NAN_MAJOR_VERSION == 2 && NAN_MINOR_VERSION >= 1)) && \
2142 NAN_CERT_VERSION >= 5
Peng Xu78a3cbd2018-07-27 14:05:34 -07002143 if (event->nan_ipv6_addr_present)
2144 snprintf(ipv6_buf, sizeof(ipv6_buf),
2145 "fe80::%02x%02x:%02xff:fe%02x:%02x%02x",
2146 event->nan_ipv6_intf_addr[8],
2147 event->nan_ipv6_intf_addr[9],
2148 event->nan_ipv6_intf_addr[10],
2149 event->nan_ipv6_intf_addr[13],
2150 event->nan_ipv6_intf_addr[14],
2151 event->nan_ipv6_intf_addr[15]);
2152 else
2153#endif
2154 convert_mac_addr_to_ipv6_lladdr(
2155 event->peer_ndi_mac_addr,
2156 ipv6_buf, sizeof(ipv6_buf));
2157
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07002158 snprintf(cmd, sizeof(cmd),
2159 "ip -6 neighbor replace %s lladdr %02x:%02x:%02x:%02x:%02x:%02x nud permanent dev nan0",
2160 ipv6_buf, event->peer_ndi_mac_addr[0],
2161 event->peer_ndi_mac_addr[1],
2162 event->peer_ndi_mac_addr[2],
2163 event->peer_ndi_mac_addr[3],
2164 event->peer_ndi_mac_addr[4],
2165 event->peer_ndi_mac_addr[5]);
2166 sigma_dut_print(global_dut, DUT_MSG_INFO,
2167 "neighbor replace cmd = %s", cmd);
2168 if (system(cmd) != 0) {
2169 sigma_dut_print(global_dut, DUT_MSG_ERROR,
2170 "Failed to run: ip -6 neighbor replace");
2171 return;
2172 }
Rakesh Sunki4c086672017-03-30 14:47:55 -07002173 }
2174}
2175
2176
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002177void * my_thread_function(void *ptr)
2178{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002179 wifi_event_loop(global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002180 pthread_exit(0);
2181 return (void *) NULL;
2182}
2183
2184
2185static NanCallbackHandler callbackHandler = {
2186 .NotifyResponse = nan_notify_response,
2187 .EventPublishReplied = nan_event_publish_replied,
2188 .EventPublishTerminated = nan_event_publish_terminated,
2189 .EventMatch = nan_event_match,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002190 .EventMatchExpired = nan_event_match_expired,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002191 .EventSubscribeTerminated = nan_event_subscribe_terminated,
2192 .EventFollowup = nan_event_followup,
2193 .EventDiscEngEvent = nan_event_disceng_event,
2194 .EventDisabled = nan_event_disabled,
Rakesh Sunki4c086672017-03-30 14:47:55 -07002195 .EventDataRequest = ndp_event_data_indication,
2196 .EventDataConfirm = ndp_event_data_confirm,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002197};
2198
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07002199
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002200void nan_init(struct sigma_dut *dut)
2201{
2202 pthread_t thread1; /* thread variables */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002203 wifi_error err = wifi_initialize(&global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002204
2205 if (err) {
2206 printf("wifi hal initialize failed\n");
2207 return;
2208 }
2209
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07002210 global_interface_handle = wifi_get_iface_handle(global_wifi_handle,
2211 (char *) "wlan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002212 /* create threads 1 */
2213 pthread_create(&thread1, NULL, &my_thread_function, NULL);
2214
2215 pthread_mutex_init(&gMutex, NULL);
2216 pthread_cond_init(&gCondition, NULL);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07002217 if (global_interface_handle)
2218 nan_register_handler(global_interface_handle, callbackHandler);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002219}
2220
2221
2222void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
2223 struct sigma_cmd *cmd)
2224{
2225 sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default");
2226
Anurag Das2052daa2018-08-31 14:35:25 +05302227#ifdef ANDROID
2228 if (dut->nanservicediscoveryinprogress) {
2229 char *argv[5];
2230 pid_t pid;
2231
2232 argv[0] = "am";
2233 argv[1] = "broadcast";
2234 argv[2] = "-a";
2235 argv[3] = "org.codeaurora.nanservicediscovery.close";
2236 argv[4] = NULL;
2237
2238 pid = fork();
2239 if (pid == -1) {
2240 sigma_dut_print(dut, DUT_MSG_ERROR, "fork: %s",
2241 strerror(errno));
2242 } else if (pid == 0) {
2243 execv("/system/bin/am", argv);
2244 sigma_dut_print(dut, DUT_MSG_ERROR, "execv: %s",
2245 strerror(errno));
2246 exit(0);
2247 }
2248 dut->nanservicediscoveryinprogress = 0;
2249 }
2250#endif /* ANDROID */
2251
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002252 if (nan_state == 0) {
2253 nan_init(dut);
2254 nan_state = 1;
2255 }
2256 is_fam = 0;
2257 event_anyresponse = 0;
2258 global_dut = dut;
Rakesh Sunki7d37f412017-03-30 14:47:55 -07002259 memset(&dut->nan_pmk[0], 0, NAN_PMK_INFO_LEN);
2260 dut->nan_pmk_len = 0;
Rakesh Sunkid7344c02017-03-30 14:47:55 -07002261 dut->sta_channel = 0;
Peng Xu8863ec72018-08-06 11:50:37 -07002262 dut->ndpe = 0;
2263 dut->trans_proto = NAN_TRANSPORT_PROTOCOL_DEFAULT;
2264 dut->trans_port = NAN_TRANSPORT_PORT_DEFAULT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002265 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002266 memset(&global_nan_sync_stats, 0, sizeof(global_nan_sync_stats));
Rakesh Sunki42363682017-05-16 15:00:42 -07002267 memset(global_publish_service_name, 0,
2268 sizeof(global_publish_service_name));
2269 global_publish_service_name_len = 0;
2270 global_publish_id = 0;
Rakesh Sunki0262cb52017-05-17 14:22:05 -07002271 global_subscribe_id = 0;
Rakesh Sunki7a40a202017-03-30 14:47:55 -07002272
Rakesh Sunki8a630b82017-03-30 14:47:55 -07002273 sigma_nan_data_end(dut, cmd);
Rakesh Sunki7a40a202017-03-30 14:47:55 -07002274 nan_data_interface_delete(0, global_interface_handle, (char *) "nan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002275 sigma_nan_disable(dut, conn, cmd);
Rakesh Sunkifa417332017-08-16 15:41:32 -07002276 global_header_handle = 0;
2277 global_match_handle = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002278}
2279
2280
2281int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
2282 struct sigma_cmd *cmd)
2283{
2284 const char *program = get_param(cmd, "Prog");
2285 const char *nan_op = get_param(cmd, "NANOp");
2286 const char *method_type = get_param(cmd, "MethodType");
Rakesh Sunkid7344c02017-03-30 14:47:55 -07002287 const char *band = get_param(cmd, "band");
Anurag Das2052daa2018-08-31 14:35:25 +05302288 const char *disc_mac_addr = get_param(cmd, "DiscoveryMacAddress");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002289 char resp_buf[100];
Rakesh Sunki7a40a202017-03-30 14:47:55 -07002290 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002291
2292 if (program == NULL)
2293 return -1;
2294
2295 if (strcasecmp(program, "NAN") != 0) {
2296 send_resp(dut, conn, SIGMA_ERROR,
2297 "ErrorCode,Unsupported program");
2298 return 0;
2299 }
2300
2301 if (nan_op) {
Rakesh Sunkib5604ff2017-05-16 15:47:08 -07002302#if NAN_CERT_VERSION >= 3
2303 int size = 0;
2304 u32 device_type_val = 0;
2305 NanDebugParams cfg_debug;
2306
2307 memset(&cfg_debug, 0, sizeof(NanDebugParams));
2308 cfg_debug.cmd = NAN_TEST_MODE_CMD_DEVICE_TYPE;
2309 if (dut->device_type == STA_testbed)
2310 device_type_val = NAN_DEVICE_TYPE_TEST_BED;
2311 else if (dut->device_type == STA_dut)
2312 device_type_val = NAN_DEVICE_TYPE_DUT;
2313
2314 memcpy(cfg_debug.debug_cmd_data, &device_type_val, sizeof(u32));
2315 size = sizeof(u32) + sizeof(u32);
2316 sigma_dut_print(dut, DUT_MSG_INFO,
2317 "%s: Device Type: cmd type = %d and command data = %u",
2318 __func__, cfg_debug.cmd, device_type_val);
2319 nan_debug_command_config(0, global_interface_handle,
2320 cfg_debug, size);
2321#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002322 /*
2323 * NANOp has been specified.
2324 * We will build a nan_enable or nan_disable command.
2325 */
2326 if (strcasecmp(nan_op, "On") == 0) {
2327 if (sigma_nan_enable(dut, conn, cmd) == 0) {
Rakesh Sunki7a40a202017-03-30 14:47:55 -07002328 ret = nan_data_interface_create(
2329 0, global_interface_handle,
2330 (char *) "nan0");
2331 if (ret != WIFI_SUCCESS) {
2332 sigma_dut_print(
2333 global_dut, DUT_MSG_ERROR,
2334 "Unable to create NAN data interface");
2335 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002336 snprintf(resp_buf, sizeof(resp_buf), "mac,"
2337 MAC_ADDR_STR,
2338 MAC_ADDR_ARRAY(global_nan_mac_addr));
2339 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
2340 } else {
2341 send_resp(dut, conn, SIGMA_ERROR,
2342 "NAN_ENABLE_FAILED");
2343 return -1;
2344 }
Rakesh Sunkid7344c02017-03-30 14:47:55 -07002345
2346 if (band && strcasecmp(band, "24g") == 0) {
2347 sigma_dut_print(dut, DUT_MSG_INFO,
2348 "%s: Setting band to 2G Only",
2349 __func__);
2350 sigma_ndp_configure_band(
2351 dut, conn, cmd,
2352 NAN_DATA_PATH_SUPPORTED_BAND_2G);
2353 } else if (band && dut->sta_channel > 12) {
2354 sigma_ndp_configure_band(
2355 dut, conn, cmd,
2356 NAN_DATA_PATH_SUPPORT_DUAL_BAND);
2357 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002358 } else if (strcasecmp(nan_op, "Off") == 0) {
Rakesh Sunkibcf9ef32017-08-16 15:53:27 -07002359 nan_data_interface_delete(0,
2360 global_interface_handle, (char *) "nan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002361 sigma_nan_disable(dut, conn, cmd);
Rakesh Sunki42363682017-05-16 15:00:42 -07002362 memset(global_publish_service_name, 0,
2363 sizeof(global_publish_service_name));
2364 global_publish_service_name_len = 0;
2365 global_publish_id = 0;
Rakesh Sunki0262cb52017-05-17 14:22:05 -07002366 global_subscribe_id = 0;
Rakesh Sunkifa417332017-08-16 15:41:32 -07002367 global_header_handle = 0;
2368 global_match_handle = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002369 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2370 }
2371 }
2372 if (nan_state && nan_op == NULL) {
2373 if (method_type) {
2374 if (strcasecmp(method_type, "Publish") == 0) {
2375 sigma_nan_publish_request(dut, conn, cmd);
2376 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2377 }
2378 if (strcasecmp(method_type, "Subscribe") == 0) {
2379 sigma_nan_subscribe_request(dut, conn, cmd);
2380 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2381 }
2382 if (strcasecmp(method_type, "Followup") == 0) {
2383 sigma_nan_transmit_followup(dut, conn, cmd);
2384 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2385 }
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07002386 if (strcasecmp(method_type, "DataRequest") == 0) {
2387 sigma_nan_data_request(dut, conn, cmd);
2388 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2389 }
Rakesh Sunkia5cc2842017-03-30 14:47:55 -07002390 if (strcasecmp(method_type, "DataResponse") == 0) {
2391 sigma_dut_print(dut, DUT_MSG_INFO,
2392 "%s: method_type is DataResponse",
2393 __func__);
2394 sigma_nan_data_response(dut, conn, cmd);
2395 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2396 }
Rakesh Sunki8a630b82017-03-30 14:47:55 -07002397 if (strcasecmp(method_type, "DataEnd") == 0) {
2398 sigma_nan_data_end(dut, cmd);
2399 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2400 }
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -07002401 if (strcasecmp(method_type, "rangerequest") == 0) {
2402 sigma_dut_print(dut, DUT_MSG_INFO,
2403 "%s: method_type is rangerequest",
2404 __func__);
2405 sigma_nan_range_request(dut, cmd);
2406 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2407 }
2408 if (strcasecmp(method_type, "cancelrange") == 0) {
2409 sigma_dut_print(dut, DUT_MSG_INFO,
2410 "%s: method_type is cancelrange",
2411 __func__);
2412 sigma_nan_cancel_range(dut, cmd);
2413 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2414 }
Rakesh Sunkib2b65162017-03-30 14:47:55 -07002415 if (strcasecmp(method_type, "SchedUpdate") == 0) {
2416 sigma_dut_print(dut, DUT_MSG_INFO,
2417 "%s: method_type is SchedUpdate",
2418 __func__);
2419 sigma_nan_schedule_update(dut, cmd);
2420 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2421 }
Anurag Das2052daa2018-08-31 14:35:25 +05302422 } else if (disc_mac_addr &&
2423 strcasecmp(disc_mac_addr, "GET") == 0) {
2424 snprintf(resp_buf, sizeof(resp_buf), "mac,"
2425 MAC_ADDR_STR,
2426 MAC_ADDR_ARRAY(global_nan_mac_addr));
2427 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002428 } else {
2429 sigma_nan_config_enable(dut, conn, cmd);
2430 snprintf(resp_buf, sizeof(resp_buf), "mac,"
2431 MAC_ADDR_STR,
2432 MAC_ADDR_ARRAY(global_nan_mac_addr));
2433 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
2434 }
2435 }
2436
2437 return 0;
2438}
2439
2440
2441int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
2442 struct sigma_cmd *cmd)
2443{
2444
2445 const char *program = get_param(cmd, "Program");
2446 const char *parameter = get_param(cmd, "Parameter");
2447 char resp_buf[100];
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002448 NanStatsRequest req;
2449 struct timespec abstime;
2450 u64 master_rank;
2451 u8 master_pref;
2452 u8 random_factor;
2453 u8 hop_count;
2454 u32 beacon_transmit_time;
2455 u32 ndp_channel_freq;
2456 u32 ndp_channel_freq2;
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002457#if NAN_CERT_VERSION >= 3
2458 u32 sched_update_channel_freq;
2459#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002460
2461 if (program == NULL) {
2462 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name");
2463 return -1;
2464 }
2465 if (strcasecmp(program, "NAN") != 0) {
2466 send_resp(dut, conn, SIGMA_ERROR,
2467 "ErrorCode,Unsupported program");
2468 return 0;
2469 }
2470
2471 if (parameter == NULL) {
2472 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter");
2473 return -1;
2474 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002475
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002476 memset(&req, 0, sizeof(NanStatsRequest));
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002477 memset(resp_buf, 0, sizeof(resp_buf));
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002478 req.stats_type = (NanStatsType) NAN_STATS_ID_DE_TIMING_SYNC;
2479 nan_stats_request(0, global_interface_handle, &req);
2480 /*
2481 * To ensure sta_get_events to get the events
2482 * only after joining the NAN cluster
2483 */
2484 abstime.tv_sec = 4;
2485 abstime.tv_nsec = 0;
2486 wait(abstime);
2487
2488 master_rank = global_nan_sync_stats.myRank;
2489 master_pref = (global_nan_sync_stats.myRank & 0xFF00000000000000) >> 56;
2490 random_factor = (global_nan_sync_stats.myRank & 0x00FF000000000000) >>
2491 48;
2492 hop_count = global_nan_sync_stats.currAmHopCount;
2493 beacon_transmit_time = global_nan_sync_stats.currAmBTT;
2494 ndp_channel_freq = global_nan_sync_stats.ndpChannelFreq;
2495 ndp_channel_freq2 = global_nan_sync_stats.ndpChannelFreq2;
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002496#if NAN_CERT_VERSION >= 3
2497 sched_update_channel_freq =
2498 global_nan_sync_stats.schedUpdateChannelFreq;
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002499
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002500 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002501 "%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",
2502 __func__, master_pref, random_factor,
2503 hop_count, beacon_transmit_time,
2504 ndp_channel_freq, ndp_channel_freq2,
2505 sched_update_channel_freq);
2506#else /* #if NAN_CERT_VERSION >= 3 */
2507 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002508 "%s: NanStatsRequest Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d ndp_channel_freq:%d ndp_channel_freq2:%d",
2509 __func__, master_pref, random_factor,
2510 hop_count, beacon_transmit_time,
2511 ndp_channel_freq, ndp_channel_freq2);
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002512#endif /* #if NAN_CERT_VERSION >= 3 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002513
2514 if (strcasecmp(parameter, "MasterPref") == 0) {
2515 snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002516 master_pref);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002517 } else if (strcasecmp(parameter, "MasterRank") == 0) {
2518 snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002519 master_rank);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002520 } else if (strcasecmp(parameter, "RandFactor") == 0) {
2521 snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002522 random_factor);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002523 } else if (strcasecmp(parameter, "HopCount") == 0) {
2524 snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002525 hop_count);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002526 } else if (strcasecmp(parameter, "BeaconTransTime") == 0) {
2527 snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002528 beacon_transmit_time);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002529 } else if (strcasecmp(parameter, "NANStatus") == 0) {
2530 if (nan_state == 1)
2531 snprintf(resp_buf, sizeof(resp_buf), "On");
2532 else
2533 snprintf(resp_buf, sizeof(resp_buf), "Off");
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002534 } else if (strcasecmp(parameter, "NDPChannel") == 0) {
2535 if (ndp_channel_freq != 0 && ndp_channel_freq2 != 0) {
2536 snprintf(resp_buf, sizeof(resp_buf),
2537 "ndpchannel,%d,ndpchannel,%d",
2538 freq_to_channel(ndp_channel_freq),
2539 freq_to_channel(ndp_channel_freq2));
2540 } else if (ndp_channel_freq != 0) {
2541 snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
2542 freq_to_channel(ndp_channel_freq));
2543 } else if (ndp_channel_freq2 != 0) {
2544 snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
2545 freq_to_channel(ndp_channel_freq2));
2546 } else {
2547 sigma_dut_print(dut, DUT_MSG_ERROR,
2548 "%s: No Negotiated NDP Channels", __func__);
2549 }
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002550#if NAN_CERT_VERSION >= 3
2551 } else if (strcasecmp(parameter, "SchedUpdateChannel") == 0) {
2552 snprintf(resp_buf, sizeof(resp_buf), "schedupdatechannel,%d",
2553 freq_to_channel(sched_update_channel_freq));
2554#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002555 } else {
2556 send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
2557 return 0;
2558 }
2559
2560 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
2561 return 0;
2562}
2563
2564
2565int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
2566 struct sigma_cmd *cmd)
2567{
2568 const char *action = get_param(cmd, "Action");
2569
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07002570 if (!action)
2571 return 0;
2572
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002573 /* Check action for start, stop and get events. */
2574 if (strcasecmp(action, "Start") == 0) {
2575 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
2576 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
2577 } else if (strcasecmp(action, "Stop") == 0) {
2578 event_anyresponse = 0;
2579 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
2580 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
2581 } else if (strcasecmp(action, "Get") == 0) {
2582 if (event_anyresponse == 1) {
2583 send_resp(dut, conn, SIGMA_COMPLETE,
2584 global_event_resp_buf);
2585 } else {
2586 send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE");
2587 }
2588 }
2589 return 0;
2590}
Rakesh Sunki4b75f962017-03-30 14:47:55 -07002591
2592#else /* #if NAN_CERT_VERSION */
2593
2594int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
2595 struct sigma_conn *conn,
2596 struct sigma_cmd *cmd)
2597{
2598 return 1;
2599}
2600
2601
2602int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
2603 struct sigma_cmd *cmd)
2604{
2605 return 0;
2606
2607}
2608
2609
2610void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
2611 struct sigma_cmd *cmd)
2612{
2613 return;
2614}
2615
2616
2617int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
2618 struct sigma_cmd *cmd)
2619{
2620 return 0;
2621}
2622
2623
2624int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
2625 struct sigma_cmd *cmd)
2626{
2627 return 0;
2628}
2629
2630#endif /* #if NAN_CERT_VERSION */