blob: b063718742881c54270c8f926708d40f7c9d5ae0 [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{
193 const char *oper_chan = get_param(cmd, "oper_chan");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200194
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700195 if (oper_chan)
196 dut->sta_channel = atoi(oper_chan);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200197
198 return 0;
199}
200
201
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700202void nan_print_further_availability_chan(struct sigma_dut *dut,
203 u8 num_chans,
204 NanFurtherAvailabilityChannel *fachan)
205{
206 int idx;
207
208 sigma_dut_print(dut, DUT_MSG_INFO,
209 "********Printing FurtherAvailabilityChan Info******");
210 sigma_dut_print(dut, DUT_MSG_INFO, "Numchans:%d", num_chans);
211 for (idx = 0; idx < num_chans; idx++) {
212 sigma_dut_print(dut, DUT_MSG_INFO,
213 "[%d]: NanAvailDuration:%d class_val:%02x channel:%d",
214 idx, fachan->entry_control,
215 fachan->class_val, fachan->channel);
216 sigma_dut_print(dut, DUT_MSG_INFO,
217 "[%d]: mapid:%d Availability bitmap:%08x",
218 idx, fachan->mapid,
219 fachan->avail_interval_bitmap);
220 }
221 sigma_dut_print(dut, DUT_MSG_INFO,
222 "*********************Done**********************");
223}
224
225
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200226int sigma_nan_enable(struct sigma_dut *dut, struct sigma_conn *conn,
227 struct sigma_cmd *cmd)
228{
229 const char *master_pref = get_param(cmd, "MasterPref");
230 const char *rand_fac = get_param(cmd, "RandFactor");
231 const char *hop_count = get_param(cmd, "HopCount");
232 const char *high_tsf = get_param(cmd, "HighTSF");
233 const char *sdftx_band = get_param(cmd, "SDFTxBand");
234 const char *oper_chan = get_param(cmd, "oper_chn");
235 const char *further_avail_ind = get_param(cmd, "FurtherAvailInd");
236 const char *band = get_param(cmd, "Band");
237 const char *only_5g = get_param(cmd, "5GOnly");
238 struct timespec abstime;
239 NanEnableRequest req;
240
241 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200242 req.cluster_low = 0;
243 req.cluster_high = 0xFFFF;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700244 req.master_pref = 100;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200245
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700246 /* This is a debug hack to beacon in channel 11 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200247 if (oper_chan) {
248 req.config_2dot4g_support = 1;
249 req.support_2dot4g_val = 111;
250 }
251
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200252 if (master_pref) {
253 int master_pref_val = strtoul(master_pref, NULL, 0);
254
255 req.master_pref = master_pref_val;
256 }
257
258 if (rand_fac) {
259 int rand_fac_val = strtoul(rand_fac, NULL, 0);
260
261 req.config_random_factor_force = 1;
262 req.random_factor_force_val = rand_fac_val;
263 }
264
265 if (hop_count) {
266 int hop_count_val = strtoul(hop_count, NULL, 0);
267
268 req.config_hop_count_force = 1;
269 req.hop_count_force_val = hop_count_val;
270 }
271
272 if (sdftx_band) {
273 if (strcasecmp(sdftx_band, "5G") == 0) {
274 req.config_2dot4g_support = 1;
275 req.support_2dot4g_val = 0;
276 }
277 }
278
279 if (band) {
280 if (strcasecmp(band, "24G") == 0) {
281 sigma_dut_print(dut, DUT_MSG_INFO,
282 "Band 2.4GHz selected");
283 /* Enable 2.4G support */
284 req.config_2dot4g_support = 1;
285 req.support_2dot4g_val = 1;
286 req.config_2dot4g_beacons = 1;
287 req.beacon_2dot4g_val = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700288 req.config_2dot4g_sdf = 1;
289 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200290
291 /* Disable 5G support */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700292 req.config_support_5g = 1;
293 req.support_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200294 req.config_5g_beacons = 1;
295 req.beacon_5g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700296 req.config_5g_sdf = 1;
297 req.sdf_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200298 }
299 }
300
301 if (further_avail_ind) {
302 sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled");
303 if (strcasecmp(further_avail_ind, "tx") == 0) {
304 is_fam = 1;
305 nan_further_availability_tx(dut, conn, cmd);
306 return 0;
307 } else if (strcasecmp(further_avail_ind, "rx") == 0) {
308 nan_further_availability_rx(dut, conn, cmd);
309 return 0;
310 }
311 }
312
313 if (only_5g && atoi(only_5g)) {
314 sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled");
315 req.config_2dot4g_support = 1;
316 req.support_2dot4g_val = 1;
317 req.config_2dot4g_beacons = 1;
318 req.beacon_2dot4g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700319 req.config_2dot4g_sdf = 1;
320 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200321 }
322
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700323 nan_enable_request(0, global_interface_handle, &req);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700324
325 /* To ensure sta_get_events to get the events
326 * only after joining the NAN cluster. */
327 abstime.tv_sec = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200328 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700329 wait(abstime);
330
331 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200332}
333
334
335int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn,
336 struct sigma_cmd *cmd)
337{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200338 struct timespec abstime;
339
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700340 nan_disable_request(0, global_interface_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200341
342 abstime.tv_sec = 4;
343 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700344 wait(abstime);
345
346 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200347}
348
349
350int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn,
351 struct sigma_cmd *cmd)
352{
353 const char *master_pref = get_param(cmd, "MasterPref");
354 const char *rand_fac = get_param(cmd, "RandFactor");
355 const char *hop_count = get_param(cmd, "HopCount");
356 struct timespec abstime;
357 NanConfigRequest req;
358
359 memset(&req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200360 req.config_rssi_proximity = 1;
361 req.rssi_proximity = 70;
362
363 if (master_pref) {
364 int master_pref_val = strtoul(master_pref, NULL, 0);
365
366 req.config_master_pref = 1;
367 req.master_pref = master_pref_val;
368 }
369
370 if (rand_fac) {
371 int rand_fac_val = strtoul(rand_fac, NULL, 0);
372
373 req.config_random_factor_force = 1;
374 req.random_factor_force_val = rand_fac_val;
375 }
376
377 if (hop_count) {
378 int hop_count_val = strtoul(hop_count, NULL, 0);
379
380 req.config_hop_count_force = 1;
381 req.hop_count_force_val = hop_count_val;
382 }
383
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700384 nan_config_request(0, global_interface_handle, &req);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200385
386 abstime.tv_sec = 4;
387 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700388 wait(abstime);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200389
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700390 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200391}
392
393
394static int sigma_nan_subscribe_request(struct sigma_dut *dut,
395 struct sigma_conn *conn,
396 struct sigma_cmd *cmd)
397{
398 const char *subscribe_type = get_param(cmd, "SubscribeType");
399 const char *service_name = get_param(cmd, "ServiceName");
400 const char *disc_range = get_param(cmd, "DiscoveryRange");
401 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
402 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
403 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
404 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
405 const char *include_bit = get_param(cmd, "IncludeBit");
406 const char *mac = get_param(cmd, "MAC");
407 const char *srf_type = get_param(cmd, "SRFType");
408 NanSubscribeRequest req;
409 int filter_len_rx = 0, filter_len_tx = 0;
410 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
411 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
412
413 memset(&req, 0, sizeof(NanSubscribeRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200414 req.ttl = 0;
415 req.period = 1000;
416 req.subscribe_type = 1;
417 req.serviceResponseFilter = 1; /* MAC */
418 req.serviceResponseInclude = 0;
419 req.ssiRequiredForMatchIndication = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700420 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200421 req.subscribe_count = 0;
422
423 if (subscribe_type) {
424 if (strcasecmp(subscribe_type, "Active") == 0) {
425 req.subscribe_type = 1;
426 } else if (strcasecmp(subscribe_type, "Passive") == 0) {
427 req.subscribe_type = 0;
428 } else if (strcasecmp(subscribe_type, "Cancel") == 0) {
429 NanSubscribeCancelRequest req;
430
431 memset(&req, 0, sizeof(NanSubscribeCancelRequest));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700432 nan_subscribe_cancel_request(0, global_interface_handle,
433 &req);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200434 return 0;
435 }
436 }
437
438 if (disc_range)
439 req.rssi_threshold_flag = atoi(disc_range);
440
441 if (sdftx_dw)
442 req.subscribe_count = atoi(sdftx_dw);
443
444 /* Check this once again if config can be called here (TBD) */
445 if (discrange_ltd)
446 req.rssi_threshold_flag = atoi(discrange_ltd);
447
448 if (include_bit) {
449 int include_bit_val = atoi(include_bit);
450
451 req.serviceResponseInclude = include_bit_val;
452 sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d",
453 req.serviceResponseInclude);
454 }
455
456 if (srf_type) {
457 int srf_type_val = atoi(srf_type);
458
459 if (srf_type_val == 1)
460 req.serviceResponseFilter = 0; /* Bloom */
461 else
462 req.serviceResponseFilter = 1; /* MAC */
463 req.useServiceResponseFilter = 1;
464 sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d",
465 req.serviceResponseFilter);
466 }
467
468 if (mac) {
469 sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac);
470 req.num_intf_addr_present = nan_parse_mac_address_list(
471 dut, mac, &req.intf_addr[0][0],
472 NAN_MAX_SUBSCRIBE_MAX_ADDRESS);
473 }
474
475 memset(input_rx, 0, sizeof(input_rx));
476 memset(input_tx, 0, sizeof(input_tx));
477 if (rx_match_filter) {
478 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
479 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
480 filter_len_rx);
481 }
482 if (tx_match_filter) {
483 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
484 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
485 filter_len_tx);
486 }
487
488 if (tx_match_filter) {
489 req.tx_match_filter_len = filter_len_tx;
490 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
491 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
492 }
493 if (rx_match_filter) {
494 req.rx_match_filter_len = filter_len_rx;
495 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
496 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
497 }
498
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700499 if (service_name) {
500 strlcpy((char *) req.service_name, service_name,
501 strlen(service_name) + 1);
502 req.service_name_len = strlen(service_name);
503 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200504
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700505 nan_subscribe_request(0, global_interface_handle, &req);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200506 return 0;
507}
508
509
510int config_post_disc_attr(void)
511{
512 NanConfigRequest configReq;
513
514 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200515
516 /* Configure Post disc attr */
517 /* Make these defines and use correct enum */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700518 configReq.num_config_discovery_attr = 1;
519 configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */
520 configReq.discovery_attr_val[0].role = 0;
521 configReq.discovery_attr_val[0].transmit_freq = 1;
522 configReq.discovery_attr_val[0].duration = 0;
523 configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200524
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700525 nan_config_request(0, global_interface_handle, &configReq);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200526 return 0;
527}
528
529
530int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn,
531 struct sigma_cmd *cmd)
532{
533 const char *publish_type = get_param(cmd, "PublishType");
534 const char *service_name = get_param(cmd, "ServiceName");
535 const char *disc_range = get_param(cmd, "DiscoveryRange");
536 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
537 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
538 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
539 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
540 NanPublishRequest req;
541 int filter_len_rx = 0, filter_len_tx = 0;
542 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
543 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
544
545 memset(&req, 0, sizeof(NanPublishRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200546 req.ttl = 0;
547 req.period = 500;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700548 req.publish_match_indicator = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200549 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
550 req.tx_type = NAN_TX_TYPE_BROADCAST;
551 req.publish_count = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700552
553 if (service_name) {
554 strlcpy((char *) req.service_name, service_name,
555 strlen(service_name) + 1);
556 req.service_name_len = strlen(service_name);
557 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200558
559 if (publish_type) {
560 if (strcasecmp(publish_type, "Solicited") == 0) {
561 req.publish_type = NAN_PUBLISH_TYPE_SOLICITED;
562 } else if (strcasecmp(publish_type, "Cancel") == 0) {
563 NanPublishCancelRequest req;
564
565 memset(&req, 0, sizeof(NanPublishCancelRequest));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700566 nan_publish_cancel_request(0, global_interface_handle,
567 &req);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200568 return 0;
569 }
570 }
571
572 if (disc_range)
573 req.rssi_threshold_flag = atoi(disc_range);
574
575 if (sdftx_dw)
576 req.publish_count = atoi(sdftx_dw);
577
578 if (discrange_ltd)
579 req.rssi_threshold_flag = atoi(discrange_ltd);
580
581 memset(input_rx, 0, sizeof(input_rx));
582 memset(input_tx, 0, sizeof(input_tx));
583 if (rx_match_filter) {
584 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
585 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
586 filter_len_rx);
587 }
588 if (tx_match_filter) {
589 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
590 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
591 filter_len_tx);
592 }
593
594 if (is_fam == 1) {
595 config_post_disc_attr();
596 /* TODO: Add comments regarding this step */
597 req.connmap = 0x10;
598 }
599
600 if (tx_match_filter) {
601 req.tx_match_filter_len = filter_len_tx;
602 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
603 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
604 }
605
606 if (rx_match_filter) {
607 req.rx_match_filter_len = filter_len_rx;
608 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
609 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
610 }
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700611
612 if (service_name) {
613 strlcpy((char *) req.service_name, service_name,
614 strlen(service_name) + 1);
615 req.service_name_len = strlen(service_name);
616 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200617
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700618 nan_publish_request(0, global_interface_handle, &req);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200619
620 return 0;
621}
622
623
624static int nan_further_availability_rx(struct sigma_dut *dut,
625 struct sigma_conn *conn,
626 struct sigma_cmd *cmd)
627{
628 const char *master_pref = get_param(cmd, "MasterPref");
629 const char *rand_fac = get_param(cmd, "RandFactor");
630 const char *hop_count = get_param(cmd, "HopCount");
631 struct timespec abstime;
632
633 NanEnableRequest req;
634
635 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200636 req.cluster_low = 0;
637 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200638 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200639
640 if (master_pref)
641 req.master_pref = strtoul(master_pref, NULL, 0);
642
643 if (rand_fac) {
644 int rand_fac_val = strtoul(rand_fac, NULL, 0);
645
646 req.config_random_factor_force = 1;
647 req.random_factor_force_val = rand_fac_val;
648 }
649
650 if (hop_count) {
651 int hop_count_val = strtoul(hop_count, NULL, 0);
652
653 req.config_hop_count_force = 1;
654 req.hop_count_force_val = hop_count_val;
655 }
656
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700657 nan_enable_request(0, global_interface_handle, &req);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700658
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200659 abstime.tv_sec = 4;
660 abstime.tv_nsec = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200661 wait(abstime);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700662
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200663 return 0;
664}
665
666
667static int nan_further_availability_tx(struct sigma_dut *dut,
668 struct sigma_conn *conn,
669 struct sigma_cmd *cmd)
670{
671 const char *master_pref = get_param(cmd, "MasterPref");
672 const char *rand_fac = get_param(cmd, "RandFactor");
673 const char *hop_count = get_param(cmd, "HopCount");
674 NanEnableRequest req;
675 NanConfigRequest configReq;
676
677 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200678 req.cluster_low = 0;
679 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200680 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200681
682 if (master_pref)
683 req.master_pref = strtoul(master_pref, NULL, 0);
684
685 if (rand_fac) {
686 int rand_fac_val = strtoul(rand_fac, NULL, 0);
687
688 req.config_random_factor_force = 1;
689 req.random_factor_force_val = rand_fac_val;
690 }
691
692 if (hop_count) {
693 int hop_count_val = strtoul(hop_count, NULL, 0);
694
695 req.config_hop_count_force = 1;
696 req.hop_count_force_val = hop_count_val;
697 }
698
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700699 nan_enable_request(0, global_interface_handle, &req);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200700
701 /* Start the config of fam */
702
703 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200704
705 configReq.config_fam = 1;
706 configReq.fam_val.numchans = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700707 configReq.fam_val.famchan[0].entry_control = 0;
708 configReq.fam_val.famchan[0].class_val = 81;
709 configReq.fam_val.famchan[0].channel = 6;
710 configReq.fam_val.famchan[0].mapid = 0;
711 configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe;
712
713 nan_config_request(0, global_interface_handle, &configReq);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200714
715 return 0;
716}
717
718
719int sigma_nan_transmit_followup(struct sigma_dut *dut,
720 struct sigma_conn *conn,
721 struct sigma_cmd *cmd)
722{
723 const char *mac = get_param(cmd, "mac");
724 const char *requestor_id = get_param(cmd, "RemoteInstanceId");
725 const char *local_id = get_param(cmd, "LocalInstanceId");
726 const char *service_name = get_param(cmd, "servicename");
727 NanTransmitFollowupRequest req;
728
729 memset(&req, 0, sizeof(NanTransmitFollowupRequest));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700730 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200731 req.addr[0] = 0xFF;
732 req.addr[1] = 0xFF;
733 req.addr[2] = 0xFF;
734 req.addr[3] = 0xFF;
735 req.addr[4] = 0xFF;
736 req.addr[5] = 0xFF;
737 req.priority = NAN_TX_PRIORITY_NORMAL;
738 req.dw_or_faw = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700739
740 if (service_name)
741 req.service_specific_info_len = strlen(service_name);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200742
743 if (requestor_id) {
744 /* int requestor_id_val = atoi(requestor_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700745 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200746 }
747 if (local_id) {
748 /* int local_id_val = atoi(local_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700749 req.publish_subscribe_id = global_header_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200750 }
751
752 if (mac == NULL) {
753 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address");
754 return -1;
755 }
756 nan_parse_mac_address(dut, mac, req.addr);
757
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200758 if (requestor_id)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700759 req.requestor_instance_id = strtoul(requestor_id, NULL, 0);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200760
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700761
762 nan_transmit_followup_request(0, global_interface_handle, &req);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200763 return 0;
764}
765
766/* NotifyResponse invoked to notify the status of the Request */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700767void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200768{
769 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700770 "%s: status %d value %d response_type %d",
771 __func__,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200772 rsp_data->status, rsp_data->value,
773 rsp_data->response_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200774 if (rsp_data->response_type == NAN_RESPONSE_STATS) {
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700775 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: stats_type %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200776 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700777 rsp_data->body.stats_response.stats_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200778 }
779#if 0
780 if (rsp_data->response_type == NAN_RESPONSE_CONFIG &&
781 rsp_data->status == 0)
782 pthread_cond_signal(&gCondition);
783#endif
784}
785
786
787/* Events Callback */
788void nan_event_publish_replied(NanPublishRepliedInd *event)
789{
790 sigma_dut_print(global_dut, DUT_MSG_INFO,
791 "%s: handle %d " MAC_ADDR_STR " rssi:%d",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700792 __func__, event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200793 MAC_ADDR_ARRAY(event->addr), event->rssi_value);
794 event_anyresponse = 1;
795 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700796 "EventName,Replied,RemoteInstanceID %d,mac," MAC_ADDR_STR,
797 (event->requestor_instance_id >> 24),
798 MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200799}
800
801
802/* Events Callback */
803void nan_event_publish_terminated(NanPublishTerminatedInd *event)
804{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700805 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d",
806 __func__, event->publish_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200807}
808
809
810/* Events Callback */
811void nan_event_match(NanMatchInd *event)
812{
813 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700814 "%s: Pub/Sub Id %d remote_requestor_id %08x "
815 MAC_ADDR_STR
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200816 " rssi:%d",
817 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700818 event->publish_subscribe_id,
819 event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200820 MAC_ADDR_ARRAY(event->addr),
821 event->rssi_value);
822 event_anyresponse = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700823 global_header_handle = event->publish_subscribe_id;
824 global_match_handle = event->requestor_instance_id;
825
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200826 /* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */
827 /* global_pub_sub_handle = event->header.handle; */
828 /* Print the SSI */
829 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700830 nan_hex_dump(global_dut, event->service_specific_info,
831 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200832 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
833 "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700834 MAC_ADDR_STR " ", (event->requestor_instance_id >> 24),
835 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200836
837 /* Print the match filter */
838 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700839 nan_hex_dump(global_dut, event->sdf_match_filter,
840 event->sdf_match_filter_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200841
842 /* Print the conn_capability */
843 sigma_dut_print(global_dut, DUT_MSG_INFO,
844 "Printing PostConnectivity Capability");
845 if (event->is_conn_capability_valid) {
846 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s",
847 event->conn_capability.is_wfd_supported ?
848 "yes" : "no");
849 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s",
850 (event->conn_capability.is_wfds_supported ?
851 "yes" : "no"));
852 sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s",
853 (event->conn_capability.is_tdls_supported ?
854 "yes" : "no"));
855 sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s",
856 (event->conn_capability.is_ibss_supported ?
857 "yes" : "no"));
858 sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s",
859 (event->conn_capability.is_mesh_supported ?
860 "yes" : "no"));
861 sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d",
862 event->conn_capability.wlan_infra_field);
863 } else {
864 sigma_dut_print(global_dut, DUT_MSG_INFO,
865 "PostConnectivity Capability not present");
866 }
867
868 /* Print the discovery_attr */
869 sigma_dut_print(global_dut, DUT_MSG_INFO,
870 "Printing PostDiscovery Attribute");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700871 if (event->num_rx_discovery_attr) {
872 int idx;
873
874 for (idx = 0; idx < event->num_rx_discovery_attr; idx++) {
875 sigma_dut_print(global_dut, DUT_MSG_INFO,
876 "PostDiscovery Attribute - %d", idx);
877 sigma_dut_print(global_dut, DUT_MSG_INFO,
878 "Conn Type:%d Device Role:%d"
879 MAC_ADDR_STR,
880 event->discovery_attr[idx].type,
881 event->discovery_attr[idx].role,
882 MAC_ADDR_ARRAY(event->discovery_attr[idx].addr));
883 sigma_dut_print(global_dut, DUT_MSG_INFO,
884 "Duration:%d MapId:%d "
885 "avail_interval_bitmap:%04x",
886 event->discovery_attr[idx].duration,
887 event->discovery_attr[idx].mapid,
888 event->discovery_attr[idx].avail_interval_bitmap);
889 sigma_dut_print(global_dut, DUT_MSG_INFO,
890 "Printing Mesh Id:");
891 nan_hex_dump(global_dut,
892 event->discovery_attr[idx].mesh_id,
893 event->discovery_attr[idx].mesh_id_len);
894 sigma_dut_print(global_dut, DUT_MSG_INFO,
895 "Printing Infrastructure Ssid:");
896 nan_hex_dump(global_dut,
897 event->discovery_attr[idx].infrastructure_ssid_val,
898 event->discovery_attr[idx].infrastructure_ssid_len);
899 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200900 } else {
901 sigma_dut_print(global_dut, DUT_MSG_INFO,
902 "PostDiscovery attribute not present");
903 }
904
905 /* Print the fam */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700906 if (event->num_chans) {
907 nan_print_further_availability_chan(global_dut,
908 event->num_chans,
909 &event->famchan[0]);
910 } else {
911 sigma_dut_print(global_dut, DUT_MSG_INFO,
912 "Further Availability Map not present");
913 }
914 if (event->cluster_attribute_len) {
915 sigma_dut_print(global_dut, DUT_MSG_INFO,
916 "Printing Cluster Attribute:");
917 nan_hex_dump(global_dut, event->cluster_attribute,
918 event->cluster_attribute_len);
919 } else {
920 sigma_dut_print(global_dut, DUT_MSG_INFO,
921 "Cluster Attribute not present");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200922 }
923}
924
925
926/* Events Callback */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700927void nan_event_match_expired(NanMatchExpiredInd *event)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200928{
929 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700930 "%s: publish_subscribe_id %d match_handle %08x",
931 __func__, event->publish_subscribe_id,
932 event->requestor_instance_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200933}
934
935
936/* Events Callback */
937void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event)
938{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700939 sigma_dut_print(global_dut, DUT_MSG_INFO,
940 "%s: Subscribe Id %d reason %d",
941 __func__, event->subscribe_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200942}
943
944
945/* Events Callback */
946void nan_event_followup(NanFollowupInd *event)
947{
948 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700949 "%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d "
950 MAC_ADDR_STR, __func__, event->publish_subscribe_id,
951 event->requestor_instance_id, event->dw_or_faw,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200952 MAC_ADDR_ARRAY(event->addr));
953
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700954 global_match_handle = event->publish_subscribe_id;
955 global_header_handle = event->requestor_instance_id;
956 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__);
957 nan_hex_dump(global_dut, event->service_specific_info,
958 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200959 event_anyresponse = 1;
960 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
961 "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700962 MAC_ADDR_STR " ", event->requestor_instance_id >> 24,
963 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200964}
965
966
967/* Events Callback */
968void nan_event_disceng_event(NanDiscEngEventInd *event)
969{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700970 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d",
971 __func__, event->event_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200972
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700973 if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200974 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster "
975 MAC_ADDR_STR,
976 __func__,
977 MAC_ADDR_ARRAY(event->data.cluster.addr));
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700978 /* To ensure sta_get_events to get the events
979 * only after joining the NAN cluster. */
980 pthread_cond_signal(&gCondition);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200981 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700982 if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200983 sigma_dut_print(global_dut, DUT_MSG_INFO,
984 "%s: Started cluster " MAC_ADDR_STR,
985 __func__,
986 MAC_ADDR_ARRAY(event->data.cluster.addr));
987 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700988 if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) {
989 sigma_dut_print(global_dut, DUT_MSG_INFO,
990 "%s: Discovery Mac Address "
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200991 MAC_ADDR_STR,
992 __func__,
993 MAC_ADDR_ARRAY(event->data.mac_addr.addr));
994 memcpy(global_nan_mac_addr, event->data.mac_addr.addr,
995 sizeof(global_nan_mac_addr));
996 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200997}
998
999
1000/* Events Callback */
1001void nan_event_disabled(NanDisabledInd *event)
1002{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001003 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d",
1004 __func__, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001005 /* pthread_cond_signal(&gCondition); */
1006}
1007
1008
Rakesh Sunki4c086672017-03-30 14:47:55 -07001009/* Events callback */
1010static void ndp_event_data_indication(NanDataPathRequestInd *event)
1011{
1012 sigma_dut_print(global_dut, DUT_MSG_INFO,
1013 "%s: Service Instance Id: %d Peer Discovery MAC ADDR "
1014 MAC_ADDR_STR
1015 " NDP Instance Id: %d App Info len %d App Info %s",
1016 __func__,
1017 event->service_instance_id,
1018 MAC_ADDR_ARRAY(event->peer_disc_mac_addr),
1019 event->ndp_instance_id,
1020 event->app_info.ndp_app_info_len,
1021 event->app_info.ndp_app_info);
1022
1023 global_ndp_instance_id = event->ndp_instance_id;
1024}
1025
1026
1027/* Events callback */
1028static void ndp_event_data_confirm(NanDataPathConfirmInd *event)
1029{
1030 sigma_dut_print(global_dut, DUT_MSG_INFO,
1031 "Received NDP Confirm Indication");
1032
1033 global_ndp_instance_id = event->ndp_instance_id;
1034 if (system("ifconfig nan0 up") != 0) {
1035 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1036 "Failed to set nan interface up");
1037 return;
1038 }
1039 if (system("ip -6 route add fe80::/64 dev nan0 table local") != 0) {
1040 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1041 "Failed to run:ip -6 route replace fe80::/64 dev nan0 table local");
1042 return;
1043 }
1044}
1045
1046
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001047void * my_thread_function(void *ptr)
1048{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001049 wifi_event_loop(global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001050 pthread_exit(0);
1051 return (void *) NULL;
1052}
1053
1054
1055static NanCallbackHandler callbackHandler = {
1056 .NotifyResponse = nan_notify_response,
1057 .EventPublishReplied = nan_event_publish_replied,
1058 .EventPublishTerminated = nan_event_publish_terminated,
1059 .EventMatch = nan_event_match,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001060 .EventMatchExpired = nan_event_match_expired,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001061 .EventSubscribeTerminated = nan_event_subscribe_terminated,
1062 .EventFollowup = nan_event_followup,
1063 .EventDiscEngEvent = nan_event_disceng_event,
1064 .EventDisabled = nan_event_disabled,
Rakesh Sunki4c086672017-03-30 14:47:55 -07001065 .EventDataRequest = ndp_event_data_indication,
1066 .EventDataConfirm = ndp_event_data_confirm,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001067};
1068
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001069
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001070void nan_init(struct sigma_dut *dut)
1071{
1072 pthread_t thread1; /* thread variables */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001073 wifi_error err = wifi_initialize(&global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001074
1075 if (err) {
1076 printf("wifi hal initialize failed\n");
1077 return;
1078 }
1079
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001080 global_interface_handle = wifi_get_iface_handle(global_wifi_handle,
1081 (char *) "wlan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001082 /* create threads 1 */
1083 pthread_create(&thread1, NULL, &my_thread_function, NULL);
1084
1085 pthread_mutex_init(&gMutex, NULL);
1086 pthread_cond_init(&gCondition, NULL);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001087 if (global_interface_handle)
1088 nan_register_handler(global_interface_handle, callbackHandler);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001089}
1090
1091
1092void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1093 struct sigma_cmd *cmd)
1094{
1095 sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default");
1096
1097 if (nan_state == 0) {
1098 nan_init(dut);
1099 nan_state = 1;
1100 }
1101 is_fam = 0;
1102 event_anyresponse = 0;
1103 global_dut = dut;
1104 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1105 sigma_nan_disable(dut, conn, cmd);
1106}
1107
1108
1109int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1110 struct sigma_cmd *cmd)
1111{
1112 const char *program = get_param(cmd, "Prog");
1113 const char *nan_op = get_param(cmd, "NANOp");
1114 const char *method_type = get_param(cmd, "MethodType");
1115 char resp_buf[100];
1116
1117 if (program == NULL)
1118 return -1;
1119
1120 if (strcasecmp(program, "NAN") != 0) {
1121 send_resp(dut, conn, SIGMA_ERROR,
1122 "ErrorCode,Unsupported program");
1123 return 0;
1124 }
1125
1126 if (nan_op) {
1127 /*
1128 * NANOp has been specified.
1129 * We will build a nan_enable or nan_disable command.
1130 */
1131 if (strcasecmp(nan_op, "On") == 0) {
1132 if (sigma_nan_enable(dut, conn, cmd) == 0) {
1133 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1134 MAC_ADDR_STR,
1135 MAC_ADDR_ARRAY(global_nan_mac_addr));
1136 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1137 } else {
1138 send_resp(dut, conn, SIGMA_ERROR,
1139 "NAN_ENABLE_FAILED");
1140 return -1;
1141 }
1142 } else if (strcasecmp(nan_op, "Off") == 0) {
1143 sigma_nan_disable(dut, conn, cmd);
1144 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1145 }
1146 }
1147 if (nan_state && nan_op == NULL) {
1148 if (method_type) {
1149 if (strcasecmp(method_type, "Publish") == 0) {
1150 sigma_nan_publish_request(dut, conn, cmd);
1151 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1152 }
1153 if (strcasecmp(method_type, "Subscribe") == 0) {
1154 sigma_nan_subscribe_request(dut, conn, cmd);
1155 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1156 }
1157 if (strcasecmp(method_type, "Followup") == 0) {
1158 sigma_nan_transmit_followup(dut, conn, cmd);
1159 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1160 }
1161 } else {
1162 sigma_nan_config_enable(dut, conn, cmd);
1163 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1164 MAC_ADDR_STR,
1165 MAC_ADDR_ARRAY(global_nan_mac_addr));
1166 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1167 }
1168 }
1169
1170 return 0;
1171}
1172
1173
1174int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1175 struct sigma_cmd *cmd)
1176{
1177
1178 const char *program = get_param(cmd, "Program");
1179 const char *parameter = get_param(cmd, "Parameter");
1180 char resp_buf[100];
1181 NanStaParameter rsp;
1182
1183 if (program == NULL) {
1184 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name");
1185 return -1;
1186 }
1187 if (strcasecmp(program, "NAN") != 0) {
1188 send_resp(dut, conn, SIGMA_ERROR,
1189 "ErrorCode,Unsupported program");
1190 return 0;
1191 }
1192
1193 if (parameter == NULL) {
1194 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter");
1195 return -1;
1196 }
1197 memset(&rsp, 0, sizeof(NanStaParameter));
1198
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001199 nan_get_sta_parameter(0, global_interface_handle, &rsp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001200 sigma_dut_print(dut, DUT_MSG_INFO,
1201 "%s: NanStaparameter Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d",
1202 __func__, rsp.master_pref, rsp.random_factor,
1203 rsp.hop_count, rsp.beacon_transmit_time);
1204
1205 if (strcasecmp(parameter, "MasterPref") == 0) {
1206 snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x",
1207 rsp.master_pref);
1208 } else if (strcasecmp(parameter, "MasterRank") == 0) {
1209 snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx",
1210 rsp.master_rank);
1211 } else if (strcasecmp(parameter, "RandFactor") == 0) {
1212 snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x",
1213 rsp.random_factor);
1214 } else if (strcasecmp(parameter, "HopCount") == 0) {
1215 snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x",
1216 rsp.hop_count);
1217 } else if (strcasecmp(parameter, "BeaconTransTime") == 0) {
1218 snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x",
1219 rsp.beacon_transmit_time);
1220 } else if (strcasecmp(parameter, "NANStatus") == 0) {
1221 if (nan_state == 1)
1222 snprintf(resp_buf, sizeof(resp_buf), "On");
1223 else
1224 snprintf(resp_buf, sizeof(resp_buf), "Off");
1225 } else {
1226 send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
1227 return 0;
1228 }
1229
1230 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1231 return 0;
1232}
1233
1234
1235int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1236 struct sigma_cmd *cmd)
1237{
1238 const char *action = get_param(cmd, "Action");
1239
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001240 if (!action)
1241 return 0;
1242
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001243 /* Check action for start, stop and get events. */
1244 if (strcasecmp(action, "Start") == 0) {
1245 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1246 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1247 } else if (strcasecmp(action, "Stop") == 0) {
1248 event_anyresponse = 0;
1249 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1250 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1251 } else if (strcasecmp(action, "Get") == 0) {
1252 if (event_anyresponse == 1) {
1253 send_resp(dut, conn, SIGMA_COMPLETE,
1254 global_event_resp_buf);
1255 } else {
1256 send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE");
1257 }
1258 }
1259 return 0;
1260}
Rakesh Sunki4b75f962017-03-30 14:47:55 -07001261
1262#else /* #if NAN_CERT_VERSION */
1263
1264int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
1265 struct sigma_conn *conn,
1266 struct sigma_cmd *cmd)
1267{
1268 return 1;
1269}
1270
1271
1272int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1273 struct sigma_cmd *cmd)
1274{
1275 return 0;
1276
1277}
1278
1279
1280void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1281 struct sigma_cmd *cmd)
1282{
1283 return;
1284}
1285
1286
1287int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1288 struct sigma_cmd *cmd)
1289{
1290 return 0;
1291}
1292
1293
1294int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1295 struct sigma_cmd *cmd)
1296{
1297 return 0;
1298}
1299
1300#endif /* #if NAN_CERT_VERSION */