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