blob: 03d10852a663f76dddcbb99963975054d0dab530 [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
Rakesh Sunki14bff1d2017-03-30 14:47:55 -0700198 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200199 return 0;
200}
201
202
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700203void nan_print_further_availability_chan(struct sigma_dut *dut,
204 u8 num_chans,
205 NanFurtherAvailabilityChannel *fachan)
206{
207 int idx;
208
209 sigma_dut_print(dut, DUT_MSG_INFO,
210 "********Printing FurtherAvailabilityChan Info******");
211 sigma_dut_print(dut, DUT_MSG_INFO, "Numchans:%d", num_chans);
212 for (idx = 0; idx < num_chans; idx++) {
213 sigma_dut_print(dut, DUT_MSG_INFO,
214 "[%d]: NanAvailDuration:%d class_val:%02x channel:%d",
215 idx, fachan->entry_control,
216 fachan->class_val, fachan->channel);
217 sigma_dut_print(dut, DUT_MSG_INFO,
218 "[%d]: mapid:%d Availability bitmap:%08x",
219 idx, fachan->mapid,
220 fachan->avail_interval_bitmap);
221 }
222 sigma_dut_print(dut, DUT_MSG_INFO,
223 "*********************Done**********************");
224}
225
226
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200227int sigma_nan_enable(struct sigma_dut *dut, struct sigma_conn *conn,
228 struct sigma_cmd *cmd)
229{
230 const char *master_pref = get_param(cmd, "MasterPref");
231 const char *rand_fac = get_param(cmd, "RandFactor");
232 const char *hop_count = get_param(cmd, "HopCount");
233 const char *high_tsf = get_param(cmd, "HighTSF");
234 const char *sdftx_band = get_param(cmd, "SDFTxBand");
235 const char *oper_chan = get_param(cmd, "oper_chn");
236 const char *further_avail_ind = get_param(cmd, "FurtherAvailInd");
237 const char *band = get_param(cmd, "Band");
238 const char *only_5g = get_param(cmd, "5GOnly");
239 struct timespec abstime;
240 NanEnableRequest req;
241
242 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200243 req.cluster_low = 0;
244 req.cluster_high = 0xFFFF;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700245 req.master_pref = 100;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200246
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700247 /* This is a debug hack to beacon in channel 11 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200248 if (oper_chan) {
249 req.config_2dot4g_support = 1;
250 req.support_2dot4g_val = 111;
251 }
252
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200253 if (master_pref) {
254 int master_pref_val = strtoul(master_pref, NULL, 0);
255
256 req.master_pref = master_pref_val;
257 }
258
259 if (rand_fac) {
260 int rand_fac_val = strtoul(rand_fac, NULL, 0);
261
262 req.config_random_factor_force = 1;
263 req.random_factor_force_val = rand_fac_val;
264 }
265
266 if (hop_count) {
267 int hop_count_val = strtoul(hop_count, NULL, 0);
268
269 req.config_hop_count_force = 1;
270 req.hop_count_force_val = hop_count_val;
271 }
272
273 if (sdftx_band) {
274 if (strcasecmp(sdftx_band, "5G") == 0) {
275 req.config_2dot4g_support = 1;
276 req.support_2dot4g_val = 0;
277 }
278 }
279
280 if (band) {
281 if (strcasecmp(band, "24G") == 0) {
282 sigma_dut_print(dut, DUT_MSG_INFO,
283 "Band 2.4GHz selected");
284 /* Enable 2.4G support */
285 req.config_2dot4g_support = 1;
286 req.support_2dot4g_val = 1;
287 req.config_2dot4g_beacons = 1;
288 req.beacon_2dot4g_val = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700289 req.config_2dot4g_sdf = 1;
290 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200291
292 /* Disable 5G support */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700293 req.config_support_5g = 1;
294 req.support_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200295 req.config_5g_beacons = 1;
296 req.beacon_5g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700297 req.config_5g_sdf = 1;
298 req.sdf_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200299 }
300 }
301
302 if (further_avail_ind) {
303 sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled");
304 if (strcasecmp(further_avail_ind, "tx") == 0) {
305 is_fam = 1;
306 nan_further_availability_tx(dut, conn, cmd);
307 return 0;
308 } else if (strcasecmp(further_avail_ind, "rx") == 0) {
309 nan_further_availability_rx(dut, conn, cmd);
310 return 0;
311 }
312 }
313
314 if (only_5g && atoi(only_5g)) {
315 sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled");
316 req.config_2dot4g_support = 1;
317 req.support_2dot4g_val = 1;
318 req.config_2dot4g_beacons = 1;
319 req.beacon_2dot4g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700320 req.config_2dot4g_sdf = 1;
321 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200322 }
323
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700324 nan_enable_request(0, global_interface_handle, &req);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700325
326 /* To ensure sta_get_events to get the events
327 * only after joining the NAN cluster. */
328 abstime.tv_sec = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200329 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700330 wait(abstime);
331
332 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200333}
334
335
336int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn,
337 struct sigma_cmd *cmd)
338{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200339 struct timespec abstime;
340
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700341 nan_disable_request(0, global_interface_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200342
343 abstime.tv_sec = 4;
344 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700345 wait(abstime);
346
347 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200348}
349
350
351int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn,
352 struct sigma_cmd *cmd)
353{
354 const char *master_pref = get_param(cmd, "MasterPref");
355 const char *rand_fac = get_param(cmd, "RandFactor");
356 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700357 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200358 struct timespec abstime;
359 NanConfigRequest req;
360
361 memset(&req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200362 req.config_rssi_proximity = 1;
363 req.rssi_proximity = 70;
364
365 if (master_pref) {
366 int master_pref_val = strtoul(master_pref, NULL, 0);
367
368 req.config_master_pref = 1;
369 req.master_pref = master_pref_val;
370 }
371
372 if (rand_fac) {
373 int rand_fac_val = strtoul(rand_fac, NULL, 0);
374
375 req.config_random_factor_force = 1;
376 req.random_factor_force_val = rand_fac_val;
377 }
378
379 if (hop_count) {
380 int hop_count_val = strtoul(hop_count, NULL, 0);
381
382 req.config_hop_count_force = 1;
383 req.hop_count_force_val = hop_count_val;
384 }
385
Rakesh Sunki107356c2017-03-30 14:47:55 -0700386 ret = nan_config_request(0, global_interface_handle, &req);
387 if (ret != WIFI_SUCCESS)
388 send_resp(dut, conn, SIGMA_ERROR, "NAN config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200389
390 abstime.tv_sec = 4;
391 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700392 wait(abstime);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200393
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700394 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200395}
396
397
398static int sigma_nan_subscribe_request(struct sigma_dut *dut,
399 struct sigma_conn *conn,
400 struct sigma_cmd *cmd)
401{
402 const char *subscribe_type = get_param(cmd, "SubscribeType");
403 const char *service_name = get_param(cmd, "ServiceName");
404 const char *disc_range = get_param(cmd, "DiscoveryRange");
405 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
406 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
407 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
408 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
409 const char *include_bit = get_param(cmd, "IncludeBit");
410 const char *mac = get_param(cmd, "MAC");
411 const char *srf_type = get_param(cmd, "SRFType");
412 NanSubscribeRequest req;
413 int filter_len_rx = 0, filter_len_tx = 0;
414 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
415 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700416 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200417
418 memset(&req, 0, sizeof(NanSubscribeRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200419 req.ttl = 0;
420 req.period = 1000;
421 req.subscribe_type = 1;
422 req.serviceResponseFilter = 1; /* MAC */
423 req.serviceResponseInclude = 0;
424 req.ssiRequiredForMatchIndication = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700425 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200426 req.subscribe_count = 0;
427
428 if (subscribe_type) {
429 if (strcasecmp(subscribe_type, "Active") == 0) {
430 req.subscribe_type = 1;
431 } else if (strcasecmp(subscribe_type, "Passive") == 0) {
432 req.subscribe_type = 0;
433 } else if (strcasecmp(subscribe_type, "Cancel") == 0) {
434 NanSubscribeCancelRequest req;
435
436 memset(&req, 0, sizeof(NanSubscribeCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700437 ret = nan_subscribe_cancel_request(
438 0, global_interface_handle, &req);
439 if (ret != WIFI_SUCCESS) {
440 send_resp(dut, conn, SIGMA_ERROR,
441 "NAN subscribe cancel request failed");
442 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200443 return 0;
444 }
445 }
446
447 if (disc_range)
448 req.rssi_threshold_flag = atoi(disc_range);
449
450 if (sdftx_dw)
451 req.subscribe_count = atoi(sdftx_dw);
452
453 /* Check this once again if config can be called here (TBD) */
454 if (discrange_ltd)
455 req.rssi_threshold_flag = atoi(discrange_ltd);
456
457 if (include_bit) {
458 int include_bit_val = atoi(include_bit);
459
460 req.serviceResponseInclude = include_bit_val;
461 sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d",
462 req.serviceResponseInclude);
463 }
464
465 if (srf_type) {
466 int srf_type_val = atoi(srf_type);
467
468 if (srf_type_val == 1)
469 req.serviceResponseFilter = 0; /* Bloom */
470 else
471 req.serviceResponseFilter = 1; /* MAC */
472 req.useServiceResponseFilter = 1;
473 sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d",
474 req.serviceResponseFilter);
475 }
476
477 if (mac) {
478 sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac);
479 req.num_intf_addr_present = nan_parse_mac_address_list(
480 dut, mac, &req.intf_addr[0][0],
481 NAN_MAX_SUBSCRIBE_MAX_ADDRESS);
482 }
483
484 memset(input_rx, 0, sizeof(input_rx));
485 memset(input_tx, 0, sizeof(input_tx));
486 if (rx_match_filter) {
487 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
488 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
489 filter_len_rx);
490 }
491 if (tx_match_filter) {
492 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
493 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
494 filter_len_tx);
495 }
496
497 if (tx_match_filter) {
498 req.tx_match_filter_len = filter_len_tx;
499 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
500 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
501 }
502 if (rx_match_filter) {
503 req.rx_match_filter_len = filter_len_rx;
504 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
505 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
506 }
507
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700508 if (service_name) {
509 strlcpy((char *) req.service_name, service_name,
510 strlen(service_name) + 1);
511 req.service_name_len = strlen(service_name);
512 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200513
Rakesh Sunki107356c2017-03-30 14:47:55 -0700514 ret = nan_subscribe_request(0, global_interface_handle, &req);
515 if (ret != WIFI_SUCCESS) {
516 send_resp(dut, conn, SIGMA_ERROR,
517 "NAN subscribe request failed");
518 }
519
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200520 return 0;
521}
522
523
Rakesh Sunkid7344c02017-03-30 14:47:55 -0700524static int sigma_ndp_configure_band(struct sigma_dut *dut,
525 struct sigma_conn *conn,
526 struct sigma_cmd *cmd,
527 NdpSupportedBand band_config_val)
528{
529 wifi_error ret;
530 NanDebugParams cfg_debug;
531 int size;
532
533 memset(&cfg_debug, 0, sizeof(NanDebugParams));
534 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS;
535 memcpy(cfg_debug.debug_cmd_data, &band_config_val, sizeof(int));
536 sigma_dut_print(dut, DUT_MSG_INFO, "%s:setting debug cmd=0x%x",
537 __func__, cfg_debug.cmd);
538 size = sizeof(u32) + sizeof(int);
539 ret = nan_debug_command_config(0, global_interface_handle, cfg_debug,
540 size);
541 if (ret != WIFI_SUCCESS)
542 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
543
544 return 0;
545}
546
547
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200548int config_post_disc_attr(void)
549{
Rakesh Sunki107356c2017-03-30 14:47:55 -0700550 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200551 NanConfigRequest configReq;
552
553 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200554
555 /* Configure Post disc attr */
556 /* Make these defines and use correct enum */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700557 configReq.num_config_discovery_attr = 1;
558 configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */
559 configReq.discovery_attr_val[0].role = 0;
560 configReq.discovery_attr_val[0].transmit_freq = 1;
561 configReq.discovery_attr_val[0].duration = 0;
562 configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200563
Rakesh Sunki107356c2017-03-30 14:47:55 -0700564 ret = nan_config_request(0, global_interface_handle, &configReq);
565 if (ret != WIFI_SUCCESS) {
566 sigma_dut_print(global_dut, DUT_MSG_INFO,
567 "NAN config request failed while configuring post discovery attribute");
568 }
569
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200570 return 0;
571}
572
573
574int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn,
575 struct sigma_cmd *cmd)
576{
577 const char *publish_type = get_param(cmd, "PublishType");
578 const char *service_name = get_param(cmd, "ServiceName");
579 const char *disc_range = get_param(cmd, "DiscoveryRange");
580 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
581 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
582 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
583 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
584 NanPublishRequest req;
585 int filter_len_rx = 0, filter_len_tx = 0;
586 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
587 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700588 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200589
590 memset(&req, 0, sizeof(NanPublishRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200591 req.ttl = 0;
592 req.period = 500;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700593 req.publish_match_indicator = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200594 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
595 req.tx_type = NAN_TX_TYPE_BROADCAST;
596 req.publish_count = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700597
598 if (service_name) {
599 strlcpy((char *) req.service_name, service_name,
600 strlen(service_name) + 1);
601 req.service_name_len = strlen(service_name);
602 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200603
604 if (publish_type) {
605 if (strcasecmp(publish_type, "Solicited") == 0) {
606 req.publish_type = NAN_PUBLISH_TYPE_SOLICITED;
607 } else if (strcasecmp(publish_type, "Cancel") == 0) {
608 NanPublishCancelRequest req;
609
610 memset(&req, 0, sizeof(NanPublishCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700611 ret = nan_publish_cancel_request(
612 0, global_interface_handle, &req);
613 if (ret != WIFI_SUCCESS) {
614 send_resp(dut, conn, SIGMA_ERROR,
615 "Unable to cancel nan publish request");
616 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200617 return 0;
618 }
619 }
620
621 if (disc_range)
622 req.rssi_threshold_flag = atoi(disc_range);
623
624 if (sdftx_dw)
625 req.publish_count = atoi(sdftx_dw);
626
627 if (discrange_ltd)
628 req.rssi_threshold_flag = atoi(discrange_ltd);
629
630 memset(input_rx, 0, sizeof(input_rx));
631 memset(input_tx, 0, sizeof(input_tx));
632 if (rx_match_filter) {
633 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
634 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
635 filter_len_rx);
636 }
637 if (tx_match_filter) {
638 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
639 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
640 filter_len_tx);
641 }
642
643 if (is_fam == 1) {
644 config_post_disc_attr();
645 /* TODO: Add comments regarding this step */
646 req.connmap = 0x10;
647 }
648
649 if (tx_match_filter) {
650 req.tx_match_filter_len = filter_len_tx;
651 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
652 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
653 }
654
655 if (rx_match_filter) {
656 req.rx_match_filter_len = filter_len_rx;
657 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
658 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
659 }
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700660
661 if (service_name) {
662 strlcpy((char *) req.service_name, service_name,
663 strlen(service_name) + 1);
664 req.service_name_len = strlen(service_name);
665 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200666
Rakesh Sunki107356c2017-03-30 14:47:55 -0700667 ret = nan_publish_request(0, global_interface_handle, &req);
668 if (ret != WIFI_SUCCESS)
669 send_resp(dut, conn, SIGMA_ERROR, "Unable to publish");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200670
671 return 0;
672}
673
674
675static int nan_further_availability_rx(struct sigma_dut *dut,
676 struct sigma_conn *conn,
677 struct sigma_cmd *cmd)
678{
679 const char *master_pref = get_param(cmd, "MasterPref");
680 const char *rand_fac = get_param(cmd, "RandFactor");
681 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700682 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200683 struct timespec abstime;
684
685 NanEnableRequest req;
686
687 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200688 req.cluster_low = 0;
689 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200690 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200691
692 if (master_pref)
693 req.master_pref = strtoul(master_pref, NULL, 0);
694
695 if (rand_fac) {
696 int rand_fac_val = strtoul(rand_fac, NULL, 0);
697
698 req.config_random_factor_force = 1;
699 req.random_factor_force_val = rand_fac_val;
700 }
701
702 if (hop_count) {
703 int hop_count_val = strtoul(hop_count, NULL, 0);
704
705 req.config_hop_count_force = 1;
706 req.hop_count_force_val = hop_count_val;
707 }
708
Rakesh Sunki107356c2017-03-30 14:47:55 -0700709 ret = nan_enable_request(0, global_interface_handle, &req);
710 if (ret != WIFI_SUCCESS) {
711 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
712 return 0;
713 }
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700714
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200715 abstime.tv_sec = 4;
716 abstime.tv_nsec = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200717 wait(abstime);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700718
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200719 return 0;
720}
721
722
723static int nan_further_availability_tx(struct sigma_dut *dut,
724 struct sigma_conn *conn,
725 struct sigma_cmd *cmd)
726{
727 const char *master_pref = get_param(cmd, "MasterPref");
728 const char *rand_fac = get_param(cmd, "RandFactor");
729 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700730 wifi_error ret;
731
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200732 NanEnableRequest req;
733 NanConfigRequest configReq;
734
735 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200736 req.cluster_low = 0;
737 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200738 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200739
740 if (master_pref)
741 req.master_pref = strtoul(master_pref, NULL, 0);
742
743 if (rand_fac) {
744 int rand_fac_val = strtoul(rand_fac, NULL, 0);
745
746 req.config_random_factor_force = 1;
747 req.random_factor_force_val = rand_fac_val;
748 }
749
750 if (hop_count) {
751 int hop_count_val = strtoul(hop_count, NULL, 0);
752
753 req.config_hop_count_force = 1;
754 req.hop_count_force_val = hop_count_val;
755 }
756
Rakesh Sunki107356c2017-03-30 14:47:55 -0700757 ret = nan_enable_request(0, global_interface_handle, &req);
758 if (ret != WIFI_SUCCESS) {
759 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
760 return 0;
761 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200762
763 /* Start the config of fam */
764
765 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200766
767 configReq.config_fam = 1;
768 configReq.fam_val.numchans = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700769 configReq.fam_val.famchan[0].entry_control = 0;
770 configReq.fam_val.famchan[0].class_val = 81;
771 configReq.fam_val.famchan[0].channel = 6;
772 configReq.fam_val.famchan[0].mapid = 0;
773 configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe;
774
Rakesh Sunki107356c2017-03-30 14:47:55 -0700775 ret = nan_config_request(0, global_interface_handle, &configReq);
776 if (ret != WIFI_SUCCESS)
777 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200778
779 return 0;
780}
781
782
783int sigma_nan_transmit_followup(struct sigma_dut *dut,
784 struct sigma_conn *conn,
785 struct sigma_cmd *cmd)
786{
787 const char *mac = get_param(cmd, "mac");
788 const char *requestor_id = get_param(cmd, "RemoteInstanceId");
789 const char *local_id = get_param(cmd, "LocalInstanceId");
790 const char *service_name = get_param(cmd, "servicename");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700791 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200792 NanTransmitFollowupRequest req;
793
794 memset(&req, 0, sizeof(NanTransmitFollowupRequest));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700795 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200796 req.addr[0] = 0xFF;
797 req.addr[1] = 0xFF;
798 req.addr[2] = 0xFF;
799 req.addr[3] = 0xFF;
800 req.addr[4] = 0xFF;
801 req.addr[5] = 0xFF;
802 req.priority = NAN_TX_PRIORITY_NORMAL;
803 req.dw_or_faw = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700804
805 if (service_name)
806 req.service_specific_info_len = strlen(service_name);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200807
808 if (requestor_id) {
809 /* int requestor_id_val = atoi(requestor_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700810 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200811 }
812 if (local_id) {
813 /* int local_id_val = atoi(local_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700814 req.publish_subscribe_id = global_header_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200815 }
816
817 if (mac == NULL) {
818 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address");
819 return -1;
820 }
821 nan_parse_mac_address(dut, mac, req.addr);
822
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200823 if (requestor_id)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700824 req.requestor_instance_id = strtoul(requestor_id, NULL, 0);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200825
Rakesh Sunki107356c2017-03-30 14:47:55 -0700826 ret = nan_transmit_followup_request(0, global_interface_handle, &req);
827 if (ret != WIFI_SUCCESS) {
828 send_resp(dut, conn, SIGMA_ERROR,
829 "Unable to complete nan transmit followup");
830 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700831
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200832 return 0;
833}
834
Rakesh Sunki107356c2017-03-30 14:47:55 -0700835
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200836/* NotifyResponse invoked to notify the status of the Request */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700837void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200838{
839 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700840 "%s: status %d value %d response_type %d",
841 __func__,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200842 rsp_data->status, rsp_data->value,
843 rsp_data->response_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200844 if (rsp_data->response_type == NAN_RESPONSE_STATS) {
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700845 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: stats_type %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200846 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700847 rsp_data->body.stats_response.stats_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200848 }
849#if 0
850 if (rsp_data->response_type == NAN_RESPONSE_CONFIG &&
851 rsp_data->status == 0)
852 pthread_cond_signal(&gCondition);
853#endif
854}
855
856
857/* Events Callback */
858void nan_event_publish_replied(NanPublishRepliedInd *event)
859{
860 sigma_dut_print(global_dut, DUT_MSG_INFO,
861 "%s: handle %d " MAC_ADDR_STR " rssi:%d",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700862 __func__, event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200863 MAC_ADDR_ARRAY(event->addr), event->rssi_value);
864 event_anyresponse = 1;
865 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700866 "EventName,Replied,RemoteInstanceID %d,mac," MAC_ADDR_STR,
867 (event->requestor_instance_id >> 24),
868 MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200869}
870
871
872/* Events Callback */
873void nan_event_publish_terminated(NanPublishTerminatedInd *event)
874{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700875 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d",
876 __func__, event->publish_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200877}
878
879
880/* Events Callback */
881void nan_event_match(NanMatchInd *event)
882{
883 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700884 "%s: Pub/Sub Id %d remote_requestor_id %08x "
885 MAC_ADDR_STR
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200886 " rssi:%d",
887 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700888 event->publish_subscribe_id,
889 event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200890 MAC_ADDR_ARRAY(event->addr),
891 event->rssi_value);
892 event_anyresponse = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700893 global_header_handle = event->publish_subscribe_id;
894 global_match_handle = event->requestor_instance_id;
895
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200896 /* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */
897 /* global_pub_sub_handle = event->header.handle; */
898 /* Print the SSI */
899 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700900 nan_hex_dump(global_dut, event->service_specific_info,
901 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200902 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
903 "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700904 MAC_ADDR_STR " ", (event->requestor_instance_id >> 24),
905 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200906
907 /* Print the match filter */
908 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700909 nan_hex_dump(global_dut, event->sdf_match_filter,
910 event->sdf_match_filter_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200911
912 /* Print the conn_capability */
913 sigma_dut_print(global_dut, DUT_MSG_INFO,
914 "Printing PostConnectivity Capability");
915 if (event->is_conn_capability_valid) {
916 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s",
917 event->conn_capability.is_wfd_supported ?
918 "yes" : "no");
919 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s",
920 (event->conn_capability.is_wfds_supported ?
921 "yes" : "no"));
922 sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s",
923 (event->conn_capability.is_tdls_supported ?
924 "yes" : "no"));
925 sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s",
926 (event->conn_capability.is_ibss_supported ?
927 "yes" : "no"));
928 sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s",
929 (event->conn_capability.is_mesh_supported ?
930 "yes" : "no"));
931 sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d",
932 event->conn_capability.wlan_infra_field);
933 } else {
934 sigma_dut_print(global_dut, DUT_MSG_INFO,
935 "PostConnectivity Capability not present");
936 }
937
938 /* Print the discovery_attr */
939 sigma_dut_print(global_dut, DUT_MSG_INFO,
940 "Printing PostDiscovery Attribute");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700941 if (event->num_rx_discovery_attr) {
942 int idx;
943
944 for (idx = 0; idx < event->num_rx_discovery_attr; idx++) {
945 sigma_dut_print(global_dut, DUT_MSG_INFO,
946 "PostDiscovery Attribute - %d", idx);
947 sigma_dut_print(global_dut, DUT_MSG_INFO,
948 "Conn Type:%d Device Role:%d"
949 MAC_ADDR_STR,
950 event->discovery_attr[idx].type,
951 event->discovery_attr[idx].role,
952 MAC_ADDR_ARRAY(event->discovery_attr[idx].addr));
953 sigma_dut_print(global_dut, DUT_MSG_INFO,
954 "Duration:%d MapId:%d "
955 "avail_interval_bitmap:%04x",
956 event->discovery_attr[idx].duration,
957 event->discovery_attr[idx].mapid,
958 event->discovery_attr[idx].avail_interval_bitmap);
959 sigma_dut_print(global_dut, DUT_MSG_INFO,
960 "Printing Mesh Id:");
961 nan_hex_dump(global_dut,
962 event->discovery_attr[idx].mesh_id,
963 event->discovery_attr[idx].mesh_id_len);
964 sigma_dut_print(global_dut, DUT_MSG_INFO,
965 "Printing Infrastructure Ssid:");
966 nan_hex_dump(global_dut,
967 event->discovery_attr[idx].infrastructure_ssid_val,
968 event->discovery_attr[idx].infrastructure_ssid_len);
969 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200970 } else {
971 sigma_dut_print(global_dut, DUT_MSG_INFO,
972 "PostDiscovery attribute not present");
973 }
974
975 /* Print the fam */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700976 if (event->num_chans) {
977 nan_print_further_availability_chan(global_dut,
978 event->num_chans,
979 &event->famchan[0]);
980 } else {
981 sigma_dut_print(global_dut, DUT_MSG_INFO,
982 "Further Availability Map not present");
983 }
984 if (event->cluster_attribute_len) {
985 sigma_dut_print(global_dut, DUT_MSG_INFO,
986 "Printing Cluster Attribute:");
987 nan_hex_dump(global_dut, event->cluster_attribute,
988 event->cluster_attribute_len);
989 } else {
990 sigma_dut_print(global_dut, DUT_MSG_INFO,
991 "Cluster Attribute not present");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200992 }
993}
994
995
996/* Events Callback */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700997void nan_event_match_expired(NanMatchExpiredInd *event)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200998{
999 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001000 "%s: publish_subscribe_id %d match_handle %08x",
1001 __func__, event->publish_subscribe_id,
1002 event->requestor_instance_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001003}
1004
1005
1006/* Events Callback */
1007void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event)
1008{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001009 sigma_dut_print(global_dut, DUT_MSG_INFO,
1010 "%s: Subscribe Id %d reason %d",
1011 __func__, event->subscribe_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001012}
1013
1014
1015/* Events Callback */
1016void nan_event_followup(NanFollowupInd *event)
1017{
1018 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001019 "%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d "
1020 MAC_ADDR_STR, __func__, event->publish_subscribe_id,
1021 event->requestor_instance_id, event->dw_or_faw,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001022 MAC_ADDR_ARRAY(event->addr));
1023
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001024 global_match_handle = event->publish_subscribe_id;
1025 global_header_handle = event->requestor_instance_id;
1026 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__);
1027 nan_hex_dump(global_dut, event->service_specific_info,
1028 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001029 event_anyresponse = 1;
1030 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1031 "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001032 MAC_ADDR_STR " ", event->requestor_instance_id >> 24,
1033 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001034}
1035
1036
1037/* Events Callback */
1038void nan_event_disceng_event(NanDiscEngEventInd *event)
1039{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001040 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d",
1041 __func__, event->event_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001042
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001043 if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001044 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster "
1045 MAC_ADDR_STR,
1046 __func__,
1047 MAC_ADDR_ARRAY(event->data.cluster.addr));
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001048 /* To ensure sta_get_events to get the events
1049 * only after joining the NAN cluster. */
1050 pthread_cond_signal(&gCondition);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001051 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001052 if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001053 sigma_dut_print(global_dut, DUT_MSG_INFO,
1054 "%s: Started cluster " MAC_ADDR_STR,
1055 __func__,
1056 MAC_ADDR_ARRAY(event->data.cluster.addr));
1057 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001058 if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) {
1059 sigma_dut_print(global_dut, DUT_MSG_INFO,
1060 "%s: Discovery Mac Address "
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001061 MAC_ADDR_STR,
1062 __func__,
1063 MAC_ADDR_ARRAY(event->data.mac_addr.addr));
1064 memcpy(global_nan_mac_addr, event->data.mac_addr.addr,
1065 sizeof(global_nan_mac_addr));
1066 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001067}
1068
1069
1070/* Events Callback */
1071void nan_event_disabled(NanDisabledInd *event)
1072{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001073 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d",
1074 __func__, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001075 /* pthread_cond_signal(&gCondition); */
1076}
1077
1078
Rakesh Sunki4c086672017-03-30 14:47:55 -07001079/* Events callback */
1080static void ndp_event_data_indication(NanDataPathRequestInd *event)
1081{
1082 sigma_dut_print(global_dut, DUT_MSG_INFO,
1083 "%s: Service Instance Id: %d Peer Discovery MAC ADDR "
1084 MAC_ADDR_STR
1085 " NDP Instance Id: %d App Info len %d App Info %s",
1086 __func__,
1087 event->service_instance_id,
1088 MAC_ADDR_ARRAY(event->peer_disc_mac_addr),
1089 event->ndp_instance_id,
1090 event->app_info.ndp_app_info_len,
1091 event->app_info.ndp_app_info);
1092
1093 global_ndp_instance_id = event->ndp_instance_id;
1094}
1095
1096
1097/* Events callback */
1098static void ndp_event_data_confirm(NanDataPathConfirmInd *event)
1099{
1100 sigma_dut_print(global_dut, DUT_MSG_INFO,
1101 "Received NDP Confirm Indication");
1102
1103 global_ndp_instance_id = event->ndp_instance_id;
1104 if (system("ifconfig nan0 up") != 0) {
1105 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1106 "Failed to set nan interface up");
1107 return;
1108 }
1109 if (system("ip -6 route add fe80::/64 dev nan0 table local") != 0) {
1110 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1111 "Failed to run:ip -6 route replace fe80::/64 dev nan0 table local");
1112 return;
1113 }
1114}
1115
1116
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001117void * my_thread_function(void *ptr)
1118{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001119 wifi_event_loop(global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001120 pthread_exit(0);
1121 return (void *) NULL;
1122}
1123
1124
1125static NanCallbackHandler callbackHandler = {
1126 .NotifyResponse = nan_notify_response,
1127 .EventPublishReplied = nan_event_publish_replied,
1128 .EventPublishTerminated = nan_event_publish_terminated,
1129 .EventMatch = nan_event_match,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001130 .EventMatchExpired = nan_event_match_expired,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001131 .EventSubscribeTerminated = nan_event_subscribe_terminated,
1132 .EventFollowup = nan_event_followup,
1133 .EventDiscEngEvent = nan_event_disceng_event,
1134 .EventDisabled = nan_event_disabled,
Rakesh Sunki4c086672017-03-30 14:47:55 -07001135 .EventDataRequest = ndp_event_data_indication,
1136 .EventDataConfirm = ndp_event_data_confirm,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001137};
1138
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001139
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001140void nan_init(struct sigma_dut *dut)
1141{
1142 pthread_t thread1; /* thread variables */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001143 wifi_error err = wifi_initialize(&global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001144
1145 if (err) {
1146 printf("wifi hal initialize failed\n");
1147 return;
1148 }
1149
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001150 global_interface_handle = wifi_get_iface_handle(global_wifi_handle,
1151 (char *) "wlan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001152 /* create threads 1 */
1153 pthread_create(&thread1, NULL, &my_thread_function, NULL);
1154
1155 pthread_mutex_init(&gMutex, NULL);
1156 pthread_cond_init(&gCondition, NULL);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001157 if (global_interface_handle)
1158 nan_register_handler(global_interface_handle, callbackHandler);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001159}
1160
1161
1162void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1163 struct sigma_cmd *cmd)
1164{
1165 sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default");
1166
1167 if (nan_state == 0) {
1168 nan_init(dut);
1169 nan_state = 1;
1170 }
1171 is_fam = 0;
1172 event_anyresponse = 0;
1173 global_dut = dut;
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001174 dut->sta_channel = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001175 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001176
1177 nan_data_interface_delete(0, global_interface_handle, (char *) "nan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001178 sigma_nan_disable(dut, conn, cmd);
1179}
1180
1181
1182int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1183 struct sigma_cmd *cmd)
1184{
1185 const char *program = get_param(cmd, "Prog");
1186 const char *nan_op = get_param(cmd, "NANOp");
1187 const char *method_type = get_param(cmd, "MethodType");
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001188 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001189 char resp_buf[100];
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001190 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001191
1192 if (program == NULL)
1193 return -1;
1194
1195 if (strcasecmp(program, "NAN") != 0) {
1196 send_resp(dut, conn, SIGMA_ERROR,
1197 "ErrorCode,Unsupported program");
1198 return 0;
1199 }
1200
1201 if (nan_op) {
1202 /*
1203 * NANOp has been specified.
1204 * We will build a nan_enable or nan_disable command.
1205 */
1206 if (strcasecmp(nan_op, "On") == 0) {
1207 if (sigma_nan_enable(dut, conn, cmd) == 0) {
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001208 ret = nan_data_interface_create(
1209 0, global_interface_handle,
1210 (char *) "nan0");
1211 if (ret != WIFI_SUCCESS) {
1212 sigma_dut_print(
1213 global_dut, DUT_MSG_ERROR,
1214 "Unable to create NAN data interface");
1215 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001216 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1217 MAC_ADDR_STR,
1218 MAC_ADDR_ARRAY(global_nan_mac_addr));
1219 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1220 } else {
1221 send_resp(dut, conn, SIGMA_ERROR,
1222 "NAN_ENABLE_FAILED");
1223 return -1;
1224 }
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001225
1226 if (band && strcasecmp(band, "24g") == 0) {
1227 sigma_dut_print(dut, DUT_MSG_INFO,
1228 "%s: Setting band to 2G Only",
1229 __func__);
1230 sigma_ndp_configure_band(
1231 dut, conn, cmd,
1232 NAN_DATA_PATH_SUPPORTED_BAND_2G);
1233 } else if (band && dut->sta_channel > 12) {
1234 sigma_ndp_configure_band(
1235 dut, conn, cmd,
1236 NAN_DATA_PATH_SUPPORT_DUAL_BAND);
1237 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001238 } else if (strcasecmp(nan_op, "Off") == 0) {
1239 sigma_nan_disable(dut, conn, cmd);
1240 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1241 }
1242 }
1243 if (nan_state && nan_op == NULL) {
1244 if (method_type) {
1245 if (strcasecmp(method_type, "Publish") == 0) {
1246 sigma_nan_publish_request(dut, conn, cmd);
1247 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1248 }
1249 if (strcasecmp(method_type, "Subscribe") == 0) {
1250 sigma_nan_subscribe_request(dut, conn, cmd);
1251 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1252 }
1253 if (strcasecmp(method_type, "Followup") == 0) {
1254 sigma_nan_transmit_followup(dut, conn, cmd);
1255 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1256 }
1257 } else {
1258 sigma_nan_config_enable(dut, conn, cmd);
1259 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1260 MAC_ADDR_STR,
1261 MAC_ADDR_ARRAY(global_nan_mac_addr));
1262 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1263 }
1264 }
1265
1266 return 0;
1267}
1268
1269
1270int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1271 struct sigma_cmd *cmd)
1272{
1273
1274 const char *program = get_param(cmd, "Program");
1275 const char *parameter = get_param(cmd, "Parameter");
1276 char resp_buf[100];
1277 NanStaParameter rsp;
1278
1279 if (program == NULL) {
1280 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name");
1281 return -1;
1282 }
1283 if (strcasecmp(program, "NAN") != 0) {
1284 send_resp(dut, conn, SIGMA_ERROR,
1285 "ErrorCode,Unsupported program");
1286 return 0;
1287 }
1288
1289 if (parameter == NULL) {
1290 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter");
1291 return -1;
1292 }
1293 memset(&rsp, 0, sizeof(NanStaParameter));
1294
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001295 nan_get_sta_parameter(0, global_interface_handle, &rsp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001296 sigma_dut_print(dut, DUT_MSG_INFO,
1297 "%s: NanStaparameter Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d",
1298 __func__, rsp.master_pref, rsp.random_factor,
1299 rsp.hop_count, rsp.beacon_transmit_time);
1300
1301 if (strcasecmp(parameter, "MasterPref") == 0) {
1302 snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x",
1303 rsp.master_pref);
1304 } else if (strcasecmp(parameter, "MasterRank") == 0) {
1305 snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx",
1306 rsp.master_rank);
1307 } else if (strcasecmp(parameter, "RandFactor") == 0) {
1308 snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x",
1309 rsp.random_factor);
1310 } else if (strcasecmp(parameter, "HopCount") == 0) {
1311 snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x",
1312 rsp.hop_count);
1313 } else if (strcasecmp(parameter, "BeaconTransTime") == 0) {
1314 snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x",
1315 rsp.beacon_transmit_time);
1316 } else if (strcasecmp(parameter, "NANStatus") == 0) {
1317 if (nan_state == 1)
1318 snprintf(resp_buf, sizeof(resp_buf), "On");
1319 else
1320 snprintf(resp_buf, sizeof(resp_buf), "Off");
1321 } else {
1322 send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
1323 return 0;
1324 }
1325
1326 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1327 return 0;
1328}
1329
1330
1331int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1332 struct sigma_cmd *cmd)
1333{
1334 const char *action = get_param(cmd, "Action");
1335
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001336 if (!action)
1337 return 0;
1338
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001339 /* Check action for start, stop and get events. */
1340 if (strcasecmp(action, "Start") == 0) {
1341 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1342 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1343 } else if (strcasecmp(action, "Stop") == 0) {
1344 event_anyresponse = 0;
1345 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1346 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1347 } else if (strcasecmp(action, "Get") == 0) {
1348 if (event_anyresponse == 1) {
1349 send_resp(dut, conn, SIGMA_COMPLETE,
1350 global_event_resp_buf);
1351 } else {
1352 send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE");
1353 }
1354 }
1355 return 0;
1356}
Rakesh Sunki4b75f962017-03-30 14:47:55 -07001357
1358#else /* #if NAN_CERT_VERSION */
1359
1360int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
1361 struct sigma_conn *conn,
1362 struct sigma_cmd *cmd)
1363{
1364 return 1;
1365}
1366
1367
1368int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1369 struct sigma_cmd *cmd)
1370{
1371 return 0;
1372
1373}
1374
1375
1376void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1377 struct sigma_cmd *cmd)
1378{
1379 return;
1380}
1381
1382
1383int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1384 struct sigma_cmd *cmd)
1385{
1386 return 0;
1387}
1388
1389
1390int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1391 struct sigma_cmd *cmd)
1392{
1393 return 0;
1394}
1395
1396#endif /* #if NAN_CERT_VERSION */