blob: cb9a4679f41e9376693264bcddc62c1f6051ad46 [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (NAN functionality)
Rakesh Sunki4b75f962017-03-30 14:47:55 -07003 * Copyright (c) 2014-2017, Qualcomm Atheros, Inc.
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004 * All Rights Reserved.
5 * Licensed under the Clear BSD license. See README for more details.
6 */
7
8#include "sigma_dut.h"
9#include <sys/stat.h>
10#include "wpa_ctrl.h"
11#include "wpa_helpers.h"
12#include "wifi_hal.h"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -070013#include "nan_cert.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014
Rakesh Sunki4b75f962017-03-30 14:47:55 -070015#if NAN_CERT_VERSION >= 2
16
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017pthread_cond_t gCondition;
18pthread_mutex_t gMutex;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -070019wifi_handle global_wifi_handle;
20wifi_interface_handle global_interface_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020021static int nan_state = 0;
22static int event_anyresponse = 0;
23static int is_fam = 0;
24
Rakesh Sunki4c086672017-03-30 14:47:55 -070025static uint16_t global_ndp_instance_id = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020026uint16_t global_header_handle = 0;
27uint32_t global_match_handle = 0;
28
29#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
30#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
31#ifndef ETH_ALEN
32#define ETH_ALEN 6
33#endif
34
35struct sigma_dut *global_dut = NULL;
36static char global_nan_mac_addr[ETH_ALEN];
37static char global_event_resp_buf[1024];
38
39static int nan_further_availability_tx(struct sigma_dut *dut,
40 struct sigma_conn *conn,
41 struct sigma_cmd *cmd);
42static int nan_further_availability_rx(struct sigma_dut *dut,
43 struct sigma_conn *conn,
44 struct sigma_cmd *cmd);
45
46
47void nan_hex_dump(struct sigma_dut *dut, uint8_t *data, size_t len)
48{
49 char buf[512];
50 uint16_t index;
51 uint8_t *ptr;
52 int pos;
53
54 memset(buf, 0, sizeof(buf));
55 ptr = data;
56 pos = 0;
57 for (index = 0; index < len; index++) {
58 pos += sprintf(&(buf[pos]), "%02x ", *ptr++);
59 if (pos > 508)
60 break;
61 }
62 sigma_dut_print(dut, DUT_MSG_INFO, "HEXDUMP len=[%d]", (int) len);
63 sigma_dut_print(dut, DUT_MSG_INFO, "buf:%s", buf);
64}
65
66
67int nan_parse_hex(unsigned char c)
68{
69 if (c >= '0' && c <= '9')
70 return c - '0';
71 if (c >= 'a' && c <= 'f')
72 return c - 'a' + 10;
73 if (c >= 'A' && c <= 'F')
74 return c - 'A' + 10;
75 return 0;
76}
77
78
79int nan_parse_token(const char *tokenIn, u8 *tokenOut, int *filterLen)
80{
81 int total_len = 0, len = 0;
82 char *saveptr = NULL;
83
84 tokenIn = strtok_r((char *) tokenIn, ":", &saveptr);
85 while (tokenIn != NULL) {
86 len = strlen(tokenIn);
87 if (len == 1 && *tokenIn == '*')
88 len = 0;
89 tokenOut[total_len++] = (u8) len;
90 if (len != 0)
91 memcpy((u8 *) tokenOut + total_len, tokenIn, len);
92 total_len += len;
93 tokenIn = strtok_r(NULL, ":", &saveptr);
94 }
95 *filterLen = total_len;
96 return 0;
97}
98
99
100int nan_parse_mac_address(struct sigma_dut *dut, const char *arg, u8 *addr)
101{
102 if (strlen(arg) != 17) {
103 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid mac address %s",
104 arg);
105 sigma_dut_print(dut, DUT_MSG_ERROR,
106 "expected format xx:xx:xx:xx:xx:xx");
107 return -1;
108 }
109
110 addr[0] = nan_parse_hex(arg[0]) << 4 | nan_parse_hex(arg[1]);
111 addr[1] = nan_parse_hex(arg[3]) << 4 | nan_parse_hex(arg[4]);
112 addr[2] = nan_parse_hex(arg[6]) << 4 | nan_parse_hex(arg[7]);
113 addr[3] = nan_parse_hex(arg[9]) << 4 | nan_parse_hex(arg[10]);
114 addr[4] = nan_parse_hex(arg[12]) << 4 | nan_parse_hex(arg[13]);
115 addr[5] = nan_parse_hex(arg[15]) << 4 | nan_parse_hex(arg[16]);
116
117 return 0;
118}
119
120
121int nan_parse_mac_address_list(struct sigma_dut *dut, const char *input,
122 u8 *output, u16 max_addr_allowed)
123{
124 /*
125 * Reads a list of mac address separated by space. Each MAC address
126 * should have the format of aa:bb:cc:dd:ee:ff.
127 */
128 char *saveptr;
129 char *token;
130 int i = 0;
131
132 for (i = 0; i < max_addr_allowed; i++) {
133 token = strtok_r((i == 0) ? (char *) input : NULL,
134 " ", &saveptr);
135 if (token) {
136 nan_parse_mac_address(dut, token, output);
137 output += NAN_MAC_ADDR_LEN;
138 } else
139 break;
140 }
141
142 sigma_dut_print(dut, DUT_MSG_INFO, "Num MacAddress:%d", i);
143
144 return i;
145}
146
147
148int nan_parse_hex_string(struct sigma_dut *dut, const char *input,
149 u8 *output, int *outputlen)
150{
151 int i = 0;
152 int j = 0;
153
154 for (i = 0; i < (int) strlen(input) && j < *outputlen; i += 2) {
155 output[j] = nan_parse_hex(input[i]);
156 if (i + 1 < (int) strlen(input)) {
157 output[j] = ((output[j] << 4) |
158 nan_parse_hex(input[i + 1]));
159 }
160 j++;
161 }
162 *outputlen = j;
163 sigma_dut_print(dut, DUT_MSG_INFO, "Input:%s inputlen:%d outputlen:%d",
164 input, (int) strlen(input), (int) *outputlen);
165 return 0;
166}
167
168
169int wait(struct timespec abstime)
170{
171 struct timeval now;
172
173 gettimeofday(&now, NULL);
174
175 abstime.tv_sec += now.tv_sec;
176 if (((abstime.tv_nsec + now.tv_usec * 1000) > 1000 * 1000 * 1000) ||
177 (abstime.tv_nsec + now.tv_usec * 1000 < 0)) {
178 abstime.tv_sec += 1;
179 abstime.tv_nsec += now.tv_usec * 1000;
180 abstime.tv_nsec -= 1000 * 1000 * 1000;
181 } else {
182 abstime.tv_nsec += now.tv_usec * 1000;
183 }
184
185 return pthread_cond_timedwait(&gCondition, &gMutex, &abstime);
186}
187
188
189int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
190 struct sigma_conn *conn,
191 struct sigma_cmd *cmd)
192{
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700193 const char *oper_chan = get_param(cmd, "oper_chn");
Rakesh Sunki7d37f412017-03-30 14:47:55 -0700194 const char *pmk = get_param(cmd, "PMK");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200195
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700196 if (oper_chan) {
197 sigma_dut_print(dut, DUT_MSG_INFO, "Operating Channel: %s",
198 oper_chan);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700199 dut->sta_channel = atoi(oper_chan);
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700200 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200201
Rakesh Sunki7d37f412017-03-30 14:47:55 -0700202 if (pmk) {
203 int pmk_len;
204
205 sigma_dut_print(dut, DUT_MSG_INFO, "%s given string pmk: %s",
206 __func__, pmk);
207 memset(dut->nan_pmk, 0, NAN_PMK_INFO_LEN);
208 dut->nan_pmk_len = 0;
209 pmk_len = NAN_PMK_INFO_LEN;
210 nan_parse_hex_string(dut, &pmk[2], &dut->nan_pmk[0], &pmk_len);
211 dut->nan_pmk_len = pmk_len;
212 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
213 __func__, dut->nan_pmk_len);
214 sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex pmk", __func__);
215 nan_hex_dump(dut, &dut->nan_pmk[0], dut->nan_pmk_len);
216 }
217
Rakesh Sunki14bff1d2017-03-30 14:47:55 -0700218 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200219 return 0;
220}
221
222
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700223void nan_print_further_availability_chan(struct sigma_dut *dut,
224 u8 num_chans,
225 NanFurtherAvailabilityChannel *fachan)
226{
227 int idx;
228
229 sigma_dut_print(dut, DUT_MSG_INFO,
230 "********Printing FurtherAvailabilityChan Info******");
231 sigma_dut_print(dut, DUT_MSG_INFO, "Numchans:%d", num_chans);
232 for (idx = 0; idx < num_chans; idx++) {
233 sigma_dut_print(dut, DUT_MSG_INFO,
234 "[%d]: NanAvailDuration:%d class_val:%02x channel:%d",
235 idx, fachan->entry_control,
236 fachan->class_val, fachan->channel);
237 sigma_dut_print(dut, DUT_MSG_INFO,
238 "[%d]: mapid:%d Availability bitmap:%08x",
239 idx, fachan->mapid,
240 fachan->avail_interval_bitmap);
241 }
242 sigma_dut_print(dut, DUT_MSG_INFO,
243 "*********************Done**********************");
244}
245
246
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200247int sigma_nan_enable(struct sigma_dut *dut, struct sigma_conn *conn,
248 struct sigma_cmd *cmd)
249{
250 const char *master_pref = get_param(cmd, "MasterPref");
251 const char *rand_fac = get_param(cmd, "RandFactor");
252 const char *hop_count = get_param(cmd, "HopCount");
253 const char *high_tsf = get_param(cmd, "HighTSF");
254 const char *sdftx_band = get_param(cmd, "SDFTxBand");
255 const char *oper_chan = get_param(cmd, "oper_chn");
256 const char *further_avail_ind = get_param(cmd, "FurtherAvailInd");
257 const char *band = get_param(cmd, "Band");
258 const char *only_5g = get_param(cmd, "5GOnly");
259 struct timespec abstime;
260 NanEnableRequest req;
261
262 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200263 req.cluster_low = 0;
264 req.cluster_high = 0xFFFF;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700265 req.master_pref = 100;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200266
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700267 /* This is a debug hack to beacon in channel 11 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200268 if (oper_chan) {
269 req.config_2dot4g_support = 1;
270 req.support_2dot4g_val = 111;
271 }
272
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200273 if (master_pref) {
274 int master_pref_val = strtoul(master_pref, NULL, 0);
275
276 req.master_pref = master_pref_val;
277 }
278
279 if (rand_fac) {
280 int rand_fac_val = strtoul(rand_fac, NULL, 0);
281
282 req.config_random_factor_force = 1;
283 req.random_factor_force_val = rand_fac_val;
284 }
285
286 if (hop_count) {
287 int hop_count_val = strtoul(hop_count, NULL, 0);
288
289 req.config_hop_count_force = 1;
290 req.hop_count_force_val = hop_count_val;
291 }
292
293 if (sdftx_band) {
294 if (strcasecmp(sdftx_band, "5G") == 0) {
295 req.config_2dot4g_support = 1;
296 req.support_2dot4g_val = 0;
297 }
298 }
299
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700300 sigma_dut_print(dut, DUT_MSG_INFO,
301 "%s: Setting dual band 2.4 GHz and 5 GHz by default",
302 __func__);
303 /* Enable 2.4 GHz support */
304 req.config_2dot4g_support = 1;
305 req.support_2dot4g_val = 1;
306 req.config_2dot4g_beacons = 1;
307 req.beacon_2dot4g_val = 1;
308 req.config_2dot4g_sdf = 1;
309 req.sdf_2dot4g_val = 1;
310
311 /* Enable 5 GHz support */
312 req.config_support_5g = 1;
313 req.support_5g_val = 1;
314 req.config_5g_beacons = 1;
315 req.beacon_5g_val = 1;
316 req.config_5g_sdf = 1;
317 req.sdf_5g_val = 1;
318
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200319 if (band) {
320 if (strcasecmp(band, "24G") == 0) {
321 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700322 "Band 2.4 GHz selected, disable 5 GHz");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200323 /* Disable 5G support */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700324 req.config_support_5g = 1;
325 req.support_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200326 req.config_5g_beacons = 1;
327 req.beacon_5g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700328 req.config_5g_sdf = 1;
329 req.sdf_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200330 }
331 }
332
333 if (further_avail_ind) {
334 sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled");
335 if (strcasecmp(further_avail_ind, "tx") == 0) {
336 is_fam = 1;
337 nan_further_availability_tx(dut, conn, cmd);
338 return 0;
339 } else if (strcasecmp(further_avail_ind, "rx") == 0) {
340 nan_further_availability_rx(dut, conn, cmd);
341 return 0;
342 }
343 }
344
345 if (only_5g && atoi(only_5g)) {
346 sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled");
347 req.config_2dot4g_support = 1;
348 req.support_2dot4g_val = 1;
349 req.config_2dot4g_beacons = 1;
350 req.beacon_2dot4g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700351 req.config_2dot4g_sdf = 1;
352 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200353 }
354
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700355 nan_enable_request(0, global_interface_handle, &req);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700356
357 /* To ensure sta_get_events to get the events
358 * only after joining the NAN cluster. */
359 abstime.tv_sec = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200360 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700361 wait(abstime);
362
363 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200364}
365
366
367int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn,
368 struct sigma_cmd *cmd)
369{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200370 struct timespec abstime;
371
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700372 nan_disable_request(0, global_interface_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200373
374 abstime.tv_sec = 4;
375 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700376 wait(abstime);
377
378 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200379}
380
381
382int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn,
383 struct sigma_cmd *cmd)
384{
385 const char *master_pref = get_param(cmd, "MasterPref");
386 const char *rand_fac = get_param(cmd, "RandFactor");
387 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700388 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200389 struct timespec abstime;
390 NanConfigRequest req;
391
392 memset(&req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200393 req.config_rssi_proximity = 1;
394 req.rssi_proximity = 70;
395
396 if (master_pref) {
397 int master_pref_val = strtoul(master_pref, NULL, 0);
398
399 req.config_master_pref = 1;
400 req.master_pref = master_pref_val;
401 }
402
403 if (rand_fac) {
404 int rand_fac_val = strtoul(rand_fac, NULL, 0);
405
406 req.config_random_factor_force = 1;
407 req.random_factor_force_val = rand_fac_val;
408 }
409
410 if (hop_count) {
411 int hop_count_val = strtoul(hop_count, NULL, 0);
412
413 req.config_hop_count_force = 1;
414 req.hop_count_force_val = hop_count_val;
415 }
416
Rakesh Sunki107356c2017-03-30 14:47:55 -0700417 ret = nan_config_request(0, global_interface_handle, &req);
418 if (ret != WIFI_SUCCESS)
419 send_resp(dut, conn, SIGMA_ERROR, "NAN config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200420
421 abstime.tv_sec = 4;
422 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700423 wait(abstime);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200424
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700425 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200426}
427
428
429static int sigma_nan_subscribe_request(struct sigma_dut *dut,
430 struct sigma_conn *conn,
431 struct sigma_cmd *cmd)
432{
433 const char *subscribe_type = get_param(cmd, "SubscribeType");
434 const char *service_name = get_param(cmd, "ServiceName");
435 const char *disc_range = get_param(cmd, "DiscoveryRange");
436 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
437 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
438 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
439 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
440 const char *include_bit = get_param(cmd, "IncludeBit");
441 const char *mac = get_param(cmd, "MAC");
442 const char *srf_type = get_param(cmd, "SRFType");
443 NanSubscribeRequest req;
444 int filter_len_rx = 0, filter_len_tx = 0;
445 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
446 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700447 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200448
449 memset(&req, 0, sizeof(NanSubscribeRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200450 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -0700451 req.period = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200452 req.subscribe_type = 1;
453 req.serviceResponseFilter = 1; /* MAC */
454 req.serviceResponseInclude = 0;
455 req.ssiRequiredForMatchIndication = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700456 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200457 req.subscribe_count = 0;
458
459 if (subscribe_type) {
460 if (strcasecmp(subscribe_type, "Active") == 0) {
461 req.subscribe_type = 1;
462 } else if (strcasecmp(subscribe_type, "Passive") == 0) {
463 req.subscribe_type = 0;
464 } else if (strcasecmp(subscribe_type, "Cancel") == 0) {
465 NanSubscribeCancelRequest req;
466
467 memset(&req, 0, sizeof(NanSubscribeCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700468 ret = nan_subscribe_cancel_request(
469 0, global_interface_handle, &req);
470 if (ret != WIFI_SUCCESS) {
471 send_resp(dut, conn, SIGMA_ERROR,
472 "NAN subscribe cancel request failed");
473 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200474 return 0;
475 }
476 }
477
478 if (disc_range)
479 req.rssi_threshold_flag = atoi(disc_range);
480
481 if (sdftx_dw)
482 req.subscribe_count = atoi(sdftx_dw);
483
484 /* Check this once again if config can be called here (TBD) */
485 if (discrange_ltd)
486 req.rssi_threshold_flag = atoi(discrange_ltd);
487
488 if (include_bit) {
489 int include_bit_val = atoi(include_bit);
490
491 req.serviceResponseInclude = include_bit_val;
492 sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d",
493 req.serviceResponseInclude);
494 }
495
496 if (srf_type) {
497 int srf_type_val = atoi(srf_type);
498
499 if (srf_type_val == 1)
500 req.serviceResponseFilter = 0; /* Bloom */
501 else
502 req.serviceResponseFilter = 1; /* MAC */
503 req.useServiceResponseFilter = 1;
504 sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d",
505 req.serviceResponseFilter);
506 }
507
508 if (mac) {
509 sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac);
510 req.num_intf_addr_present = nan_parse_mac_address_list(
511 dut, mac, &req.intf_addr[0][0],
512 NAN_MAX_SUBSCRIBE_MAX_ADDRESS);
513 }
514
515 memset(input_rx, 0, sizeof(input_rx));
516 memset(input_tx, 0, sizeof(input_tx));
517 if (rx_match_filter) {
518 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
519 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
520 filter_len_rx);
521 }
522 if (tx_match_filter) {
523 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
524 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
525 filter_len_tx);
526 }
527
528 if (tx_match_filter) {
529 req.tx_match_filter_len = filter_len_tx;
530 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
531 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
532 }
533 if (rx_match_filter) {
534 req.rx_match_filter_len = filter_len_rx;
535 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
536 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
537 }
538
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700539 if (service_name) {
540 strlcpy((char *) req.service_name, service_name,
541 strlen(service_name) + 1);
542 req.service_name_len = strlen(service_name);
543 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200544
Rakesh Sunki107356c2017-03-30 14:47:55 -0700545 ret = nan_subscribe_request(0, global_interface_handle, &req);
546 if (ret != WIFI_SUCCESS) {
547 send_resp(dut, conn, SIGMA_ERROR,
548 "NAN subscribe request failed");
549 }
550
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200551 return 0;
552}
553
554
Rakesh Sunkid7344c02017-03-30 14:47:55 -0700555static int sigma_ndp_configure_band(struct sigma_dut *dut,
556 struct sigma_conn *conn,
557 struct sigma_cmd *cmd,
558 NdpSupportedBand band_config_val)
559{
560 wifi_error ret;
561 NanDebugParams cfg_debug;
562 int size;
563
564 memset(&cfg_debug, 0, sizeof(NanDebugParams));
565 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS;
566 memcpy(cfg_debug.debug_cmd_data, &band_config_val, sizeof(int));
567 sigma_dut_print(dut, DUT_MSG_INFO, "%s:setting debug cmd=0x%x",
568 __func__, cfg_debug.cmd);
569 size = sizeof(u32) + sizeof(int);
570 ret = nan_debug_command_config(0, global_interface_handle, cfg_debug,
571 size);
572 if (ret != WIFI_SUCCESS)
573 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
574
575 return 0;
576}
577
578
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200579int config_post_disc_attr(void)
580{
Rakesh Sunki107356c2017-03-30 14:47:55 -0700581 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200582 NanConfigRequest configReq;
583
584 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200585
586 /* Configure Post disc attr */
587 /* Make these defines and use correct enum */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700588 configReq.num_config_discovery_attr = 1;
589 configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */
590 configReq.discovery_attr_val[0].role = 0;
591 configReq.discovery_attr_val[0].transmit_freq = 1;
592 configReq.discovery_attr_val[0].duration = 0;
593 configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200594
Rakesh Sunki107356c2017-03-30 14:47:55 -0700595 ret = nan_config_request(0, global_interface_handle, &configReq);
596 if (ret != WIFI_SUCCESS) {
597 sigma_dut_print(global_dut, DUT_MSG_INFO,
598 "NAN config request failed while configuring post discovery attribute");
599 }
600
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200601 return 0;
602}
603
604
605int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn,
606 struct sigma_cmd *cmd)
607{
608 const char *publish_type = get_param(cmd, "PublishType");
609 const char *service_name = get_param(cmd, "ServiceName");
610 const char *disc_range = get_param(cmd, "DiscoveryRange");
611 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
612 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
613 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
614 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
615 NanPublishRequest req;
616 int filter_len_rx = 0, filter_len_tx = 0;
617 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
618 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700619 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200620
621 memset(&req, 0, sizeof(NanPublishRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200622 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -0700623 req.period = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700624 req.publish_match_indicator = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200625 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
626 req.tx_type = NAN_TX_TYPE_BROADCAST;
627 req.publish_count = 0;
Rakesh Sunki0a0eea82017-03-30 14:47:55 -0700628 req.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_ALL;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700629
630 if (service_name) {
631 strlcpy((char *) req.service_name, service_name,
632 strlen(service_name) + 1);
633 req.service_name_len = strlen(service_name);
634 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200635
636 if (publish_type) {
637 if (strcasecmp(publish_type, "Solicited") == 0) {
638 req.publish_type = NAN_PUBLISH_TYPE_SOLICITED;
639 } else if (strcasecmp(publish_type, "Cancel") == 0) {
640 NanPublishCancelRequest req;
641
642 memset(&req, 0, sizeof(NanPublishCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700643 ret = nan_publish_cancel_request(
644 0, global_interface_handle, &req);
645 if (ret != WIFI_SUCCESS) {
646 send_resp(dut, conn, SIGMA_ERROR,
647 "Unable to cancel nan publish request");
648 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200649 return 0;
650 }
651 }
652
653 if (disc_range)
654 req.rssi_threshold_flag = atoi(disc_range);
655
656 if (sdftx_dw)
657 req.publish_count = atoi(sdftx_dw);
658
659 if (discrange_ltd)
660 req.rssi_threshold_flag = atoi(discrange_ltd);
661
662 memset(input_rx, 0, sizeof(input_rx));
663 memset(input_tx, 0, sizeof(input_tx));
664 if (rx_match_filter) {
665 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
666 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
667 filter_len_rx);
668 }
669 if (tx_match_filter) {
670 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
671 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
672 filter_len_tx);
673 }
674
675 if (is_fam == 1) {
676 config_post_disc_attr();
677 /* TODO: Add comments regarding this step */
678 req.connmap = 0x10;
679 }
680
681 if (tx_match_filter) {
682 req.tx_match_filter_len = filter_len_tx;
683 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
684 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
685 }
686
687 if (rx_match_filter) {
688 req.rx_match_filter_len = filter_len_rx;
689 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
690 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
691 }
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700692
693 if (service_name) {
694 strlcpy((char *) req.service_name, service_name,
695 strlen(service_name) + 1);
696 req.service_name_len = strlen(service_name);
697 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200698
Rakesh Sunki107356c2017-03-30 14:47:55 -0700699 ret = nan_publish_request(0, global_interface_handle, &req);
700 if (ret != WIFI_SUCCESS)
701 send_resp(dut, conn, SIGMA_ERROR, "Unable to publish");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200702
703 return 0;
704}
705
706
707static int nan_further_availability_rx(struct sigma_dut *dut,
708 struct sigma_conn *conn,
709 struct sigma_cmd *cmd)
710{
711 const char *master_pref = get_param(cmd, "MasterPref");
712 const char *rand_fac = get_param(cmd, "RandFactor");
713 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700714 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200715 struct timespec abstime;
716
717 NanEnableRequest req;
718
719 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200720 req.cluster_low = 0;
721 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200722 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200723
724 if (master_pref)
725 req.master_pref = strtoul(master_pref, NULL, 0);
726
727 if (rand_fac) {
728 int rand_fac_val = strtoul(rand_fac, NULL, 0);
729
730 req.config_random_factor_force = 1;
731 req.random_factor_force_val = rand_fac_val;
732 }
733
734 if (hop_count) {
735 int hop_count_val = strtoul(hop_count, NULL, 0);
736
737 req.config_hop_count_force = 1;
738 req.hop_count_force_val = hop_count_val;
739 }
740
Rakesh Sunki107356c2017-03-30 14:47:55 -0700741 ret = nan_enable_request(0, global_interface_handle, &req);
742 if (ret != WIFI_SUCCESS) {
743 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
744 return 0;
745 }
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700746
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200747 abstime.tv_sec = 4;
748 abstime.tv_nsec = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200749 wait(abstime);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700750
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200751 return 0;
752}
753
754
755static int nan_further_availability_tx(struct sigma_dut *dut,
756 struct sigma_conn *conn,
757 struct sigma_cmd *cmd)
758{
759 const char *master_pref = get_param(cmd, "MasterPref");
760 const char *rand_fac = get_param(cmd, "RandFactor");
761 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700762 wifi_error ret;
763
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200764 NanEnableRequest req;
765 NanConfigRequest configReq;
766
767 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200768 req.cluster_low = 0;
769 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200770 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200771
772 if (master_pref)
773 req.master_pref = strtoul(master_pref, NULL, 0);
774
775 if (rand_fac) {
776 int rand_fac_val = strtoul(rand_fac, NULL, 0);
777
778 req.config_random_factor_force = 1;
779 req.random_factor_force_val = rand_fac_val;
780 }
781
782 if (hop_count) {
783 int hop_count_val = strtoul(hop_count, NULL, 0);
784
785 req.config_hop_count_force = 1;
786 req.hop_count_force_val = hop_count_val;
787 }
788
Rakesh Sunki107356c2017-03-30 14:47:55 -0700789 ret = nan_enable_request(0, global_interface_handle, &req);
790 if (ret != WIFI_SUCCESS) {
791 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
792 return 0;
793 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200794
795 /* Start the config of fam */
796
797 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200798
799 configReq.config_fam = 1;
800 configReq.fam_val.numchans = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700801 configReq.fam_val.famchan[0].entry_control = 0;
802 configReq.fam_val.famchan[0].class_val = 81;
803 configReq.fam_val.famchan[0].channel = 6;
804 configReq.fam_val.famchan[0].mapid = 0;
805 configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe;
806
Rakesh Sunki107356c2017-03-30 14:47:55 -0700807 ret = nan_config_request(0, global_interface_handle, &configReq);
808 if (ret != WIFI_SUCCESS)
809 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200810
811 return 0;
812}
813
814
815int sigma_nan_transmit_followup(struct sigma_dut *dut,
816 struct sigma_conn *conn,
817 struct sigma_cmd *cmd)
818{
819 const char *mac = get_param(cmd, "mac");
820 const char *requestor_id = get_param(cmd, "RemoteInstanceId");
821 const char *local_id = get_param(cmd, "LocalInstanceId");
822 const char *service_name = get_param(cmd, "servicename");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700823 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200824 NanTransmitFollowupRequest req;
825
826 memset(&req, 0, sizeof(NanTransmitFollowupRequest));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700827 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200828 req.addr[0] = 0xFF;
829 req.addr[1] = 0xFF;
830 req.addr[2] = 0xFF;
831 req.addr[3] = 0xFF;
832 req.addr[4] = 0xFF;
833 req.addr[5] = 0xFF;
834 req.priority = NAN_TX_PRIORITY_NORMAL;
835 req.dw_or_faw = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700836
837 if (service_name)
838 req.service_specific_info_len = strlen(service_name);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200839
840 if (requestor_id) {
841 /* int requestor_id_val = atoi(requestor_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700842 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200843 }
844 if (local_id) {
845 /* int local_id_val = atoi(local_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700846 req.publish_subscribe_id = global_header_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200847 }
848
849 if (mac == NULL) {
850 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address");
851 return -1;
852 }
853 nan_parse_mac_address(dut, mac, req.addr);
854
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200855 if (requestor_id)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700856 req.requestor_instance_id = strtoul(requestor_id, NULL, 0);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200857
Rakesh Sunki107356c2017-03-30 14:47:55 -0700858 ret = nan_transmit_followup_request(0, global_interface_handle, &req);
859 if (ret != WIFI_SUCCESS) {
860 send_resp(dut, conn, SIGMA_ERROR,
861 "Unable to complete nan transmit followup");
862 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700863
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200864 return 0;
865}
866
Rakesh Sunki107356c2017-03-30 14:47:55 -0700867
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200868/* NotifyResponse invoked to notify the status of the Request */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700869void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200870{
871 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700872 "%s: status %d value %d response_type %d",
873 __func__,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200874 rsp_data->status, rsp_data->value,
875 rsp_data->response_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200876 if (rsp_data->response_type == NAN_RESPONSE_STATS) {
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700877 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: stats_type %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200878 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700879 rsp_data->body.stats_response.stats_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200880 }
881#if 0
882 if (rsp_data->response_type == NAN_RESPONSE_CONFIG &&
883 rsp_data->status == 0)
884 pthread_cond_signal(&gCondition);
885#endif
886}
887
888
889/* Events Callback */
890void nan_event_publish_replied(NanPublishRepliedInd *event)
891{
892 sigma_dut_print(global_dut, DUT_MSG_INFO,
893 "%s: handle %d " MAC_ADDR_STR " rssi:%d",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700894 __func__, event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200895 MAC_ADDR_ARRAY(event->addr), event->rssi_value);
896 event_anyresponse = 1;
897 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700898 "EventName,Replied,RemoteInstanceID %d,mac," MAC_ADDR_STR,
899 (event->requestor_instance_id >> 24),
900 MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200901}
902
903
904/* Events Callback */
905void nan_event_publish_terminated(NanPublishTerminatedInd *event)
906{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700907 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d",
908 __func__, event->publish_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200909}
910
911
912/* Events Callback */
913void nan_event_match(NanMatchInd *event)
914{
915 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700916 "%s: Pub/Sub Id %d remote_requestor_id %08x "
917 MAC_ADDR_STR
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200918 " rssi:%d",
919 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700920 event->publish_subscribe_id,
921 event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200922 MAC_ADDR_ARRAY(event->addr),
923 event->rssi_value);
924 event_anyresponse = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700925 global_header_handle = event->publish_subscribe_id;
926 global_match_handle = event->requestor_instance_id;
927
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200928 /* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */
929 /* global_pub_sub_handle = event->header.handle; */
930 /* Print the SSI */
931 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700932 nan_hex_dump(global_dut, event->service_specific_info,
933 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200934 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
935 "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700936 MAC_ADDR_STR " ", (event->requestor_instance_id >> 24),
937 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200938
939 /* Print the match filter */
940 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700941 nan_hex_dump(global_dut, event->sdf_match_filter,
942 event->sdf_match_filter_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200943
944 /* Print the conn_capability */
945 sigma_dut_print(global_dut, DUT_MSG_INFO,
946 "Printing PostConnectivity Capability");
947 if (event->is_conn_capability_valid) {
948 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s",
949 event->conn_capability.is_wfd_supported ?
950 "yes" : "no");
951 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s",
952 (event->conn_capability.is_wfds_supported ?
953 "yes" : "no"));
954 sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s",
955 (event->conn_capability.is_tdls_supported ?
956 "yes" : "no"));
957 sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s",
958 (event->conn_capability.is_ibss_supported ?
959 "yes" : "no"));
960 sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s",
961 (event->conn_capability.is_mesh_supported ?
962 "yes" : "no"));
963 sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d",
964 event->conn_capability.wlan_infra_field);
965 } else {
966 sigma_dut_print(global_dut, DUT_MSG_INFO,
967 "PostConnectivity Capability not present");
968 }
969
970 /* Print the discovery_attr */
971 sigma_dut_print(global_dut, DUT_MSG_INFO,
972 "Printing PostDiscovery Attribute");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700973 if (event->num_rx_discovery_attr) {
974 int idx;
975
976 for (idx = 0; idx < event->num_rx_discovery_attr; idx++) {
977 sigma_dut_print(global_dut, DUT_MSG_INFO,
978 "PostDiscovery Attribute - %d", idx);
979 sigma_dut_print(global_dut, DUT_MSG_INFO,
980 "Conn Type:%d Device Role:%d"
981 MAC_ADDR_STR,
982 event->discovery_attr[idx].type,
983 event->discovery_attr[idx].role,
984 MAC_ADDR_ARRAY(event->discovery_attr[idx].addr));
985 sigma_dut_print(global_dut, DUT_MSG_INFO,
986 "Duration:%d MapId:%d "
987 "avail_interval_bitmap:%04x",
988 event->discovery_attr[idx].duration,
989 event->discovery_attr[idx].mapid,
990 event->discovery_attr[idx].avail_interval_bitmap);
991 sigma_dut_print(global_dut, DUT_MSG_INFO,
992 "Printing Mesh Id:");
993 nan_hex_dump(global_dut,
994 event->discovery_attr[idx].mesh_id,
995 event->discovery_attr[idx].mesh_id_len);
996 sigma_dut_print(global_dut, DUT_MSG_INFO,
997 "Printing Infrastructure Ssid:");
998 nan_hex_dump(global_dut,
999 event->discovery_attr[idx].infrastructure_ssid_val,
1000 event->discovery_attr[idx].infrastructure_ssid_len);
1001 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001002 } else {
1003 sigma_dut_print(global_dut, DUT_MSG_INFO,
1004 "PostDiscovery attribute not present");
1005 }
1006
1007 /* Print the fam */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001008 if (event->num_chans) {
1009 nan_print_further_availability_chan(global_dut,
1010 event->num_chans,
1011 &event->famchan[0]);
1012 } else {
1013 sigma_dut_print(global_dut, DUT_MSG_INFO,
1014 "Further Availability Map not present");
1015 }
1016 if (event->cluster_attribute_len) {
1017 sigma_dut_print(global_dut, DUT_MSG_INFO,
1018 "Printing Cluster Attribute:");
1019 nan_hex_dump(global_dut, event->cluster_attribute,
1020 event->cluster_attribute_len);
1021 } else {
1022 sigma_dut_print(global_dut, DUT_MSG_INFO,
1023 "Cluster Attribute not present");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001024 }
1025}
1026
1027
1028/* Events Callback */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001029void nan_event_match_expired(NanMatchExpiredInd *event)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001030{
1031 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001032 "%s: publish_subscribe_id %d match_handle %08x",
1033 __func__, event->publish_subscribe_id,
1034 event->requestor_instance_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001035}
1036
1037
1038/* Events Callback */
1039void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event)
1040{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001041 sigma_dut_print(global_dut, DUT_MSG_INFO,
1042 "%s: Subscribe Id %d reason %d",
1043 __func__, event->subscribe_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001044}
1045
1046
1047/* Events Callback */
1048void nan_event_followup(NanFollowupInd *event)
1049{
1050 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001051 "%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d "
1052 MAC_ADDR_STR, __func__, event->publish_subscribe_id,
1053 event->requestor_instance_id, event->dw_or_faw,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001054 MAC_ADDR_ARRAY(event->addr));
1055
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001056 global_match_handle = event->publish_subscribe_id;
1057 global_header_handle = event->requestor_instance_id;
1058 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__);
1059 nan_hex_dump(global_dut, event->service_specific_info,
1060 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001061 event_anyresponse = 1;
1062 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1063 "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001064 MAC_ADDR_STR " ", event->requestor_instance_id >> 24,
1065 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001066}
1067
1068
1069/* Events Callback */
1070void nan_event_disceng_event(NanDiscEngEventInd *event)
1071{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001072 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d",
1073 __func__, event->event_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001074
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001075 if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001076 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster "
1077 MAC_ADDR_STR,
1078 __func__,
1079 MAC_ADDR_ARRAY(event->data.cluster.addr));
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001080 /* To ensure sta_get_events to get the events
1081 * only after joining the NAN cluster. */
1082 pthread_cond_signal(&gCondition);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001083 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001084 if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001085 sigma_dut_print(global_dut, DUT_MSG_INFO,
1086 "%s: Started cluster " MAC_ADDR_STR,
1087 __func__,
1088 MAC_ADDR_ARRAY(event->data.cluster.addr));
1089 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001090 if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) {
1091 sigma_dut_print(global_dut, DUT_MSG_INFO,
1092 "%s: Discovery Mac Address "
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001093 MAC_ADDR_STR,
1094 __func__,
1095 MAC_ADDR_ARRAY(event->data.mac_addr.addr));
1096 memcpy(global_nan_mac_addr, event->data.mac_addr.addr,
1097 sizeof(global_nan_mac_addr));
1098 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001099}
1100
1101
1102/* Events Callback */
1103void nan_event_disabled(NanDisabledInd *event)
1104{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001105 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d",
1106 __func__, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001107 /* pthread_cond_signal(&gCondition); */
1108}
1109
1110
Rakesh Sunki4c086672017-03-30 14:47:55 -07001111/* Events callback */
1112static void ndp_event_data_indication(NanDataPathRequestInd *event)
1113{
1114 sigma_dut_print(global_dut, DUT_MSG_INFO,
1115 "%s: Service Instance Id: %d Peer Discovery MAC ADDR "
1116 MAC_ADDR_STR
1117 " NDP Instance Id: %d App Info len %d App Info %s",
1118 __func__,
1119 event->service_instance_id,
1120 MAC_ADDR_ARRAY(event->peer_disc_mac_addr),
1121 event->ndp_instance_id,
1122 event->app_info.ndp_app_info_len,
1123 event->app_info.ndp_app_info);
1124
1125 global_ndp_instance_id = event->ndp_instance_id;
1126}
1127
1128
1129/* Events callback */
1130static void ndp_event_data_confirm(NanDataPathConfirmInd *event)
1131{
1132 sigma_dut_print(global_dut, DUT_MSG_INFO,
1133 "Received NDP Confirm Indication");
1134
1135 global_ndp_instance_id = event->ndp_instance_id;
1136 if (system("ifconfig nan0 up") != 0) {
1137 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1138 "Failed to set nan interface up");
1139 return;
1140 }
1141 if (system("ip -6 route add fe80::/64 dev nan0 table local") != 0) {
1142 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1143 "Failed to run:ip -6 route replace fe80::/64 dev nan0 table local");
1144 return;
1145 }
1146}
1147
1148
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001149void * my_thread_function(void *ptr)
1150{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001151 wifi_event_loop(global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001152 pthread_exit(0);
1153 return (void *) NULL;
1154}
1155
1156
1157static NanCallbackHandler callbackHandler = {
1158 .NotifyResponse = nan_notify_response,
1159 .EventPublishReplied = nan_event_publish_replied,
1160 .EventPublishTerminated = nan_event_publish_terminated,
1161 .EventMatch = nan_event_match,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001162 .EventMatchExpired = nan_event_match_expired,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001163 .EventSubscribeTerminated = nan_event_subscribe_terminated,
1164 .EventFollowup = nan_event_followup,
1165 .EventDiscEngEvent = nan_event_disceng_event,
1166 .EventDisabled = nan_event_disabled,
Rakesh Sunki4c086672017-03-30 14:47:55 -07001167 .EventDataRequest = ndp_event_data_indication,
1168 .EventDataConfirm = ndp_event_data_confirm,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001169};
1170
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001171
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001172void nan_init(struct sigma_dut *dut)
1173{
1174 pthread_t thread1; /* thread variables */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001175 wifi_error err = wifi_initialize(&global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001176
1177 if (err) {
1178 printf("wifi hal initialize failed\n");
1179 return;
1180 }
1181
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001182 global_interface_handle = wifi_get_iface_handle(global_wifi_handle,
1183 (char *) "wlan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001184 /* create threads 1 */
1185 pthread_create(&thread1, NULL, &my_thread_function, NULL);
1186
1187 pthread_mutex_init(&gMutex, NULL);
1188 pthread_cond_init(&gCondition, NULL);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001189 if (global_interface_handle)
1190 nan_register_handler(global_interface_handle, callbackHandler);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001191}
1192
1193
1194void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1195 struct sigma_cmd *cmd)
1196{
1197 sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default");
1198
1199 if (nan_state == 0) {
1200 nan_init(dut);
1201 nan_state = 1;
1202 }
1203 is_fam = 0;
1204 event_anyresponse = 0;
1205 global_dut = dut;
Rakesh Sunki7d37f412017-03-30 14:47:55 -07001206 memset(&dut->nan_pmk[0], 0, NAN_PMK_INFO_LEN);
1207 dut->nan_pmk_len = 0;
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001208 dut->sta_channel = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001209 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001210
1211 nan_data_interface_delete(0, global_interface_handle, (char *) "nan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001212 sigma_nan_disable(dut, conn, cmd);
1213}
1214
1215
1216int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1217 struct sigma_cmd *cmd)
1218{
1219 const char *program = get_param(cmd, "Prog");
1220 const char *nan_op = get_param(cmd, "NANOp");
1221 const char *method_type = get_param(cmd, "MethodType");
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001222 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001223 char resp_buf[100];
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001224 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001225
1226 if (program == NULL)
1227 return -1;
1228
1229 if (strcasecmp(program, "NAN") != 0) {
1230 send_resp(dut, conn, SIGMA_ERROR,
1231 "ErrorCode,Unsupported program");
1232 return 0;
1233 }
1234
1235 if (nan_op) {
1236 /*
1237 * NANOp has been specified.
1238 * We will build a nan_enable or nan_disable command.
1239 */
1240 if (strcasecmp(nan_op, "On") == 0) {
1241 if (sigma_nan_enable(dut, conn, cmd) == 0) {
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001242 ret = nan_data_interface_create(
1243 0, global_interface_handle,
1244 (char *) "nan0");
1245 if (ret != WIFI_SUCCESS) {
1246 sigma_dut_print(
1247 global_dut, DUT_MSG_ERROR,
1248 "Unable to create NAN data interface");
1249 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001250 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1251 MAC_ADDR_STR,
1252 MAC_ADDR_ARRAY(global_nan_mac_addr));
1253 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1254 } else {
1255 send_resp(dut, conn, SIGMA_ERROR,
1256 "NAN_ENABLE_FAILED");
1257 return -1;
1258 }
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001259
1260 if (band && strcasecmp(band, "24g") == 0) {
1261 sigma_dut_print(dut, DUT_MSG_INFO,
1262 "%s: Setting band to 2G Only",
1263 __func__);
1264 sigma_ndp_configure_band(
1265 dut, conn, cmd,
1266 NAN_DATA_PATH_SUPPORTED_BAND_2G);
1267 } else if (band && dut->sta_channel > 12) {
1268 sigma_ndp_configure_band(
1269 dut, conn, cmd,
1270 NAN_DATA_PATH_SUPPORT_DUAL_BAND);
1271 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001272 } else if (strcasecmp(nan_op, "Off") == 0) {
1273 sigma_nan_disable(dut, conn, cmd);
1274 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1275 }
1276 }
1277 if (nan_state && nan_op == NULL) {
1278 if (method_type) {
1279 if (strcasecmp(method_type, "Publish") == 0) {
1280 sigma_nan_publish_request(dut, conn, cmd);
1281 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1282 }
1283 if (strcasecmp(method_type, "Subscribe") == 0) {
1284 sigma_nan_subscribe_request(dut, conn, cmd);
1285 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1286 }
1287 if (strcasecmp(method_type, "Followup") == 0) {
1288 sigma_nan_transmit_followup(dut, conn, cmd);
1289 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1290 }
1291 } else {
1292 sigma_nan_config_enable(dut, conn, cmd);
1293 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1294 MAC_ADDR_STR,
1295 MAC_ADDR_ARRAY(global_nan_mac_addr));
1296 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1297 }
1298 }
1299
1300 return 0;
1301}
1302
1303
1304int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1305 struct sigma_cmd *cmd)
1306{
1307
1308 const char *program = get_param(cmd, "Program");
1309 const char *parameter = get_param(cmd, "Parameter");
1310 char resp_buf[100];
1311 NanStaParameter rsp;
1312
1313 if (program == NULL) {
1314 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name");
1315 return -1;
1316 }
1317 if (strcasecmp(program, "NAN") != 0) {
1318 send_resp(dut, conn, SIGMA_ERROR,
1319 "ErrorCode,Unsupported program");
1320 return 0;
1321 }
1322
1323 if (parameter == NULL) {
1324 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter");
1325 return -1;
1326 }
1327 memset(&rsp, 0, sizeof(NanStaParameter));
1328
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001329 nan_get_sta_parameter(0, global_interface_handle, &rsp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001330 sigma_dut_print(dut, DUT_MSG_INFO,
1331 "%s: NanStaparameter Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d",
1332 __func__, rsp.master_pref, rsp.random_factor,
1333 rsp.hop_count, rsp.beacon_transmit_time);
1334
1335 if (strcasecmp(parameter, "MasterPref") == 0) {
1336 snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x",
1337 rsp.master_pref);
1338 } else if (strcasecmp(parameter, "MasterRank") == 0) {
1339 snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx",
1340 rsp.master_rank);
1341 } else if (strcasecmp(parameter, "RandFactor") == 0) {
1342 snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x",
1343 rsp.random_factor);
1344 } else if (strcasecmp(parameter, "HopCount") == 0) {
1345 snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x",
1346 rsp.hop_count);
1347 } else if (strcasecmp(parameter, "BeaconTransTime") == 0) {
1348 snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x",
1349 rsp.beacon_transmit_time);
1350 } else if (strcasecmp(parameter, "NANStatus") == 0) {
1351 if (nan_state == 1)
1352 snprintf(resp_buf, sizeof(resp_buf), "On");
1353 else
1354 snprintf(resp_buf, sizeof(resp_buf), "Off");
1355 } else {
1356 send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
1357 return 0;
1358 }
1359
1360 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1361 return 0;
1362}
1363
1364
1365int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1366 struct sigma_cmd *cmd)
1367{
1368 const char *action = get_param(cmd, "Action");
1369
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001370 if (!action)
1371 return 0;
1372
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001373 /* Check action for start, stop and get events. */
1374 if (strcasecmp(action, "Start") == 0) {
1375 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1376 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1377 } else if (strcasecmp(action, "Stop") == 0) {
1378 event_anyresponse = 0;
1379 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1380 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1381 } else if (strcasecmp(action, "Get") == 0) {
1382 if (event_anyresponse == 1) {
1383 send_resp(dut, conn, SIGMA_COMPLETE,
1384 global_event_resp_buf);
1385 } else {
1386 send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE");
1387 }
1388 }
1389 return 0;
1390}
Rakesh Sunki4b75f962017-03-30 14:47:55 -07001391
1392#else /* #if NAN_CERT_VERSION */
1393
1394int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
1395 struct sigma_conn *conn,
1396 struct sigma_cmd *cmd)
1397{
1398 return 1;
1399}
1400
1401
1402int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1403 struct sigma_cmd *cmd)
1404{
1405 return 0;
1406
1407}
1408
1409
1410void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1411 struct sigma_cmd *cmd)
1412{
1413 return;
1414}
1415
1416
1417int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1418 struct sigma_cmd *cmd)
1419{
1420 return 0;
1421}
1422
1423
1424int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1425 struct sigma_cmd *cmd)
1426{
1427 return 0;
1428}
1429
1430#endif /* #if NAN_CERT_VERSION */