blob: 5ce39379db3016ffb861e33c2b0ba1db44cf9d80 [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (NAN functionality)
Rakesh Sunki4b75f962017-03-30 14:47:55 -07003 * Copyright (c) 2014-2017, Qualcomm Atheros, Inc.
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004 * All Rights Reserved.
5 * Licensed under the Clear BSD license. See README for more details.
6 */
7
8#include "sigma_dut.h"
9#include <sys/stat.h>
10#include "wpa_ctrl.h"
11#include "wpa_helpers.h"
12#include "wifi_hal.h"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -070013#include "nan_cert.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014
Rakesh Sunki4b75f962017-03-30 14:47:55 -070015#if NAN_CERT_VERSION >= 2
16
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017pthread_cond_t gCondition;
18pthread_mutex_t gMutex;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -070019wifi_handle global_wifi_handle;
20wifi_interface_handle global_interface_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020021static int nan_state = 0;
22static int event_anyresponse = 0;
23static int is_fam = 0;
24
Rakesh Sunki4c086672017-03-30 14:47:55 -070025static uint16_t global_ndp_instance_id = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020026uint16_t global_header_handle = 0;
27uint32_t global_match_handle = 0;
28
29#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
30#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
31#ifndef ETH_ALEN
32#define ETH_ALEN 6
33#endif
34
35struct sigma_dut *global_dut = NULL;
36static char global_nan_mac_addr[ETH_ALEN];
37static char global_event_resp_buf[1024];
38
39static int nan_further_availability_tx(struct sigma_dut *dut,
40 struct sigma_conn *conn,
41 struct sigma_cmd *cmd);
42static int nan_further_availability_rx(struct sigma_dut *dut,
43 struct sigma_conn *conn,
44 struct sigma_cmd *cmd);
45
46
47void nan_hex_dump(struct sigma_dut *dut, uint8_t *data, size_t len)
48{
49 char buf[512];
50 uint16_t index;
51 uint8_t *ptr;
52 int pos;
53
54 memset(buf, 0, sizeof(buf));
55 ptr = data;
56 pos = 0;
57 for (index = 0; index < len; index++) {
58 pos += sprintf(&(buf[pos]), "%02x ", *ptr++);
59 if (pos > 508)
60 break;
61 }
62 sigma_dut_print(dut, DUT_MSG_INFO, "HEXDUMP len=[%d]", (int) len);
63 sigma_dut_print(dut, DUT_MSG_INFO, "buf:%s", buf);
64}
65
66
67int nan_parse_hex(unsigned char c)
68{
69 if (c >= '0' && c <= '9')
70 return c - '0';
71 if (c >= 'a' && c <= 'f')
72 return c - 'a' + 10;
73 if (c >= 'A' && c <= 'F')
74 return c - 'A' + 10;
75 return 0;
76}
77
78
79int nan_parse_token(const char *tokenIn, u8 *tokenOut, int *filterLen)
80{
81 int total_len = 0, len = 0;
82 char *saveptr = NULL;
83
84 tokenIn = strtok_r((char *) tokenIn, ":", &saveptr);
85 while (tokenIn != NULL) {
86 len = strlen(tokenIn);
87 if (len == 1 && *tokenIn == '*')
88 len = 0;
89 tokenOut[total_len++] = (u8) len;
90 if (len != 0)
91 memcpy((u8 *) tokenOut + total_len, tokenIn, len);
92 total_len += len;
93 tokenIn = strtok_r(NULL, ":", &saveptr);
94 }
95 *filterLen = total_len;
96 return 0;
97}
98
99
100int nan_parse_mac_address(struct sigma_dut *dut, const char *arg, u8 *addr)
101{
102 if (strlen(arg) != 17) {
103 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid mac address %s",
104 arg);
105 sigma_dut_print(dut, DUT_MSG_ERROR,
106 "expected format xx:xx:xx:xx:xx:xx");
107 return -1;
108 }
109
110 addr[0] = nan_parse_hex(arg[0]) << 4 | nan_parse_hex(arg[1]);
111 addr[1] = nan_parse_hex(arg[3]) << 4 | nan_parse_hex(arg[4]);
112 addr[2] = nan_parse_hex(arg[6]) << 4 | nan_parse_hex(arg[7]);
113 addr[3] = nan_parse_hex(arg[9]) << 4 | nan_parse_hex(arg[10]);
114 addr[4] = nan_parse_hex(arg[12]) << 4 | nan_parse_hex(arg[13]);
115 addr[5] = nan_parse_hex(arg[15]) << 4 | nan_parse_hex(arg[16]);
116
117 return 0;
118}
119
120
121int nan_parse_mac_address_list(struct sigma_dut *dut, const char *input,
122 u8 *output, u16 max_addr_allowed)
123{
124 /*
125 * Reads a list of mac address separated by space. Each MAC address
126 * should have the format of aa:bb:cc:dd:ee:ff.
127 */
128 char *saveptr;
129 char *token;
130 int i = 0;
131
132 for (i = 0; i < max_addr_allowed; i++) {
133 token = strtok_r((i == 0) ? (char *) input : NULL,
134 " ", &saveptr);
135 if (token) {
136 nan_parse_mac_address(dut, token, output);
137 output += NAN_MAC_ADDR_LEN;
138 } else
139 break;
140 }
141
142 sigma_dut_print(dut, DUT_MSG_INFO, "Num MacAddress:%d", i);
143
144 return i;
145}
146
147
148int nan_parse_hex_string(struct sigma_dut *dut, const char *input,
149 u8 *output, int *outputlen)
150{
151 int i = 0;
152 int j = 0;
153
154 for (i = 0; i < (int) strlen(input) && j < *outputlen; i += 2) {
155 output[j] = nan_parse_hex(input[i]);
156 if (i + 1 < (int) strlen(input)) {
157 output[j] = ((output[j] << 4) |
158 nan_parse_hex(input[i + 1]));
159 }
160 j++;
161 }
162 *outputlen = j;
163 sigma_dut_print(dut, DUT_MSG_INFO, "Input:%s inputlen:%d outputlen:%d",
164 input, (int) strlen(input), (int) *outputlen);
165 return 0;
166}
167
168
169int wait(struct timespec abstime)
170{
171 struct timeval now;
172
173 gettimeofday(&now, NULL);
174
175 abstime.tv_sec += now.tv_sec;
176 if (((abstime.tv_nsec + now.tv_usec * 1000) > 1000 * 1000 * 1000) ||
177 (abstime.tv_nsec + now.tv_usec * 1000 < 0)) {
178 abstime.tv_sec += 1;
179 abstime.tv_nsec += now.tv_usec * 1000;
180 abstime.tv_nsec -= 1000 * 1000 * 1000;
181 } else {
182 abstime.tv_nsec += now.tv_usec * 1000;
183 }
184
185 return pthread_cond_timedwait(&gCondition, &gMutex, &abstime);
186}
187
188
189int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
190 struct sigma_conn *conn,
191 struct sigma_cmd *cmd)
192{
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700193 const char *oper_chan = get_param(cmd, "oper_chn");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200194
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700195 if (oper_chan) {
196 sigma_dut_print(dut, DUT_MSG_INFO, "Operating Channel: %s",
197 oper_chan);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700198 dut->sta_channel = atoi(oper_chan);
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700199 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200200
Rakesh Sunki14bff1d2017-03-30 14:47:55 -0700201 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200202 return 0;
203}
204
205
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700206void nan_print_further_availability_chan(struct sigma_dut *dut,
207 u8 num_chans,
208 NanFurtherAvailabilityChannel *fachan)
209{
210 int idx;
211
212 sigma_dut_print(dut, DUT_MSG_INFO,
213 "********Printing FurtherAvailabilityChan Info******");
214 sigma_dut_print(dut, DUT_MSG_INFO, "Numchans:%d", num_chans);
215 for (idx = 0; idx < num_chans; idx++) {
216 sigma_dut_print(dut, DUT_MSG_INFO,
217 "[%d]: NanAvailDuration:%d class_val:%02x channel:%d",
218 idx, fachan->entry_control,
219 fachan->class_val, fachan->channel);
220 sigma_dut_print(dut, DUT_MSG_INFO,
221 "[%d]: mapid:%d Availability bitmap:%08x",
222 idx, fachan->mapid,
223 fachan->avail_interval_bitmap);
224 }
225 sigma_dut_print(dut, DUT_MSG_INFO,
226 "*********************Done**********************");
227}
228
229
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200230int sigma_nan_enable(struct sigma_dut *dut, struct sigma_conn *conn,
231 struct sigma_cmd *cmd)
232{
233 const char *master_pref = get_param(cmd, "MasterPref");
234 const char *rand_fac = get_param(cmd, "RandFactor");
235 const char *hop_count = get_param(cmd, "HopCount");
236 const char *high_tsf = get_param(cmd, "HighTSF");
237 const char *sdftx_band = get_param(cmd, "SDFTxBand");
238 const char *oper_chan = get_param(cmd, "oper_chn");
239 const char *further_avail_ind = get_param(cmd, "FurtherAvailInd");
240 const char *band = get_param(cmd, "Band");
241 const char *only_5g = get_param(cmd, "5GOnly");
242 struct timespec abstime;
243 NanEnableRequest req;
244
245 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200246 req.cluster_low = 0;
247 req.cluster_high = 0xFFFF;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700248 req.master_pref = 100;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200249
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700250 /* This is a debug hack to beacon in channel 11 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200251 if (oper_chan) {
252 req.config_2dot4g_support = 1;
253 req.support_2dot4g_val = 111;
254 }
255
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200256 if (master_pref) {
257 int master_pref_val = strtoul(master_pref, NULL, 0);
258
259 req.master_pref = master_pref_val;
260 }
261
262 if (rand_fac) {
263 int rand_fac_val = strtoul(rand_fac, NULL, 0);
264
265 req.config_random_factor_force = 1;
266 req.random_factor_force_val = rand_fac_val;
267 }
268
269 if (hop_count) {
270 int hop_count_val = strtoul(hop_count, NULL, 0);
271
272 req.config_hop_count_force = 1;
273 req.hop_count_force_val = hop_count_val;
274 }
275
276 if (sdftx_band) {
277 if (strcasecmp(sdftx_band, "5G") == 0) {
278 req.config_2dot4g_support = 1;
279 req.support_2dot4g_val = 0;
280 }
281 }
282
283 if (band) {
284 if (strcasecmp(band, "24G") == 0) {
285 sigma_dut_print(dut, DUT_MSG_INFO,
286 "Band 2.4GHz selected");
287 /* Enable 2.4G support */
288 req.config_2dot4g_support = 1;
289 req.support_2dot4g_val = 1;
290 req.config_2dot4g_beacons = 1;
291 req.beacon_2dot4g_val = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700292 req.config_2dot4g_sdf = 1;
293 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200294
295 /* Disable 5G support */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700296 req.config_support_5g = 1;
297 req.support_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200298 req.config_5g_beacons = 1;
299 req.beacon_5g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700300 req.config_5g_sdf = 1;
301 req.sdf_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200302 }
303 }
304
305 if (further_avail_ind) {
306 sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled");
307 if (strcasecmp(further_avail_ind, "tx") == 0) {
308 is_fam = 1;
309 nan_further_availability_tx(dut, conn, cmd);
310 return 0;
311 } else if (strcasecmp(further_avail_ind, "rx") == 0) {
312 nan_further_availability_rx(dut, conn, cmd);
313 return 0;
314 }
315 }
316
317 if (only_5g && atoi(only_5g)) {
318 sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled");
319 req.config_2dot4g_support = 1;
320 req.support_2dot4g_val = 1;
321 req.config_2dot4g_beacons = 1;
322 req.beacon_2dot4g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700323 req.config_2dot4g_sdf = 1;
324 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200325 }
326
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700327 nan_enable_request(0, global_interface_handle, &req);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700328
329 /* To ensure sta_get_events to get the events
330 * only after joining the NAN cluster. */
331 abstime.tv_sec = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200332 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700333 wait(abstime);
334
335 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200336}
337
338
339int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn,
340 struct sigma_cmd *cmd)
341{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200342 struct timespec abstime;
343
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700344 nan_disable_request(0, global_interface_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200345
346 abstime.tv_sec = 4;
347 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700348 wait(abstime);
349
350 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200351}
352
353
354int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn,
355 struct sigma_cmd *cmd)
356{
357 const char *master_pref = get_param(cmd, "MasterPref");
358 const char *rand_fac = get_param(cmd, "RandFactor");
359 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700360 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200361 struct timespec abstime;
362 NanConfigRequest req;
363
364 memset(&req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200365 req.config_rssi_proximity = 1;
366 req.rssi_proximity = 70;
367
368 if (master_pref) {
369 int master_pref_val = strtoul(master_pref, NULL, 0);
370
371 req.config_master_pref = 1;
372 req.master_pref = master_pref_val;
373 }
374
375 if (rand_fac) {
376 int rand_fac_val = strtoul(rand_fac, NULL, 0);
377
378 req.config_random_factor_force = 1;
379 req.random_factor_force_val = rand_fac_val;
380 }
381
382 if (hop_count) {
383 int hop_count_val = strtoul(hop_count, NULL, 0);
384
385 req.config_hop_count_force = 1;
386 req.hop_count_force_val = hop_count_val;
387 }
388
Rakesh Sunki107356c2017-03-30 14:47:55 -0700389 ret = nan_config_request(0, global_interface_handle, &req);
390 if (ret != WIFI_SUCCESS)
391 send_resp(dut, conn, SIGMA_ERROR, "NAN config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200392
393 abstime.tv_sec = 4;
394 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700395 wait(abstime);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200396
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700397 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200398}
399
400
401static int sigma_nan_subscribe_request(struct sigma_dut *dut,
402 struct sigma_conn *conn,
403 struct sigma_cmd *cmd)
404{
405 const char *subscribe_type = get_param(cmd, "SubscribeType");
406 const char *service_name = get_param(cmd, "ServiceName");
407 const char *disc_range = get_param(cmd, "DiscoveryRange");
408 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
409 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
410 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
411 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
412 const char *include_bit = get_param(cmd, "IncludeBit");
413 const char *mac = get_param(cmd, "MAC");
414 const char *srf_type = get_param(cmd, "SRFType");
415 NanSubscribeRequest req;
416 int filter_len_rx = 0, filter_len_tx = 0;
417 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
418 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700419 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200420
421 memset(&req, 0, sizeof(NanSubscribeRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200422 req.ttl = 0;
423 req.period = 1000;
424 req.subscribe_type = 1;
425 req.serviceResponseFilter = 1; /* MAC */
426 req.serviceResponseInclude = 0;
427 req.ssiRequiredForMatchIndication = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700428 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200429 req.subscribe_count = 0;
430
431 if (subscribe_type) {
432 if (strcasecmp(subscribe_type, "Active") == 0) {
433 req.subscribe_type = 1;
434 } else if (strcasecmp(subscribe_type, "Passive") == 0) {
435 req.subscribe_type = 0;
436 } else if (strcasecmp(subscribe_type, "Cancel") == 0) {
437 NanSubscribeCancelRequest req;
438
439 memset(&req, 0, sizeof(NanSubscribeCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700440 ret = nan_subscribe_cancel_request(
441 0, global_interface_handle, &req);
442 if (ret != WIFI_SUCCESS) {
443 send_resp(dut, conn, SIGMA_ERROR,
444 "NAN subscribe cancel request failed");
445 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200446 return 0;
447 }
448 }
449
450 if (disc_range)
451 req.rssi_threshold_flag = atoi(disc_range);
452
453 if (sdftx_dw)
454 req.subscribe_count = atoi(sdftx_dw);
455
456 /* Check this once again if config can be called here (TBD) */
457 if (discrange_ltd)
458 req.rssi_threshold_flag = atoi(discrange_ltd);
459
460 if (include_bit) {
461 int include_bit_val = atoi(include_bit);
462
463 req.serviceResponseInclude = include_bit_val;
464 sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d",
465 req.serviceResponseInclude);
466 }
467
468 if (srf_type) {
469 int srf_type_val = atoi(srf_type);
470
471 if (srf_type_val == 1)
472 req.serviceResponseFilter = 0; /* Bloom */
473 else
474 req.serviceResponseFilter = 1; /* MAC */
475 req.useServiceResponseFilter = 1;
476 sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d",
477 req.serviceResponseFilter);
478 }
479
480 if (mac) {
481 sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac);
482 req.num_intf_addr_present = nan_parse_mac_address_list(
483 dut, mac, &req.intf_addr[0][0],
484 NAN_MAX_SUBSCRIBE_MAX_ADDRESS);
485 }
486
487 memset(input_rx, 0, sizeof(input_rx));
488 memset(input_tx, 0, sizeof(input_tx));
489 if (rx_match_filter) {
490 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
491 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
492 filter_len_rx);
493 }
494 if (tx_match_filter) {
495 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
496 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
497 filter_len_tx);
498 }
499
500 if (tx_match_filter) {
501 req.tx_match_filter_len = filter_len_tx;
502 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
503 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
504 }
505 if (rx_match_filter) {
506 req.rx_match_filter_len = filter_len_rx;
507 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
508 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
509 }
510
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700511 if (service_name) {
512 strlcpy((char *) req.service_name, service_name,
513 strlen(service_name) + 1);
514 req.service_name_len = strlen(service_name);
515 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200516
Rakesh Sunki107356c2017-03-30 14:47:55 -0700517 ret = nan_subscribe_request(0, global_interface_handle, &req);
518 if (ret != WIFI_SUCCESS) {
519 send_resp(dut, conn, SIGMA_ERROR,
520 "NAN subscribe request failed");
521 }
522
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200523 return 0;
524}
525
526
Rakesh Sunkid7344c02017-03-30 14:47:55 -0700527static int sigma_ndp_configure_band(struct sigma_dut *dut,
528 struct sigma_conn *conn,
529 struct sigma_cmd *cmd,
530 NdpSupportedBand band_config_val)
531{
532 wifi_error ret;
533 NanDebugParams cfg_debug;
534 int size;
535
536 memset(&cfg_debug, 0, sizeof(NanDebugParams));
537 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS;
538 memcpy(cfg_debug.debug_cmd_data, &band_config_val, sizeof(int));
539 sigma_dut_print(dut, DUT_MSG_INFO, "%s:setting debug cmd=0x%x",
540 __func__, cfg_debug.cmd);
541 size = sizeof(u32) + sizeof(int);
542 ret = nan_debug_command_config(0, global_interface_handle, cfg_debug,
543 size);
544 if (ret != WIFI_SUCCESS)
545 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
546
547 return 0;
548}
549
550
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200551int config_post_disc_attr(void)
552{
Rakesh Sunki107356c2017-03-30 14:47:55 -0700553 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200554 NanConfigRequest configReq;
555
556 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200557
558 /* Configure Post disc attr */
559 /* Make these defines and use correct enum */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700560 configReq.num_config_discovery_attr = 1;
561 configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */
562 configReq.discovery_attr_val[0].role = 0;
563 configReq.discovery_attr_val[0].transmit_freq = 1;
564 configReq.discovery_attr_val[0].duration = 0;
565 configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200566
Rakesh Sunki107356c2017-03-30 14:47:55 -0700567 ret = nan_config_request(0, global_interface_handle, &configReq);
568 if (ret != WIFI_SUCCESS) {
569 sigma_dut_print(global_dut, DUT_MSG_INFO,
570 "NAN config request failed while configuring post discovery attribute");
571 }
572
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200573 return 0;
574}
575
576
577int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn,
578 struct sigma_cmd *cmd)
579{
580 const char *publish_type = get_param(cmd, "PublishType");
581 const char *service_name = get_param(cmd, "ServiceName");
582 const char *disc_range = get_param(cmd, "DiscoveryRange");
583 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
584 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
585 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
586 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
587 NanPublishRequest req;
588 int filter_len_rx = 0, filter_len_tx = 0;
589 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
590 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700591 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200592
593 memset(&req, 0, sizeof(NanPublishRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200594 req.ttl = 0;
595 req.period = 500;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700596 req.publish_match_indicator = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200597 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
598 req.tx_type = NAN_TX_TYPE_BROADCAST;
599 req.publish_count = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700600
601 if (service_name) {
602 strlcpy((char *) req.service_name, service_name,
603 strlen(service_name) + 1);
604 req.service_name_len = strlen(service_name);
605 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200606
607 if (publish_type) {
608 if (strcasecmp(publish_type, "Solicited") == 0) {
609 req.publish_type = NAN_PUBLISH_TYPE_SOLICITED;
610 } else if (strcasecmp(publish_type, "Cancel") == 0) {
611 NanPublishCancelRequest req;
612
613 memset(&req, 0, sizeof(NanPublishCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700614 ret = nan_publish_cancel_request(
615 0, global_interface_handle, &req);
616 if (ret != WIFI_SUCCESS) {
617 send_resp(dut, conn, SIGMA_ERROR,
618 "Unable to cancel nan publish request");
619 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200620 return 0;
621 }
622 }
623
624 if (disc_range)
625 req.rssi_threshold_flag = atoi(disc_range);
626
627 if (sdftx_dw)
628 req.publish_count = atoi(sdftx_dw);
629
630 if (discrange_ltd)
631 req.rssi_threshold_flag = atoi(discrange_ltd);
632
633 memset(input_rx, 0, sizeof(input_rx));
634 memset(input_tx, 0, sizeof(input_tx));
635 if (rx_match_filter) {
636 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
637 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
638 filter_len_rx);
639 }
640 if (tx_match_filter) {
641 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
642 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
643 filter_len_tx);
644 }
645
646 if (is_fam == 1) {
647 config_post_disc_attr();
648 /* TODO: Add comments regarding this step */
649 req.connmap = 0x10;
650 }
651
652 if (tx_match_filter) {
653 req.tx_match_filter_len = filter_len_tx;
654 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
655 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
656 }
657
658 if (rx_match_filter) {
659 req.rx_match_filter_len = filter_len_rx;
660 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
661 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
662 }
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700663
664 if (service_name) {
665 strlcpy((char *) req.service_name, service_name,
666 strlen(service_name) + 1);
667 req.service_name_len = strlen(service_name);
668 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200669
Rakesh Sunki107356c2017-03-30 14:47:55 -0700670 ret = nan_publish_request(0, global_interface_handle, &req);
671 if (ret != WIFI_SUCCESS)
672 send_resp(dut, conn, SIGMA_ERROR, "Unable to publish");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200673
674 return 0;
675}
676
677
678static int nan_further_availability_rx(struct sigma_dut *dut,
679 struct sigma_conn *conn,
680 struct sigma_cmd *cmd)
681{
682 const char *master_pref = get_param(cmd, "MasterPref");
683 const char *rand_fac = get_param(cmd, "RandFactor");
684 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700685 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200686 struct timespec abstime;
687
688 NanEnableRequest req;
689
690 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200691 req.cluster_low = 0;
692 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200693 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200694
695 if (master_pref)
696 req.master_pref = strtoul(master_pref, NULL, 0);
697
698 if (rand_fac) {
699 int rand_fac_val = strtoul(rand_fac, NULL, 0);
700
701 req.config_random_factor_force = 1;
702 req.random_factor_force_val = rand_fac_val;
703 }
704
705 if (hop_count) {
706 int hop_count_val = strtoul(hop_count, NULL, 0);
707
708 req.config_hop_count_force = 1;
709 req.hop_count_force_val = hop_count_val;
710 }
711
Rakesh Sunki107356c2017-03-30 14:47:55 -0700712 ret = nan_enable_request(0, global_interface_handle, &req);
713 if (ret != WIFI_SUCCESS) {
714 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
715 return 0;
716 }
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700717
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200718 abstime.tv_sec = 4;
719 abstime.tv_nsec = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200720 wait(abstime);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700721
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200722 return 0;
723}
724
725
726static int nan_further_availability_tx(struct sigma_dut *dut,
727 struct sigma_conn *conn,
728 struct sigma_cmd *cmd)
729{
730 const char *master_pref = get_param(cmd, "MasterPref");
731 const char *rand_fac = get_param(cmd, "RandFactor");
732 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700733 wifi_error ret;
734
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200735 NanEnableRequest req;
736 NanConfigRequest configReq;
737
738 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200739 req.cluster_low = 0;
740 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200741 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200742
743 if (master_pref)
744 req.master_pref = strtoul(master_pref, NULL, 0);
745
746 if (rand_fac) {
747 int rand_fac_val = strtoul(rand_fac, NULL, 0);
748
749 req.config_random_factor_force = 1;
750 req.random_factor_force_val = rand_fac_val;
751 }
752
753 if (hop_count) {
754 int hop_count_val = strtoul(hop_count, NULL, 0);
755
756 req.config_hop_count_force = 1;
757 req.hop_count_force_val = hop_count_val;
758 }
759
Rakesh Sunki107356c2017-03-30 14:47:55 -0700760 ret = nan_enable_request(0, global_interface_handle, &req);
761 if (ret != WIFI_SUCCESS) {
762 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
763 return 0;
764 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200765
766 /* Start the config of fam */
767
768 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200769
770 configReq.config_fam = 1;
771 configReq.fam_val.numchans = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700772 configReq.fam_val.famchan[0].entry_control = 0;
773 configReq.fam_val.famchan[0].class_val = 81;
774 configReq.fam_val.famchan[0].channel = 6;
775 configReq.fam_val.famchan[0].mapid = 0;
776 configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe;
777
Rakesh Sunki107356c2017-03-30 14:47:55 -0700778 ret = nan_config_request(0, global_interface_handle, &configReq);
779 if (ret != WIFI_SUCCESS)
780 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200781
782 return 0;
783}
784
785
786int sigma_nan_transmit_followup(struct sigma_dut *dut,
787 struct sigma_conn *conn,
788 struct sigma_cmd *cmd)
789{
790 const char *mac = get_param(cmd, "mac");
791 const char *requestor_id = get_param(cmd, "RemoteInstanceId");
792 const char *local_id = get_param(cmd, "LocalInstanceId");
793 const char *service_name = get_param(cmd, "servicename");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700794 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200795 NanTransmitFollowupRequest req;
796
797 memset(&req, 0, sizeof(NanTransmitFollowupRequest));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700798 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200799 req.addr[0] = 0xFF;
800 req.addr[1] = 0xFF;
801 req.addr[2] = 0xFF;
802 req.addr[3] = 0xFF;
803 req.addr[4] = 0xFF;
804 req.addr[5] = 0xFF;
805 req.priority = NAN_TX_PRIORITY_NORMAL;
806 req.dw_or_faw = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700807
808 if (service_name)
809 req.service_specific_info_len = strlen(service_name);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200810
811 if (requestor_id) {
812 /* int requestor_id_val = atoi(requestor_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700813 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200814 }
815 if (local_id) {
816 /* int local_id_val = atoi(local_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700817 req.publish_subscribe_id = global_header_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200818 }
819
820 if (mac == NULL) {
821 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address");
822 return -1;
823 }
824 nan_parse_mac_address(dut, mac, req.addr);
825
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200826 if (requestor_id)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700827 req.requestor_instance_id = strtoul(requestor_id, NULL, 0);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200828
Rakesh Sunki107356c2017-03-30 14:47:55 -0700829 ret = nan_transmit_followup_request(0, global_interface_handle, &req);
830 if (ret != WIFI_SUCCESS) {
831 send_resp(dut, conn, SIGMA_ERROR,
832 "Unable to complete nan transmit followup");
833 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700834
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200835 return 0;
836}
837
Rakesh Sunki107356c2017-03-30 14:47:55 -0700838
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200839/* NotifyResponse invoked to notify the status of the Request */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700840void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200841{
842 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700843 "%s: status %d value %d response_type %d",
844 __func__,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200845 rsp_data->status, rsp_data->value,
846 rsp_data->response_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200847 if (rsp_data->response_type == NAN_RESPONSE_STATS) {
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700848 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: stats_type %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200849 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700850 rsp_data->body.stats_response.stats_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200851 }
852#if 0
853 if (rsp_data->response_type == NAN_RESPONSE_CONFIG &&
854 rsp_data->status == 0)
855 pthread_cond_signal(&gCondition);
856#endif
857}
858
859
860/* Events Callback */
861void nan_event_publish_replied(NanPublishRepliedInd *event)
862{
863 sigma_dut_print(global_dut, DUT_MSG_INFO,
864 "%s: handle %d " MAC_ADDR_STR " rssi:%d",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700865 __func__, event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200866 MAC_ADDR_ARRAY(event->addr), event->rssi_value);
867 event_anyresponse = 1;
868 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700869 "EventName,Replied,RemoteInstanceID %d,mac," MAC_ADDR_STR,
870 (event->requestor_instance_id >> 24),
871 MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200872}
873
874
875/* Events Callback */
876void nan_event_publish_terminated(NanPublishTerminatedInd *event)
877{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700878 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d",
879 __func__, event->publish_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200880}
881
882
883/* Events Callback */
884void nan_event_match(NanMatchInd *event)
885{
886 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700887 "%s: Pub/Sub Id %d remote_requestor_id %08x "
888 MAC_ADDR_STR
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200889 " rssi:%d",
890 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700891 event->publish_subscribe_id,
892 event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200893 MAC_ADDR_ARRAY(event->addr),
894 event->rssi_value);
895 event_anyresponse = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700896 global_header_handle = event->publish_subscribe_id;
897 global_match_handle = event->requestor_instance_id;
898
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200899 /* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */
900 /* global_pub_sub_handle = event->header.handle; */
901 /* Print the SSI */
902 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700903 nan_hex_dump(global_dut, event->service_specific_info,
904 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200905 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
906 "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700907 MAC_ADDR_STR " ", (event->requestor_instance_id >> 24),
908 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200909
910 /* Print the match filter */
911 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700912 nan_hex_dump(global_dut, event->sdf_match_filter,
913 event->sdf_match_filter_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200914
915 /* Print the conn_capability */
916 sigma_dut_print(global_dut, DUT_MSG_INFO,
917 "Printing PostConnectivity Capability");
918 if (event->is_conn_capability_valid) {
919 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s",
920 event->conn_capability.is_wfd_supported ?
921 "yes" : "no");
922 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s",
923 (event->conn_capability.is_wfds_supported ?
924 "yes" : "no"));
925 sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s",
926 (event->conn_capability.is_tdls_supported ?
927 "yes" : "no"));
928 sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s",
929 (event->conn_capability.is_ibss_supported ?
930 "yes" : "no"));
931 sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s",
932 (event->conn_capability.is_mesh_supported ?
933 "yes" : "no"));
934 sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d",
935 event->conn_capability.wlan_infra_field);
936 } else {
937 sigma_dut_print(global_dut, DUT_MSG_INFO,
938 "PostConnectivity Capability not present");
939 }
940
941 /* Print the discovery_attr */
942 sigma_dut_print(global_dut, DUT_MSG_INFO,
943 "Printing PostDiscovery Attribute");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700944 if (event->num_rx_discovery_attr) {
945 int idx;
946
947 for (idx = 0; idx < event->num_rx_discovery_attr; idx++) {
948 sigma_dut_print(global_dut, DUT_MSG_INFO,
949 "PostDiscovery Attribute - %d", idx);
950 sigma_dut_print(global_dut, DUT_MSG_INFO,
951 "Conn Type:%d Device Role:%d"
952 MAC_ADDR_STR,
953 event->discovery_attr[idx].type,
954 event->discovery_attr[idx].role,
955 MAC_ADDR_ARRAY(event->discovery_attr[idx].addr));
956 sigma_dut_print(global_dut, DUT_MSG_INFO,
957 "Duration:%d MapId:%d "
958 "avail_interval_bitmap:%04x",
959 event->discovery_attr[idx].duration,
960 event->discovery_attr[idx].mapid,
961 event->discovery_attr[idx].avail_interval_bitmap);
962 sigma_dut_print(global_dut, DUT_MSG_INFO,
963 "Printing Mesh Id:");
964 nan_hex_dump(global_dut,
965 event->discovery_attr[idx].mesh_id,
966 event->discovery_attr[idx].mesh_id_len);
967 sigma_dut_print(global_dut, DUT_MSG_INFO,
968 "Printing Infrastructure Ssid:");
969 nan_hex_dump(global_dut,
970 event->discovery_attr[idx].infrastructure_ssid_val,
971 event->discovery_attr[idx].infrastructure_ssid_len);
972 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200973 } else {
974 sigma_dut_print(global_dut, DUT_MSG_INFO,
975 "PostDiscovery attribute not present");
976 }
977
978 /* Print the fam */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700979 if (event->num_chans) {
980 nan_print_further_availability_chan(global_dut,
981 event->num_chans,
982 &event->famchan[0]);
983 } else {
984 sigma_dut_print(global_dut, DUT_MSG_INFO,
985 "Further Availability Map not present");
986 }
987 if (event->cluster_attribute_len) {
988 sigma_dut_print(global_dut, DUT_MSG_INFO,
989 "Printing Cluster Attribute:");
990 nan_hex_dump(global_dut, event->cluster_attribute,
991 event->cluster_attribute_len);
992 } else {
993 sigma_dut_print(global_dut, DUT_MSG_INFO,
994 "Cluster Attribute not present");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200995 }
996}
997
998
999/* Events Callback */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001000void nan_event_match_expired(NanMatchExpiredInd *event)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001001{
1002 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001003 "%s: publish_subscribe_id %d match_handle %08x",
1004 __func__, event->publish_subscribe_id,
1005 event->requestor_instance_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001006}
1007
1008
1009/* Events Callback */
1010void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event)
1011{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001012 sigma_dut_print(global_dut, DUT_MSG_INFO,
1013 "%s: Subscribe Id %d reason %d",
1014 __func__, event->subscribe_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001015}
1016
1017
1018/* Events Callback */
1019void nan_event_followup(NanFollowupInd *event)
1020{
1021 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001022 "%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d "
1023 MAC_ADDR_STR, __func__, event->publish_subscribe_id,
1024 event->requestor_instance_id, event->dw_or_faw,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001025 MAC_ADDR_ARRAY(event->addr));
1026
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001027 global_match_handle = event->publish_subscribe_id;
1028 global_header_handle = event->requestor_instance_id;
1029 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__);
1030 nan_hex_dump(global_dut, event->service_specific_info,
1031 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001032 event_anyresponse = 1;
1033 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1034 "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001035 MAC_ADDR_STR " ", event->requestor_instance_id >> 24,
1036 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001037}
1038
1039
1040/* Events Callback */
1041void nan_event_disceng_event(NanDiscEngEventInd *event)
1042{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001043 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d",
1044 __func__, event->event_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001045
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001046 if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001047 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster "
1048 MAC_ADDR_STR,
1049 __func__,
1050 MAC_ADDR_ARRAY(event->data.cluster.addr));
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001051 /* To ensure sta_get_events to get the events
1052 * only after joining the NAN cluster. */
1053 pthread_cond_signal(&gCondition);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001054 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001055 if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001056 sigma_dut_print(global_dut, DUT_MSG_INFO,
1057 "%s: Started cluster " MAC_ADDR_STR,
1058 __func__,
1059 MAC_ADDR_ARRAY(event->data.cluster.addr));
1060 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001061 if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) {
1062 sigma_dut_print(global_dut, DUT_MSG_INFO,
1063 "%s: Discovery Mac Address "
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001064 MAC_ADDR_STR,
1065 __func__,
1066 MAC_ADDR_ARRAY(event->data.mac_addr.addr));
1067 memcpy(global_nan_mac_addr, event->data.mac_addr.addr,
1068 sizeof(global_nan_mac_addr));
1069 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001070}
1071
1072
1073/* Events Callback */
1074void nan_event_disabled(NanDisabledInd *event)
1075{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001076 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d",
1077 __func__, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001078 /* pthread_cond_signal(&gCondition); */
1079}
1080
1081
Rakesh Sunki4c086672017-03-30 14:47:55 -07001082/* Events callback */
1083static void ndp_event_data_indication(NanDataPathRequestInd *event)
1084{
1085 sigma_dut_print(global_dut, DUT_MSG_INFO,
1086 "%s: Service Instance Id: %d Peer Discovery MAC ADDR "
1087 MAC_ADDR_STR
1088 " NDP Instance Id: %d App Info len %d App Info %s",
1089 __func__,
1090 event->service_instance_id,
1091 MAC_ADDR_ARRAY(event->peer_disc_mac_addr),
1092 event->ndp_instance_id,
1093 event->app_info.ndp_app_info_len,
1094 event->app_info.ndp_app_info);
1095
1096 global_ndp_instance_id = event->ndp_instance_id;
1097}
1098
1099
1100/* Events callback */
1101static void ndp_event_data_confirm(NanDataPathConfirmInd *event)
1102{
1103 sigma_dut_print(global_dut, DUT_MSG_INFO,
1104 "Received NDP Confirm Indication");
1105
1106 global_ndp_instance_id = event->ndp_instance_id;
1107 if (system("ifconfig nan0 up") != 0) {
1108 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1109 "Failed to set nan interface up");
1110 return;
1111 }
1112 if (system("ip -6 route add fe80::/64 dev nan0 table local") != 0) {
1113 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1114 "Failed to run:ip -6 route replace fe80::/64 dev nan0 table local");
1115 return;
1116 }
1117}
1118
1119
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001120void * my_thread_function(void *ptr)
1121{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001122 wifi_event_loop(global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001123 pthread_exit(0);
1124 return (void *) NULL;
1125}
1126
1127
1128static NanCallbackHandler callbackHandler = {
1129 .NotifyResponse = nan_notify_response,
1130 .EventPublishReplied = nan_event_publish_replied,
1131 .EventPublishTerminated = nan_event_publish_terminated,
1132 .EventMatch = nan_event_match,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001133 .EventMatchExpired = nan_event_match_expired,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001134 .EventSubscribeTerminated = nan_event_subscribe_terminated,
1135 .EventFollowup = nan_event_followup,
1136 .EventDiscEngEvent = nan_event_disceng_event,
1137 .EventDisabled = nan_event_disabled,
Rakesh Sunki4c086672017-03-30 14:47:55 -07001138 .EventDataRequest = ndp_event_data_indication,
1139 .EventDataConfirm = ndp_event_data_confirm,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001140};
1141
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001142
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001143void nan_init(struct sigma_dut *dut)
1144{
1145 pthread_t thread1; /* thread variables */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001146 wifi_error err = wifi_initialize(&global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001147
1148 if (err) {
1149 printf("wifi hal initialize failed\n");
1150 return;
1151 }
1152
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001153 global_interface_handle = wifi_get_iface_handle(global_wifi_handle,
1154 (char *) "wlan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001155 /* create threads 1 */
1156 pthread_create(&thread1, NULL, &my_thread_function, NULL);
1157
1158 pthread_mutex_init(&gMutex, NULL);
1159 pthread_cond_init(&gCondition, NULL);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001160 if (global_interface_handle)
1161 nan_register_handler(global_interface_handle, callbackHandler);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001162}
1163
1164
1165void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1166 struct sigma_cmd *cmd)
1167{
1168 sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default");
1169
1170 if (nan_state == 0) {
1171 nan_init(dut);
1172 nan_state = 1;
1173 }
1174 is_fam = 0;
1175 event_anyresponse = 0;
1176 global_dut = dut;
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001177 dut->sta_channel = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001178 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001179
1180 nan_data_interface_delete(0, global_interface_handle, (char *) "nan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001181 sigma_nan_disable(dut, conn, cmd);
1182}
1183
1184
1185int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1186 struct sigma_cmd *cmd)
1187{
1188 const char *program = get_param(cmd, "Prog");
1189 const char *nan_op = get_param(cmd, "NANOp");
1190 const char *method_type = get_param(cmd, "MethodType");
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001191 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001192 char resp_buf[100];
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001193 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001194
1195 if (program == NULL)
1196 return -1;
1197
1198 if (strcasecmp(program, "NAN") != 0) {
1199 send_resp(dut, conn, SIGMA_ERROR,
1200 "ErrorCode,Unsupported program");
1201 return 0;
1202 }
1203
1204 if (nan_op) {
1205 /*
1206 * NANOp has been specified.
1207 * We will build a nan_enable or nan_disable command.
1208 */
1209 if (strcasecmp(nan_op, "On") == 0) {
1210 if (sigma_nan_enable(dut, conn, cmd) == 0) {
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001211 ret = nan_data_interface_create(
1212 0, global_interface_handle,
1213 (char *) "nan0");
1214 if (ret != WIFI_SUCCESS) {
1215 sigma_dut_print(
1216 global_dut, DUT_MSG_ERROR,
1217 "Unable to create NAN data interface");
1218 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001219 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1220 MAC_ADDR_STR,
1221 MAC_ADDR_ARRAY(global_nan_mac_addr));
1222 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1223 } else {
1224 send_resp(dut, conn, SIGMA_ERROR,
1225 "NAN_ENABLE_FAILED");
1226 return -1;
1227 }
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001228
1229 if (band && strcasecmp(band, "24g") == 0) {
1230 sigma_dut_print(dut, DUT_MSG_INFO,
1231 "%s: Setting band to 2G Only",
1232 __func__);
1233 sigma_ndp_configure_band(
1234 dut, conn, cmd,
1235 NAN_DATA_PATH_SUPPORTED_BAND_2G);
1236 } else if (band && dut->sta_channel > 12) {
1237 sigma_ndp_configure_band(
1238 dut, conn, cmd,
1239 NAN_DATA_PATH_SUPPORT_DUAL_BAND);
1240 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001241 } else if (strcasecmp(nan_op, "Off") == 0) {
1242 sigma_nan_disable(dut, conn, cmd);
1243 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1244 }
1245 }
1246 if (nan_state && nan_op == NULL) {
1247 if (method_type) {
1248 if (strcasecmp(method_type, "Publish") == 0) {
1249 sigma_nan_publish_request(dut, conn, cmd);
1250 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1251 }
1252 if (strcasecmp(method_type, "Subscribe") == 0) {
1253 sigma_nan_subscribe_request(dut, conn, cmd);
1254 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1255 }
1256 if (strcasecmp(method_type, "Followup") == 0) {
1257 sigma_nan_transmit_followup(dut, conn, cmd);
1258 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1259 }
1260 } else {
1261 sigma_nan_config_enable(dut, conn, cmd);
1262 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1263 MAC_ADDR_STR,
1264 MAC_ADDR_ARRAY(global_nan_mac_addr));
1265 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1266 }
1267 }
1268
1269 return 0;
1270}
1271
1272
1273int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1274 struct sigma_cmd *cmd)
1275{
1276
1277 const char *program = get_param(cmd, "Program");
1278 const char *parameter = get_param(cmd, "Parameter");
1279 char resp_buf[100];
1280 NanStaParameter rsp;
1281
1282 if (program == NULL) {
1283 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name");
1284 return -1;
1285 }
1286 if (strcasecmp(program, "NAN") != 0) {
1287 send_resp(dut, conn, SIGMA_ERROR,
1288 "ErrorCode,Unsupported program");
1289 return 0;
1290 }
1291
1292 if (parameter == NULL) {
1293 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter");
1294 return -1;
1295 }
1296 memset(&rsp, 0, sizeof(NanStaParameter));
1297
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001298 nan_get_sta_parameter(0, global_interface_handle, &rsp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001299 sigma_dut_print(dut, DUT_MSG_INFO,
1300 "%s: NanStaparameter Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d",
1301 __func__, rsp.master_pref, rsp.random_factor,
1302 rsp.hop_count, rsp.beacon_transmit_time);
1303
1304 if (strcasecmp(parameter, "MasterPref") == 0) {
1305 snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x",
1306 rsp.master_pref);
1307 } else if (strcasecmp(parameter, "MasterRank") == 0) {
1308 snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx",
1309 rsp.master_rank);
1310 } else if (strcasecmp(parameter, "RandFactor") == 0) {
1311 snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x",
1312 rsp.random_factor);
1313 } else if (strcasecmp(parameter, "HopCount") == 0) {
1314 snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x",
1315 rsp.hop_count);
1316 } else if (strcasecmp(parameter, "BeaconTransTime") == 0) {
1317 snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x",
1318 rsp.beacon_transmit_time);
1319 } else if (strcasecmp(parameter, "NANStatus") == 0) {
1320 if (nan_state == 1)
1321 snprintf(resp_buf, sizeof(resp_buf), "On");
1322 else
1323 snprintf(resp_buf, sizeof(resp_buf), "Off");
1324 } else {
1325 send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
1326 return 0;
1327 }
1328
1329 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1330 return 0;
1331}
1332
1333
1334int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1335 struct sigma_cmd *cmd)
1336{
1337 const char *action = get_param(cmd, "Action");
1338
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001339 if (!action)
1340 return 0;
1341
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001342 /* Check action for start, stop and get events. */
1343 if (strcasecmp(action, "Start") == 0) {
1344 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1345 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1346 } else if (strcasecmp(action, "Stop") == 0) {
1347 event_anyresponse = 0;
1348 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1349 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1350 } else if (strcasecmp(action, "Get") == 0) {
1351 if (event_anyresponse == 1) {
1352 send_resp(dut, conn, SIGMA_COMPLETE,
1353 global_event_resp_buf);
1354 } else {
1355 send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE");
1356 }
1357 }
1358 return 0;
1359}
Rakesh Sunki4b75f962017-03-30 14:47:55 -07001360
1361#else /* #if NAN_CERT_VERSION */
1362
1363int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
1364 struct sigma_conn *conn,
1365 struct sigma_cmd *cmd)
1366{
1367 return 1;
1368}
1369
1370
1371int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1372 struct sigma_cmd *cmd)
1373{
1374 return 0;
1375
1376}
1377
1378
1379void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1380 struct sigma_cmd *cmd)
1381{
1382 return;
1383}
1384
1385
1386int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1387 struct sigma_cmd *cmd)
1388{
1389 return 0;
1390}
1391
1392
1393int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1394 struct sigma_cmd *cmd)
1395{
1396 return 0;
1397}
1398
1399#endif /* #if NAN_CERT_VERSION */