blob: b524aa2b87d782635d517c0ea7a43f6a7821a4e5 [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;
Rakesh Sunkid51e8982017-03-30 14:47:55 -070021static NanSyncStats global_nan_sync_stats;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020022static int nan_state = 0;
23static int event_anyresponse = 0;
24static int is_fam = 0;
25
Rakesh Sunki4c086672017-03-30 14:47:55 -070026static uint16_t global_ndp_instance_id = 0;
Rakesh Sunki4d5912d2017-03-30 14:47:55 -070027static uint16_t global_publish_id = 0;
28static uint16_t global_subscribe_id = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020029uint16_t global_header_handle = 0;
30uint32_t global_match_handle = 0;
31
32#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
33#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
34#ifndef ETH_ALEN
35#define ETH_ALEN 6
36#endif
37
38struct sigma_dut *global_dut = NULL;
39static char global_nan_mac_addr[ETH_ALEN];
Rakesh Sunki14cfcd22017-03-30 14:47:55 -070040static char global_peer_mac_addr[ETH_ALEN];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020041static char global_event_resp_buf[1024];
42
43static int nan_further_availability_tx(struct sigma_dut *dut,
44 struct sigma_conn *conn,
45 struct sigma_cmd *cmd);
46static int nan_further_availability_rx(struct sigma_dut *dut,
47 struct sigma_conn *conn,
48 struct sigma_cmd *cmd);
49
50
51void nan_hex_dump(struct sigma_dut *dut, uint8_t *data, size_t len)
52{
53 char buf[512];
54 uint16_t index;
55 uint8_t *ptr;
56 int pos;
57
58 memset(buf, 0, sizeof(buf));
59 ptr = data;
60 pos = 0;
61 for (index = 0; index < len; index++) {
62 pos += sprintf(&(buf[pos]), "%02x ", *ptr++);
63 if (pos > 508)
64 break;
65 }
66 sigma_dut_print(dut, DUT_MSG_INFO, "HEXDUMP len=[%d]", (int) len);
67 sigma_dut_print(dut, DUT_MSG_INFO, "buf:%s", buf);
68}
69
70
71int nan_parse_hex(unsigned char c)
72{
73 if (c >= '0' && c <= '9')
74 return c - '0';
75 if (c >= 'a' && c <= 'f')
76 return c - 'a' + 10;
77 if (c >= 'A' && c <= 'F')
78 return c - 'A' + 10;
79 return 0;
80}
81
82
83int nan_parse_token(const char *tokenIn, u8 *tokenOut, int *filterLen)
84{
85 int total_len = 0, len = 0;
86 char *saveptr = NULL;
87
88 tokenIn = strtok_r((char *) tokenIn, ":", &saveptr);
89 while (tokenIn != NULL) {
90 len = strlen(tokenIn);
91 if (len == 1 && *tokenIn == '*')
92 len = 0;
93 tokenOut[total_len++] = (u8) len;
94 if (len != 0)
95 memcpy((u8 *) tokenOut + total_len, tokenIn, len);
96 total_len += len;
97 tokenIn = strtok_r(NULL, ":", &saveptr);
98 }
99 *filterLen = total_len;
100 return 0;
101}
102
103
104int nan_parse_mac_address(struct sigma_dut *dut, const char *arg, u8 *addr)
105{
106 if (strlen(arg) != 17) {
107 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid mac address %s",
108 arg);
109 sigma_dut_print(dut, DUT_MSG_ERROR,
110 "expected format xx:xx:xx:xx:xx:xx");
111 return -1;
112 }
113
114 addr[0] = nan_parse_hex(arg[0]) << 4 | nan_parse_hex(arg[1]);
115 addr[1] = nan_parse_hex(arg[3]) << 4 | nan_parse_hex(arg[4]);
116 addr[2] = nan_parse_hex(arg[6]) << 4 | nan_parse_hex(arg[7]);
117 addr[3] = nan_parse_hex(arg[9]) << 4 | nan_parse_hex(arg[10]);
118 addr[4] = nan_parse_hex(arg[12]) << 4 | nan_parse_hex(arg[13]);
119 addr[5] = nan_parse_hex(arg[15]) << 4 | nan_parse_hex(arg[16]);
120
121 return 0;
122}
123
124
125int nan_parse_mac_address_list(struct sigma_dut *dut, const char *input,
126 u8 *output, u16 max_addr_allowed)
127{
128 /*
129 * Reads a list of mac address separated by space. Each MAC address
130 * should have the format of aa:bb:cc:dd:ee:ff.
131 */
132 char *saveptr;
133 char *token;
134 int i = 0;
135
136 for (i = 0; i < max_addr_allowed; i++) {
137 token = strtok_r((i == 0) ? (char *) input : NULL,
138 " ", &saveptr);
139 if (token) {
140 nan_parse_mac_address(dut, token, output);
141 output += NAN_MAC_ADDR_LEN;
142 } else
143 break;
144 }
145
146 sigma_dut_print(dut, DUT_MSG_INFO, "Num MacAddress:%d", i);
147
148 return i;
149}
150
151
152int nan_parse_hex_string(struct sigma_dut *dut, const char *input,
153 u8 *output, int *outputlen)
154{
155 int i = 0;
156 int j = 0;
157
158 for (i = 0; i < (int) strlen(input) && j < *outputlen; i += 2) {
159 output[j] = nan_parse_hex(input[i]);
160 if (i + 1 < (int) strlen(input)) {
161 output[j] = ((output[j] << 4) |
162 nan_parse_hex(input[i + 1]));
163 }
164 j++;
165 }
166 *outputlen = j;
167 sigma_dut_print(dut, DUT_MSG_INFO, "Input:%s inputlen:%d outputlen:%d",
168 input, (int) strlen(input), (int) *outputlen);
169 return 0;
170}
171
172
173int wait(struct timespec abstime)
174{
175 struct timeval now;
176
177 gettimeofday(&now, NULL);
178
179 abstime.tv_sec += now.tv_sec;
180 if (((abstime.tv_nsec + now.tv_usec * 1000) > 1000 * 1000 * 1000) ||
181 (abstime.tv_nsec + now.tv_usec * 1000 < 0)) {
182 abstime.tv_sec += 1;
183 abstime.tv_nsec += now.tv_usec * 1000;
184 abstime.tv_nsec -= 1000 * 1000 * 1000;
185 } else {
186 abstime.tv_nsec += now.tv_usec * 1000;
187 }
188
189 return pthread_cond_timedwait(&gCondition, &gMutex, &abstime);
190}
191
192
193int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
194 struct sigma_conn *conn,
195 struct sigma_cmd *cmd)
196{
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700197 const char *oper_chan = get_param(cmd, "oper_chn");
Rakesh Sunki7d37f412017-03-30 14:47:55 -0700198 const char *pmk = get_param(cmd, "PMK");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200199
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700200 if (oper_chan) {
201 sigma_dut_print(dut, DUT_MSG_INFO, "Operating Channel: %s",
202 oper_chan);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700203 dut->sta_channel = atoi(oper_chan);
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700204 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200205
Rakesh Sunki7d37f412017-03-30 14:47:55 -0700206 if (pmk) {
207 int pmk_len;
208
209 sigma_dut_print(dut, DUT_MSG_INFO, "%s given string pmk: %s",
210 __func__, pmk);
211 memset(dut->nan_pmk, 0, NAN_PMK_INFO_LEN);
212 dut->nan_pmk_len = 0;
213 pmk_len = NAN_PMK_INFO_LEN;
214 nan_parse_hex_string(dut, &pmk[2], &dut->nan_pmk[0], &pmk_len);
215 dut->nan_pmk_len = pmk_len;
216 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
217 __func__, dut->nan_pmk_len);
218 sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex pmk", __func__);
219 nan_hex_dump(dut, &dut->nan_pmk[0], dut->nan_pmk_len);
220 }
221
Rakesh Sunki14bff1d2017-03-30 14:47:55 -0700222 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200223 return 0;
224}
225
226
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700227void nan_print_further_availability_chan(struct sigma_dut *dut,
228 u8 num_chans,
229 NanFurtherAvailabilityChannel *fachan)
230{
231 int idx;
232
233 sigma_dut_print(dut, DUT_MSG_INFO,
234 "********Printing FurtherAvailabilityChan Info******");
235 sigma_dut_print(dut, DUT_MSG_INFO, "Numchans:%d", num_chans);
236 for (idx = 0; idx < num_chans; idx++) {
237 sigma_dut_print(dut, DUT_MSG_INFO,
238 "[%d]: NanAvailDuration:%d class_val:%02x channel:%d",
239 idx, fachan->entry_control,
240 fachan->class_val, fachan->channel);
241 sigma_dut_print(dut, DUT_MSG_INFO,
242 "[%d]: mapid:%d Availability bitmap:%08x",
243 idx, fachan->mapid,
244 fachan->avail_interval_bitmap);
245 }
246 sigma_dut_print(dut, DUT_MSG_INFO,
247 "*********************Done**********************");
248}
249
250
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200251int sigma_nan_enable(struct sigma_dut *dut, struct sigma_conn *conn,
252 struct sigma_cmd *cmd)
253{
254 const char *master_pref = get_param(cmd, "MasterPref");
255 const char *rand_fac = get_param(cmd, "RandFactor");
256 const char *hop_count = get_param(cmd, "HopCount");
257 const char *high_tsf = get_param(cmd, "HighTSF");
258 const char *sdftx_band = get_param(cmd, "SDFTxBand");
259 const char *oper_chan = get_param(cmd, "oper_chn");
260 const char *further_avail_ind = get_param(cmd, "FurtherAvailInd");
261 const char *band = get_param(cmd, "Band");
262 const char *only_5g = get_param(cmd, "5GOnly");
Rakesh Sunki38dd72e2017-03-30 14:47:55 -0700263 const char *nan_availability = get_param(cmd, "NANAvailability");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200264 struct timespec abstime;
265 NanEnableRequest req;
266
267 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200268 req.cluster_low = 0;
269 req.cluster_high = 0xFFFF;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700270 req.master_pref = 100;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200271
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700272 /* This is a debug hack to beacon in channel 11 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200273 if (oper_chan) {
274 req.config_2dot4g_support = 1;
275 req.support_2dot4g_val = 111;
276 }
277
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200278 if (master_pref) {
279 int master_pref_val = strtoul(master_pref, NULL, 0);
280
281 req.master_pref = master_pref_val;
282 }
283
284 if (rand_fac) {
285 int rand_fac_val = strtoul(rand_fac, NULL, 0);
286
287 req.config_random_factor_force = 1;
288 req.random_factor_force_val = rand_fac_val;
289 }
290
291 if (hop_count) {
292 int hop_count_val = strtoul(hop_count, NULL, 0);
293
294 req.config_hop_count_force = 1;
295 req.hop_count_force_val = hop_count_val;
296 }
297
298 if (sdftx_band) {
299 if (strcasecmp(sdftx_band, "5G") == 0) {
300 req.config_2dot4g_support = 1;
301 req.support_2dot4g_val = 0;
302 }
303 }
304
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700305 sigma_dut_print(dut, DUT_MSG_INFO,
306 "%s: Setting dual band 2.4 GHz and 5 GHz by default",
307 __func__);
308 /* Enable 2.4 GHz support */
309 req.config_2dot4g_support = 1;
310 req.support_2dot4g_val = 1;
311 req.config_2dot4g_beacons = 1;
312 req.beacon_2dot4g_val = 1;
313 req.config_2dot4g_sdf = 1;
314 req.sdf_2dot4g_val = 1;
315
316 /* Enable 5 GHz support */
317 req.config_support_5g = 1;
318 req.support_5g_val = 1;
319 req.config_5g_beacons = 1;
320 req.beacon_5g_val = 1;
321 req.config_5g_sdf = 1;
322 req.sdf_5g_val = 1;
323
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200324 if (band) {
325 if (strcasecmp(band, "24G") == 0) {
326 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700327 "Band 2.4 GHz selected, disable 5 GHz");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200328 /* Disable 5G support */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700329 req.config_support_5g = 1;
330 req.support_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200331 req.config_5g_beacons = 1;
332 req.beacon_5g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700333 req.config_5g_sdf = 1;
334 req.sdf_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200335 }
336 }
337
338 if (further_avail_ind) {
339 sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled");
340 if (strcasecmp(further_avail_ind, "tx") == 0) {
341 is_fam = 1;
342 nan_further_availability_tx(dut, conn, cmd);
343 return 0;
344 } else if (strcasecmp(further_avail_ind, "rx") == 0) {
345 nan_further_availability_rx(dut, conn, cmd);
346 return 0;
347 }
348 }
349
350 if (only_5g && atoi(only_5g)) {
351 sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled");
352 req.config_2dot4g_support = 1;
353 req.support_2dot4g_val = 1;
354 req.config_2dot4g_beacons = 1;
355 req.beacon_2dot4g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700356 req.config_2dot4g_sdf = 1;
357 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200358 }
359
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700360 nan_enable_request(0, global_interface_handle, &req);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700361
Rakesh Sunki38dd72e2017-03-30 14:47:55 -0700362 if (nan_availability) {
363 int cmd_len, size;
364 NanDebugParams cfg_debug;
365
366 sigma_dut_print(dut, DUT_MSG_INFO,
367 "%s given string nan_availability: %s",
368 __func__, nan_availability);
369 memset(&cfg_debug, 0, sizeof(NanDebugParams));
370 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY;
371 size = NAN_MAX_DEBUG_MESSAGE_DATA_LEN;
372 nan_parse_hex_string(dut, &nan_availability[2],
373 &cfg_debug.debug_cmd_data[0], &size);
374 sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex nan_availability",
375 __func__);
376 nan_hex_dump(dut, &cfg_debug.debug_cmd_data[0], size);
377 cmd_len = size + sizeof(u32);
378 nan_debug_command_config(0, global_interface_handle,
379 cfg_debug, cmd_len);
380 }
381
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700382 /* To ensure sta_get_events to get the events
383 * only after joining the NAN cluster. */
384 abstime.tv_sec = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200385 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700386 wait(abstime);
387
388 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200389}
390
391
392int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn,
393 struct sigma_cmd *cmd)
394{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200395 struct timespec abstime;
396
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700397 nan_disable_request(0, global_interface_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200398
399 abstime.tv_sec = 4;
400 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700401 wait(abstime);
402
403 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200404}
405
406
407int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn,
408 struct sigma_cmd *cmd)
409{
410 const char *master_pref = get_param(cmd, "MasterPref");
411 const char *rand_fac = get_param(cmd, "RandFactor");
412 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700413 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200414 struct timespec abstime;
415 NanConfigRequest req;
416
417 memset(&req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200418 req.config_rssi_proximity = 1;
419 req.rssi_proximity = 70;
420
421 if (master_pref) {
422 int master_pref_val = strtoul(master_pref, NULL, 0);
423
424 req.config_master_pref = 1;
425 req.master_pref = master_pref_val;
426 }
427
428 if (rand_fac) {
429 int rand_fac_val = strtoul(rand_fac, NULL, 0);
430
431 req.config_random_factor_force = 1;
432 req.random_factor_force_val = rand_fac_val;
433 }
434
435 if (hop_count) {
436 int hop_count_val = strtoul(hop_count, NULL, 0);
437
438 req.config_hop_count_force = 1;
439 req.hop_count_force_val = hop_count_val;
440 }
441
Rakesh Sunki107356c2017-03-30 14:47:55 -0700442 ret = nan_config_request(0, global_interface_handle, &req);
443 if (ret != WIFI_SUCCESS)
444 send_resp(dut, conn, SIGMA_ERROR, "NAN config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200445
446 abstime.tv_sec = 4;
447 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700448 wait(abstime);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200449
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700450 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200451}
452
453
454static int sigma_nan_subscribe_request(struct sigma_dut *dut,
455 struct sigma_conn *conn,
456 struct sigma_cmd *cmd)
457{
458 const char *subscribe_type = get_param(cmd, "SubscribeType");
459 const char *service_name = get_param(cmd, "ServiceName");
460 const char *disc_range = get_param(cmd, "DiscoveryRange");
461 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
462 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
463 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
464 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
465 const char *include_bit = get_param(cmd, "IncludeBit");
466 const char *mac = get_param(cmd, "MAC");
467 const char *srf_type = get_param(cmd, "SRFType");
468 NanSubscribeRequest req;
469 int filter_len_rx = 0, filter_len_tx = 0;
470 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
471 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700472 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200473
474 memset(&req, 0, sizeof(NanSubscribeRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200475 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -0700476 req.period = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200477 req.subscribe_type = 1;
478 req.serviceResponseFilter = 1; /* MAC */
479 req.serviceResponseInclude = 0;
480 req.ssiRequiredForMatchIndication = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700481 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200482 req.subscribe_count = 0;
483
484 if (subscribe_type) {
485 if (strcasecmp(subscribe_type, "Active") == 0) {
486 req.subscribe_type = 1;
487 } else if (strcasecmp(subscribe_type, "Passive") == 0) {
488 req.subscribe_type = 0;
489 } else if (strcasecmp(subscribe_type, "Cancel") == 0) {
490 NanSubscribeCancelRequest req;
491
492 memset(&req, 0, sizeof(NanSubscribeCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700493 ret = nan_subscribe_cancel_request(
494 0, global_interface_handle, &req);
495 if (ret != WIFI_SUCCESS) {
496 send_resp(dut, conn, SIGMA_ERROR,
497 "NAN subscribe cancel request failed");
498 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200499 return 0;
500 }
501 }
502
503 if (disc_range)
504 req.rssi_threshold_flag = atoi(disc_range);
505
506 if (sdftx_dw)
507 req.subscribe_count = atoi(sdftx_dw);
508
509 /* Check this once again if config can be called here (TBD) */
510 if (discrange_ltd)
511 req.rssi_threshold_flag = atoi(discrange_ltd);
512
513 if (include_bit) {
514 int include_bit_val = atoi(include_bit);
515
516 req.serviceResponseInclude = include_bit_val;
517 sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d",
518 req.serviceResponseInclude);
519 }
520
521 if (srf_type) {
522 int srf_type_val = atoi(srf_type);
523
524 if (srf_type_val == 1)
525 req.serviceResponseFilter = 0; /* Bloom */
526 else
527 req.serviceResponseFilter = 1; /* MAC */
528 req.useServiceResponseFilter = 1;
529 sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d",
530 req.serviceResponseFilter);
531 }
532
533 if (mac) {
534 sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac);
535 req.num_intf_addr_present = nan_parse_mac_address_list(
536 dut, mac, &req.intf_addr[0][0],
537 NAN_MAX_SUBSCRIBE_MAX_ADDRESS);
538 }
539
540 memset(input_rx, 0, sizeof(input_rx));
541 memset(input_tx, 0, sizeof(input_tx));
542 if (rx_match_filter) {
543 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
544 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
545 filter_len_rx);
546 }
547 if (tx_match_filter) {
548 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
549 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
550 filter_len_tx);
551 }
552
553 if (tx_match_filter) {
554 req.tx_match_filter_len = filter_len_tx;
555 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
556 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
557 }
558 if (rx_match_filter) {
559 req.rx_match_filter_len = filter_len_rx;
560 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
561 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
562 }
563
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700564 if (service_name) {
565 strlcpy((char *) req.service_name, service_name,
566 strlen(service_name) + 1);
567 req.service_name_len = strlen(service_name);
568 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200569
Rakesh Sunki107356c2017-03-30 14:47:55 -0700570 ret = nan_subscribe_request(0, global_interface_handle, &req);
571 if (ret != WIFI_SUCCESS) {
572 send_resp(dut, conn, SIGMA_ERROR,
573 "NAN subscribe request failed");
574 }
575
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200576 return 0;
577}
578
579
Rakesh Sunkid7344c02017-03-30 14:47:55 -0700580static int sigma_ndp_configure_band(struct sigma_dut *dut,
581 struct sigma_conn *conn,
582 struct sigma_cmd *cmd,
583 NdpSupportedBand band_config_val)
584{
585 wifi_error ret;
586 NanDebugParams cfg_debug;
587 int size;
588
589 memset(&cfg_debug, 0, sizeof(NanDebugParams));
590 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS;
591 memcpy(cfg_debug.debug_cmd_data, &band_config_val, sizeof(int));
592 sigma_dut_print(dut, DUT_MSG_INFO, "%s:setting debug cmd=0x%x",
593 __func__, cfg_debug.cmd);
594 size = sizeof(u32) + sizeof(int);
595 ret = nan_debug_command_config(0, global_interface_handle, cfg_debug,
596 size);
597 if (ret != WIFI_SUCCESS)
598 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
599
600 return 0;
601}
602
603
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700604static int sigma_nan_data_request(struct sigma_dut *dut,
605 struct sigma_conn *conn,
606 struct sigma_cmd *cmd)
607{
608 const char *ndp_security = get_param(cmd, "DataPathSecurity");
609 const char *ndp_resp_mac = get_param(cmd, "RespNanMac");
610 const char *include_immutable = get_param(cmd, "includeimmutable");
611 const char *avoid_channel = get_param(cmd, "avoidchannel");
612 const char *invalid_nan_schedule = get_param(cmd, "InvalidNANSchedule");
613 const char *map_order = get_param(cmd, "maporder");
614 wifi_error ret;
615 NanDataPathInitiatorRequest init_req;
616 NanDebugParams cfg_debug;
617 int size;
618
619 memset(&init_req, 0, sizeof(NanDataPathInitiatorRequest));
620
621 if (ndp_security) {
622 if (strcasecmp(ndp_security, "open") == 0)
623 init_req.ndp_cfg.security_cfg =
624 NAN_DP_CONFIG_NO_SECURITY;
625 else if (strcasecmp(ndp_security, "secure") == 0)
626 init_req.ndp_cfg.security_cfg = NAN_DP_CONFIG_SECURITY;
627 }
628
629 if (include_immutable) {
630 int include_immutable_val = 0;
631
632 memset(&cfg_debug, 0, sizeof(NanDebugParams));
633 cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE;
634 include_immutable_val = atoi(include_immutable);
635 memcpy(cfg_debug.debug_cmd_data, &include_immutable_val,
636 sizeof(int));
637 size = sizeof(u32) + sizeof(int);
638 nan_debug_command_config(0, global_interface_handle,
639 cfg_debug, size);
640 }
641
642 if (avoid_channel) {
643 int avoid_channel_freq = 0;
644
645 memset(&cfg_debug, 0, sizeof(NanDebugParams));
646 avoid_channel_freq = channel_to_freq(atoi(avoid_channel));
647 cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL;
648 memcpy(cfg_debug.debug_cmd_data, &avoid_channel_freq,
649 sizeof(int));
650 size = sizeof(u32) + sizeof(int);
651 nan_debug_command_config(0, global_interface_handle,
652 cfg_debug, size);
653 }
654
655 if (invalid_nan_schedule) {
656 int invalid_nan_schedule_type = 0;
657
658 memset(&cfg_debug, 0, sizeof(NanDebugParams));
659 invalid_nan_schedule_type = atoi(invalid_nan_schedule);
660 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_TYPE;
661 memcpy(cfg_debug.debug_cmd_data,
662 &invalid_nan_schedule_type, sizeof(int));
663 size = sizeof(u32) + sizeof(int);
664 sigma_dut_print(dut, DUT_MSG_INFO,
665 "%s: invalid schedule type: cmd type = %d and command data = %d",
666 __func__, cfg_debug.cmd,
667 invalid_nan_schedule_type);
668 nan_debug_command_config(0, global_interface_handle,
669 cfg_debug, size);
670 }
671
672 if (map_order) {
673 int map_order_val = 0;
674
675 memset(&cfg_debug, 0, sizeof(NanDebugParams));
676 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER;
677 map_order_val = atoi(map_order);
678 memcpy(cfg_debug.debug_cmd_data, &map_order_val, sizeof(int));
679 size = sizeof(u32) + sizeof(int);
680 sigma_dut_print(dut, DUT_MSG_INFO,
681 "%s: map order: cmd type = %d and command data = %d",
682 __func__,
683 cfg_debug.cmd, invalid_nan_schedule_type);
684 nan_debug_command_config(0, global_interface_handle,
685 cfg_debug, size);
686 }
687
688 /*
689 * Setting this flag, so that interface for ping6 command
690 * is set appropriately in traffic_send_ping().
691 */
692 dut->ndp_enable = 1;
693
694 /*
695 * Intended sleep after NAN data interface create
696 * before the NAN data request
697 */
698 sleep(4);
699
700 init_req.requestor_instance_id = global_match_handle;
701 strlcpy((char *) init_req.ndp_iface, "nan0",
702 sizeof(init_req.ndp_iface));
703
704 if (ndp_resp_mac) {
705 nan_parse_mac_address(dut, ndp_resp_mac,
706 init_req.peer_disc_mac_addr);
707 sigma_dut_print(
708 dut, DUT_MSG_INFO, "PEER MAC ADDR: " MAC_ADDR_STR,
709 MAC_ADDR_ARRAY(init_req.peer_disc_mac_addr));
710 } else {
711 memcpy(init_req.peer_disc_mac_addr, global_peer_mac_addr,
712 sizeof(init_req.peer_disc_mac_addr));
713 }
714
715 /* Not requesting the channel and letting FW decide */
716 if (dut->sta_channel == 0) {
717 init_req.channel_request_type = NAN_DP_CHANNEL_NOT_REQUESTED;
718 init_req.channel = 0;
719 } else {
720 init_req.channel_request_type = NAN_DP_FORCE_CHANNEL_SETUP;
721 init_req.channel = channel_to_freq(dut->sta_channel);
722 }
723 sigma_dut_print(dut, DUT_MSG_INFO,
724 "%s: Initiator Request: Channel = %d Channel Request Type = %d",
725 __func__, init_req.channel,
726 init_req.channel_request_type);
727
728 if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) {
729 memcpy(&init_req.key_info.body.pmk_info.pmk[0],
730 &dut->nan_pmk[0], NAN_PMK_INFO_LEN);
731 init_req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
732 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
733 __func__,
734 init_req.key_info.body.pmk_info.pmk_len);
735 }
736
737 ret = nan_data_request_initiator(0, global_interface_handle, &init_req);
738 if (ret != WIFI_SUCCESS) {
739 send_resp(dut, conn, SIGMA_ERROR,
740 "Unable to initiate nan data request");
741 return 0;
742 }
743
744 return 0;
745}
746
747
Rakesh Sunkia5cc2842017-03-30 14:47:55 -0700748static int sigma_nan_data_response(struct sigma_dut *dut,
749 struct sigma_conn *conn,
750 struct sigma_cmd *cmd)
751{
752 const char *ndl_response = get_param(cmd, "NDLresponse");
753 const char *m4_response_type = get_param(cmd, "M4ResponseType");
754 wifi_error ret;
755 NanDebugParams cfg_debug;
756 int size;
757
758 if (ndl_response) {
759 int auto_responder_mode_val = 0;
760
761 sigma_dut_print(dut, DUT_MSG_INFO,
762 "%s: ndl_response = (%s) is passed",
763 __func__, ndl_response);
764 memset(&cfg_debug, 0, sizeof(NanDebugParams));
765 cfg_debug.cmd = NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE;
766 if (strcasecmp(ndl_response, "Auto") == 0) {
767 auto_responder_mode_val = NAN_DATA_RESPONDER_MODE_AUTO;
768 } else if (strcasecmp(ndl_response, "Reject") == 0) {
769 auto_responder_mode_val =
770 NAN_DATA_RESPONDER_MODE_REJECT;
771 } else if (strcasecmp(ndl_response, "Accept") == 0) {
772 auto_responder_mode_val =
773 NAN_DATA_RESPONDER_MODE_ACCEPT;
774 } else if (strcasecmp(ndl_response, "Counter") == 0) {
775 auto_responder_mode_val =
776 NAN_DATA_RESPONDER_MODE_COUNTER;
777 } else {
778 sigma_dut_print(dut, DUT_MSG_ERROR,
779 "%s: Invalid ndl_response",
780 __func__);
781 return 0;
782 }
783 memcpy(cfg_debug.debug_cmd_data, &auto_responder_mode_val,
784 sizeof(int));
785 size = sizeof(u32) + sizeof(int);
786 ret = nan_debug_command_config(0, global_interface_handle,
787 cfg_debug, size);
788 if (ret != WIFI_SUCCESS) {
789 send_resp(dut, conn, SIGMA_ERROR,
790 "Nan config request failed");
791 }
792 }
793
794 if (m4_response_type) {
795 int m4_response_type_val = 0;
796
797 sigma_dut_print(dut, DUT_MSG_INFO,
798 "%s: m4_response_type = (%s) is passed",
799 __func__, m4_response_type);
800 memset(&cfg_debug, 0, sizeof(NanDebugParams));
801 cfg_debug.cmd = NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE;
802 if (strcasecmp(m4_response_type, "Accept") == 0)
803 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_ACCEPT;
804 else if (strcasecmp(m4_response_type, "Reject") == 0)
805 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_REJECT;
806 else if (strcasecmp(m4_response_type, "BadMic") == 0)
807 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_BADMIC;
808
809 memcpy(cfg_debug.debug_cmd_data, &m4_response_type_val,
810 sizeof(int));
811 size = sizeof(u32) + sizeof(int);
812 ret = nan_debug_command_config(0, global_interface_handle,
813 cfg_debug, size);
814 if (ret != WIFI_SUCCESS) {
815 send_resp(dut, conn, SIGMA_ERROR,
816 "Nan config request failed");
817 }
818 }
819
820 return 0;
821}
822
823
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200824int config_post_disc_attr(void)
825{
Rakesh Sunki107356c2017-03-30 14:47:55 -0700826 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200827 NanConfigRequest configReq;
828
829 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200830
831 /* Configure Post disc attr */
832 /* Make these defines and use correct enum */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700833 configReq.num_config_discovery_attr = 1;
834 configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */
835 configReq.discovery_attr_val[0].role = 0;
836 configReq.discovery_attr_val[0].transmit_freq = 1;
837 configReq.discovery_attr_val[0].duration = 0;
838 configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200839
Rakesh Sunki107356c2017-03-30 14:47:55 -0700840 ret = nan_config_request(0, global_interface_handle, &configReq);
841 if (ret != WIFI_SUCCESS) {
842 sigma_dut_print(global_dut, DUT_MSG_INFO,
843 "NAN config request failed while configuring post discovery attribute");
844 }
845
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200846 return 0;
847}
848
849
850int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn,
851 struct sigma_cmd *cmd)
852{
853 const char *publish_type = get_param(cmd, "PublishType");
854 const char *service_name = get_param(cmd, "ServiceName");
855 const char *disc_range = get_param(cmd, "DiscoveryRange");
856 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
857 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
858 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
859 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
860 NanPublishRequest req;
861 int filter_len_rx = 0, filter_len_tx = 0;
862 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
863 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700864 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200865
866 memset(&req, 0, sizeof(NanPublishRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200867 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -0700868 req.period = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700869 req.publish_match_indicator = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200870 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
871 req.tx_type = NAN_TX_TYPE_BROADCAST;
872 req.publish_count = 0;
Rakesh Sunki0a0eea82017-03-30 14:47:55 -0700873 req.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_ALL;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700874
875 if (service_name) {
876 strlcpy((char *) req.service_name, service_name,
877 strlen(service_name) + 1);
878 req.service_name_len = strlen(service_name);
879 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200880
881 if (publish_type) {
882 if (strcasecmp(publish_type, "Solicited") == 0) {
883 req.publish_type = NAN_PUBLISH_TYPE_SOLICITED;
884 } else if (strcasecmp(publish_type, "Cancel") == 0) {
885 NanPublishCancelRequest req;
886
887 memset(&req, 0, sizeof(NanPublishCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700888 ret = nan_publish_cancel_request(
889 0, global_interface_handle, &req);
890 if (ret != WIFI_SUCCESS) {
891 send_resp(dut, conn, SIGMA_ERROR,
892 "Unable to cancel nan publish request");
893 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200894 return 0;
895 }
896 }
897
898 if (disc_range)
899 req.rssi_threshold_flag = atoi(disc_range);
900
901 if (sdftx_dw)
902 req.publish_count = atoi(sdftx_dw);
903
904 if (discrange_ltd)
905 req.rssi_threshold_flag = atoi(discrange_ltd);
906
907 memset(input_rx, 0, sizeof(input_rx));
908 memset(input_tx, 0, sizeof(input_tx));
909 if (rx_match_filter) {
910 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
911 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
912 filter_len_rx);
913 }
914 if (tx_match_filter) {
915 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
916 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
917 filter_len_tx);
918 }
919
920 if (is_fam == 1) {
921 config_post_disc_attr();
922 /* TODO: Add comments regarding this step */
923 req.connmap = 0x10;
924 }
925
926 if (tx_match_filter) {
927 req.tx_match_filter_len = filter_len_tx;
928 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
929 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
930 }
931
932 if (rx_match_filter) {
933 req.rx_match_filter_len = filter_len_rx;
934 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
935 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
936 }
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700937
938 if (service_name) {
939 strlcpy((char *) req.service_name, service_name,
940 strlen(service_name) + 1);
941 req.service_name_len = strlen(service_name);
942 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200943
Rakesh Sunki107356c2017-03-30 14:47:55 -0700944 ret = nan_publish_request(0, global_interface_handle, &req);
945 if (ret != WIFI_SUCCESS)
946 send_resp(dut, conn, SIGMA_ERROR, "Unable to publish");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200947
948 return 0;
949}
950
951
952static int nan_further_availability_rx(struct sigma_dut *dut,
953 struct sigma_conn *conn,
954 struct sigma_cmd *cmd)
955{
956 const char *master_pref = get_param(cmd, "MasterPref");
957 const char *rand_fac = get_param(cmd, "RandFactor");
958 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700959 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200960 struct timespec abstime;
961
962 NanEnableRequest req;
963
964 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200965 req.cluster_low = 0;
966 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200967 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200968
969 if (master_pref)
970 req.master_pref = strtoul(master_pref, NULL, 0);
971
972 if (rand_fac) {
973 int rand_fac_val = strtoul(rand_fac, NULL, 0);
974
975 req.config_random_factor_force = 1;
976 req.random_factor_force_val = rand_fac_val;
977 }
978
979 if (hop_count) {
980 int hop_count_val = strtoul(hop_count, NULL, 0);
981
982 req.config_hop_count_force = 1;
983 req.hop_count_force_val = hop_count_val;
984 }
985
Rakesh Sunki107356c2017-03-30 14:47:55 -0700986 ret = nan_enable_request(0, global_interface_handle, &req);
987 if (ret != WIFI_SUCCESS) {
988 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
989 return 0;
990 }
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700991
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200992 abstime.tv_sec = 4;
993 abstime.tv_nsec = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200994 wait(abstime);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700995
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200996 return 0;
997}
998
999
1000static int nan_further_availability_tx(struct sigma_dut *dut,
1001 struct sigma_conn *conn,
1002 struct sigma_cmd *cmd)
1003{
1004 const char *master_pref = get_param(cmd, "MasterPref");
1005 const char *rand_fac = get_param(cmd, "RandFactor");
1006 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001007 wifi_error ret;
1008
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001009 NanEnableRequest req;
1010 NanConfigRequest configReq;
1011
1012 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001013 req.cluster_low = 0;
1014 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001015 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001016
1017 if (master_pref)
1018 req.master_pref = strtoul(master_pref, NULL, 0);
1019
1020 if (rand_fac) {
1021 int rand_fac_val = strtoul(rand_fac, NULL, 0);
1022
1023 req.config_random_factor_force = 1;
1024 req.random_factor_force_val = rand_fac_val;
1025 }
1026
1027 if (hop_count) {
1028 int hop_count_val = strtoul(hop_count, NULL, 0);
1029
1030 req.config_hop_count_force = 1;
1031 req.hop_count_force_val = hop_count_val;
1032 }
1033
Rakesh Sunki107356c2017-03-30 14:47:55 -07001034 ret = nan_enable_request(0, global_interface_handle, &req);
1035 if (ret != WIFI_SUCCESS) {
1036 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
1037 return 0;
1038 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001039
1040 /* Start the config of fam */
1041
1042 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001043
1044 configReq.config_fam = 1;
1045 configReq.fam_val.numchans = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001046 configReq.fam_val.famchan[0].entry_control = 0;
1047 configReq.fam_val.famchan[0].class_val = 81;
1048 configReq.fam_val.famchan[0].channel = 6;
1049 configReq.fam_val.famchan[0].mapid = 0;
1050 configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe;
1051
Rakesh Sunki107356c2017-03-30 14:47:55 -07001052 ret = nan_config_request(0, global_interface_handle, &configReq);
1053 if (ret != WIFI_SUCCESS)
1054 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001055
1056 return 0;
1057}
1058
1059
1060int sigma_nan_transmit_followup(struct sigma_dut *dut,
1061 struct sigma_conn *conn,
1062 struct sigma_cmd *cmd)
1063{
1064 const char *mac = get_param(cmd, "mac");
1065 const char *requestor_id = get_param(cmd, "RemoteInstanceId");
1066 const char *local_id = get_param(cmd, "LocalInstanceId");
1067 const char *service_name = get_param(cmd, "servicename");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001068 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001069 NanTransmitFollowupRequest req;
1070
1071 memset(&req, 0, sizeof(NanTransmitFollowupRequest));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001072 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001073 req.addr[0] = 0xFF;
1074 req.addr[1] = 0xFF;
1075 req.addr[2] = 0xFF;
1076 req.addr[3] = 0xFF;
1077 req.addr[4] = 0xFF;
1078 req.addr[5] = 0xFF;
1079 req.priority = NAN_TX_PRIORITY_NORMAL;
1080 req.dw_or_faw = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001081
1082 if (service_name)
1083 req.service_specific_info_len = strlen(service_name);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001084
1085 if (requestor_id) {
1086 /* int requestor_id_val = atoi(requestor_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001087 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001088 }
1089 if (local_id) {
1090 /* int local_id_val = atoi(local_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001091 req.publish_subscribe_id = global_header_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001092 }
1093
1094 if (mac == NULL) {
1095 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address");
1096 return -1;
1097 }
1098 nan_parse_mac_address(dut, mac, req.addr);
1099
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001100 if (requestor_id)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001101 req.requestor_instance_id = strtoul(requestor_id, NULL, 0);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001102
Rakesh Sunki107356c2017-03-30 14:47:55 -07001103 ret = nan_transmit_followup_request(0, global_interface_handle, &req);
1104 if (ret != WIFI_SUCCESS) {
1105 send_resp(dut, conn, SIGMA_ERROR,
1106 "Unable to complete nan transmit followup");
1107 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001108
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001109 return 0;
1110}
1111
Rakesh Sunki107356c2017-03-30 14:47:55 -07001112
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001113/* NotifyResponse invoked to notify the status of the Request */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001114void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001115{
1116 sigma_dut_print(global_dut, DUT_MSG_INFO,
Rakesh Sunkifdbd60b2017-03-30 14:47:55 -07001117 "%s: status %d response_type %d",
1118 __func__, rsp_data->status, rsp_data->response_type);
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001119 if (rsp_data->response_type == NAN_RESPONSE_STATS &&
1120 rsp_data->body.stats_response.stats_type ==
1121 NAN_STATS_ID_DE_TIMING_SYNC) {
1122 NanSyncStats *pSyncStats;
1123
1124 sigma_dut_print(global_dut, DUT_MSG_INFO,
1125 "%s: stats_type %d", __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001126 rsp_data->body.stats_response.stats_type);
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001127 pSyncStats = &rsp_data->body.stats_response.data.sync_stats;
1128 memcpy(&global_nan_sync_stats, pSyncStats,
1129 sizeof(NanSyncStats));
1130 pthread_cond_signal(&gCondition);
Rakesh Sunki4d5912d2017-03-30 14:47:55 -07001131 } else if (rsp_data->response_type == NAN_RESPONSE_PUBLISH) {
1132 sigma_dut_print(global_dut, DUT_MSG_INFO,
1133 "%s: publish_id %d\n",
1134 __func__,
1135 rsp_data->body.publish_response.publish_id);
1136 global_publish_id = rsp_data->body.publish_response.publish_id;
1137 } else if (rsp_data->response_type == NAN_RESPONSE_SUBSCRIBE) {
1138 sigma_dut_print(global_dut, DUT_MSG_INFO,
1139 "%s: subscribe_id %d\n",
1140 __func__,
1141 rsp_data->body.subscribe_response.subscribe_id);
1142 global_subscribe_id =
1143 rsp_data->body.subscribe_response.subscribe_id;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001144 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001145}
1146
1147
1148/* Events Callback */
1149void nan_event_publish_replied(NanPublishRepliedInd *event)
1150{
1151 sigma_dut_print(global_dut, DUT_MSG_INFO,
1152 "%s: handle %d " MAC_ADDR_STR " rssi:%d",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001153 __func__, event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001154 MAC_ADDR_ARRAY(event->addr), event->rssi_value);
1155 event_anyresponse = 1;
1156 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001157 "EventName,Replied,RemoteInstanceID %d,mac," MAC_ADDR_STR,
1158 (event->requestor_instance_id >> 24),
1159 MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001160}
1161
1162
1163/* Events Callback */
1164void nan_event_publish_terminated(NanPublishTerminatedInd *event)
1165{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001166 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d",
1167 __func__, event->publish_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001168}
1169
1170
1171/* Events Callback */
1172void nan_event_match(NanMatchInd *event)
1173{
1174 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001175 "%s: Pub/Sub Id %d remote_requestor_id %08x "
1176 MAC_ADDR_STR
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001177 " rssi:%d",
1178 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001179 event->publish_subscribe_id,
1180 event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001181 MAC_ADDR_ARRAY(event->addr),
1182 event->rssi_value);
1183 event_anyresponse = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001184 global_header_handle = event->publish_subscribe_id;
1185 global_match_handle = event->requestor_instance_id;
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07001186 memcpy(global_peer_mac_addr, event->addr, sizeof(global_peer_mac_addr));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001187
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001188 /* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */
1189 /* global_pub_sub_handle = event->header.handle; */
1190 /* Print the SSI */
1191 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001192 nan_hex_dump(global_dut, event->service_specific_info,
1193 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001194 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1195 "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001196 MAC_ADDR_STR " ", (event->requestor_instance_id >> 24),
1197 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001198
1199 /* Print the match filter */
1200 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001201 nan_hex_dump(global_dut, event->sdf_match_filter,
1202 event->sdf_match_filter_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001203
1204 /* Print the conn_capability */
1205 sigma_dut_print(global_dut, DUT_MSG_INFO,
1206 "Printing PostConnectivity Capability");
1207 if (event->is_conn_capability_valid) {
1208 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s",
1209 event->conn_capability.is_wfd_supported ?
1210 "yes" : "no");
1211 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s",
1212 (event->conn_capability.is_wfds_supported ?
1213 "yes" : "no"));
1214 sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s",
1215 (event->conn_capability.is_tdls_supported ?
1216 "yes" : "no"));
1217 sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s",
1218 (event->conn_capability.is_ibss_supported ?
1219 "yes" : "no"));
1220 sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s",
1221 (event->conn_capability.is_mesh_supported ?
1222 "yes" : "no"));
1223 sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d",
1224 event->conn_capability.wlan_infra_field);
1225 } else {
1226 sigma_dut_print(global_dut, DUT_MSG_INFO,
1227 "PostConnectivity Capability not present");
1228 }
1229
1230 /* Print the discovery_attr */
1231 sigma_dut_print(global_dut, DUT_MSG_INFO,
1232 "Printing PostDiscovery Attribute");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001233 if (event->num_rx_discovery_attr) {
1234 int idx;
1235
1236 for (idx = 0; idx < event->num_rx_discovery_attr; idx++) {
1237 sigma_dut_print(global_dut, DUT_MSG_INFO,
1238 "PostDiscovery Attribute - %d", idx);
1239 sigma_dut_print(global_dut, DUT_MSG_INFO,
1240 "Conn Type:%d Device Role:%d"
1241 MAC_ADDR_STR,
1242 event->discovery_attr[idx].type,
1243 event->discovery_attr[idx].role,
1244 MAC_ADDR_ARRAY(event->discovery_attr[idx].addr));
1245 sigma_dut_print(global_dut, DUT_MSG_INFO,
1246 "Duration:%d MapId:%d "
1247 "avail_interval_bitmap:%04x",
1248 event->discovery_attr[idx].duration,
1249 event->discovery_attr[idx].mapid,
1250 event->discovery_attr[idx].avail_interval_bitmap);
1251 sigma_dut_print(global_dut, DUT_MSG_INFO,
1252 "Printing Mesh Id:");
1253 nan_hex_dump(global_dut,
1254 event->discovery_attr[idx].mesh_id,
1255 event->discovery_attr[idx].mesh_id_len);
1256 sigma_dut_print(global_dut, DUT_MSG_INFO,
1257 "Printing Infrastructure Ssid:");
1258 nan_hex_dump(global_dut,
1259 event->discovery_attr[idx].infrastructure_ssid_val,
1260 event->discovery_attr[idx].infrastructure_ssid_len);
1261 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001262 } else {
1263 sigma_dut_print(global_dut, DUT_MSG_INFO,
1264 "PostDiscovery attribute not present");
1265 }
1266
1267 /* Print the fam */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001268 if (event->num_chans) {
1269 nan_print_further_availability_chan(global_dut,
1270 event->num_chans,
1271 &event->famchan[0]);
1272 } else {
1273 sigma_dut_print(global_dut, DUT_MSG_INFO,
1274 "Further Availability Map not present");
1275 }
1276 if (event->cluster_attribute_len) {
1277 sigma_dut_print(global_dut, DUT_MSG_INFO,
1278 "Printing Cluster Attribute:");
1279 nan_hex_dump(global_dut, event->cluster_attribute,
1280 event->cluster_attribute_len);
1281 } else {
1282 sigma_dut_print(global_dut, DUT_MSG_INFO,
1283 "Cluster Attribute not present");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001284 }
1285}
1286
1287
1288/* Events Callback */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001289void nan_event_match_expired(NanMatchExpiredInd *event)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001290{
1291 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001292 "%s: publish_subscribe_id %d match_handle %08x",
1293 __func__, event->publish_subscribe_id,
1294 event->requestor_instance_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001295}
1296
1297
1298/* Events Callback */
1299void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event)
1300{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001301 sigma_dut_print(global_dut, DUT_MSG_INFO,
1302 "%s: Subscribe Id %d reason %d",
1303 __func__, event->subscribe_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001304}
1305
1306
1307/* Events Callback */
1308void nan_event_followup(NanFollowupInd *event)
1309{
1310 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001311 "%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d "
1312 MAC_ADDR_STR, __func__, event->publish_subscribe_id,
1313 event->requestor_instance_id, event->dw_or_faw,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001314 MAC_ADDR_ARRAY(event->addr));
1315
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001316 global_match_handle = event->publish_subscribe_id;
1317 global_header_handle = event->requestor_instance_id;
1318 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__);
1319 nan_hex_dump(global_dut, event->service_specific_info,
1320 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001321 event_anyresponse = 1;
1322 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1323 "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001324 MAC_ADDR_STR " ", event->requestor_instance_id >> 24,
1325 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001326}
1327
1328
1329/* Events Callback */
1330void nan_event_disceng_event(NanDiscEngEventInd *event)
1331{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001332 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d",
1333 __func__, event->event_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001334
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001335 if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001336 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster "
1337 MAC_ADDR_STR,
1338 __func__,
1339 MAC_ADDR_ARRAY(event->data.cluster.addr));
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001340 /* To ensure sta_get_events to get the events
1341 * only after joining the NAN cluster. */
1342 pthread_cond_signal(&gCondition);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001343 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001344 if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001345 sigma_dut_print(global_dut, DUT_MSG_INFO,
1346 "%s: Started cluster " MAC_ADDR_STR,
1347 __func__,
1348 MAC_ADDR_ARRAY(event->data.cluster.addr));
1349 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001350 if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) {
1351 sigma_dut_print(global_dut, DUT_MSG_INFO,
1352 "%s: Discovery Mac Address "
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001353 MAC_ADDR_STR,
1354 __func__,
1355 MAC_ADDR_ARRAY(event->data.mac_addr.addr));
1356 memcpy(global_nan_mac_addr, event->data.mac_addr.addr,
1357 sizeof(global_nan_mac_addr));
1358 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001359}
1360
1361
1362/* Events Callback */
1363void nan_event_disabled(NanDisabledInd *event)
1364{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001365 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d",
1366 __func__, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001367 /* pthread_cond_signal(&gCondition); */
1368}
1369
1370
Rakesh Sunki4c086672017-03-30 14:47:55 -07001371/* Events callback */
1372static void ndp_event_data_indication(NanDataPathRequestInd *event)
1373{
1374 sigma_dut_print(global_dut, DUT_MSG_INFO,
1375 "%s: Service Instance Id: %d Peer Discovery MAC ADDR "
1376 MAC_ADDR_STR
1377 " NDP Instance Id: %d App Info len %d App Info %s",
1378 __func__,
1379 event->service_instance_id,
1380 MAC_ADDR_ARRAY(event->peer_disc_mac_addr),
1381 event->ndp_instance_id,
1382 event->app_info.ndp_app_info_len,
1383 event->app_info.ndp_app_info);
1384
1385 global_ndp_instance_id = event->ndp_instance_id;
1386}
1387
1388
1389/* Events callback */
1390static void ndp_event_data_confirm(NanDataPathConfirmInd *event)
1391{
1392 sigma_dut_print(global_dut, DUT_MSG_INFO,
1393 "Received NDP Confirm Indication");
1394
1395 global_ndp_instance_id = event->ndp_instance_id;
1396 if (system("ifconfig nan0 up") != 0) {
1397 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1398 "Failed to set nan interface up");
1399 return;
1400 }
1401 if (system("ip -6 route add fe80::/64 dev nan0 table local") != 0) {
1402 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1403 "Failed to run:ip -6 route replace fe80::/64 dev nan0 table local");
1404 return;
1405 }
1406}
1407
1408
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001409void * my_thread_function(void *ptr)
1410{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001411 wifi_event_loop(global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001412 pthread_exit(0);
1413 return (void *) NULL;
1414}
1415
1416
1417static NanCallbackHandler callbackHandler = {
1418 .NotifyResponse = nan_notify_response,
1419 .EventPublishReplied = nan_event_publish_replied,
1420 .EventPublishTerminated = nan_event_publish_terminated,
1421 .EventMatch = nan_event_match,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001422 .EventMatchExpired = nan_event_match_expired,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001423 .EventSubscribeTerminated = nan_event_subscribe_terminated,
1424 .EventFollowup = nan_event_followup,
1425 .EventDiscEngEvent = nan_event_disceng_event,
1426 .EventDisabled = nan_event_disabled,
Rakesh Sunki4c086672017-03-30 14:47:55 -07001427 .EventDataRequest = ndp_event_data_indication,
1428 .EventDataConfirm = ndp_event_data_confirm,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001429};
1430
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001431
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001432void nan_init(struct sigma_dut *dut)
1433{
1434 pthread_t thread1; /* thread variables */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001435 wifi_error err = wifi_initialize(&global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001436
1437 if (err) {
1438 printf("wifi hal initialize failed\n");
1439 return;
1440 }
1441
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001442 global_interface_handle = wifi_get_iface_handle(global_wifi_handle,
1443 (char *) "wlan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001444 /* create threads 1 */
1445 pthread_create(&thread1, NULL, &my_thread_function, NULL);
1446
1447 pthread_mutex_init(&gMutex, NULL);
1448 pthread_cond_init(&gCondition, NULL);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001449 if (global_interface_handle)
1450 nan_register_handler(global_interface_handle, callbackHandler);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001451}
1452
1453
1454void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1455 struct sigma_cmd *cmd)
1456{
1457 sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default");
1458
1459 if (nan_state == 0) {
1460 nan_init(dut);
1461 nan_state = 1;
1462 }
1463 is_fam = 0;
1464 event_anyresponse = 0;
1465 global_dut = dut;
Rakesh Sunki7d37f412017-03-30 14:47:55 -07001466 memset(&dut->nan_pmk[0], 0, NAN_PMK_INFO_LEN);
1467 dut->nan_pmk_len = 0;
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001468 dut->sta_channel = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001469 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001470 memset(&global_nan_sync_stats, 0, sizeof(global_nan_sync_stats));
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001471
1472 nan_data_interface_delete(0, global_interface_handle, (char *) "nan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001473 sigma_nan_disable(dut, conn, cmd);
1474}
1475
1476
1477int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1478 struct sigma_cmd *cmd)
1479{
1480 const char *program = get_param(cmd, "Prog");
1481 const char *nan_op = get_param(cmd, "NANOp");
1482 const char *method_type = get_param(cmd, "MethodType");
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001483 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001484 char resp_buf[100];
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001485 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001486
1487 if (program == NULL)
1488 return -1;
1489
1490 if (strcasecmp(program, "NAN") != 0) {
1491 send_resp(dut, conn, SIGMA_ERROR,
1492 "ErrorCode,Unsupported program");
1493 return 0;
1494 }
1495
1496 if (nan_op) {
1497 /*
1498 * NANOp has been specified.
1499 * We will build a nan_enable or nan_disable command.
1500 */
1501 if (strcasecmp(nan_op, "On") == 0) {
1502 if (sigma_nan_enable(dut, conn, cmd) == 0) {
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001503 ret = nan_data_interface_create(
1504 0, global_interface_handle,
1505 (char *) "nan0");
1506 if (ret != WIFI_SUCCESS) {
1507 sigma_dut_print(
1508 global_dut, DUT_MSG_ERROR,
1509 "Unable to create NAN data interface");
1510 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001511 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1512 MAC_ADDR_STR,
1513 MAC_ADDR_ARRAY(global_nan_mac_addr));
1514 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1515 } else {
1516 send_resp(dut, conn, SIGMA_ERROR,
1517 "NAN_ENABLE_FAILED");
1518 return -1;
1519 }
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001520
1521 if (band && strcasecmp(band, "24g") == 0) {
1522 sigma_dut_print(dut, DUT_MSG_INFO,
1523 "%s: Setting band to 2G Only",
1524 __func__);
1525 sigma_ndp_configure_band(
1526 dut, conn, cmd,
1527 NAN_DATA_PATH_SUPPORTED_BAND_2G);
1528 } else if (band && dut->sta_channel > 12) {
1529 sigma_ndp_configure_band(
1530 dut, conn, cmd,
1531 NAN_DATA_PATH_SUPPORT_DUAL_BAND);
1532 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001533 } else if (strcasecmp(nan_op, "Off") == 0) {
1534 sigma_nan_disable(dut, conn, cmd);
1535 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1536 }
1537 }
1538 if (nan_state && nan_op == NULL) {
1539 if (method_type) {
1540 if (strcasecmp(method_type, "Publish") == 0) {
1541 sigma_nan_publish_request(dut, conn, cmd);
1542 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1543 }
1544 if (strcasecmp(method_type, "Subscribe") == 0) {
1545 sigma_nan_subscribe_request(dut, conn, cmd);
1546 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1547 }
1548 if (strcasecmp(method_type, "Followup") == 0) {
1549 sigma_nan_transmit_followup(dut, conn, cmd);
1550 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1551 }
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07001552 if (strcasecmp(method_type, "DataRequest") == 0) {
1553 sigma_nan_data_request(dut, conn, cmd);
1554 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1555 }
Rakesh Sunkia5cc2842017-03-30 14:47:55 -07001556 if (strcasecmp(method_type, "DataResponse") == 0) {
1557 sigma_dut_print(dut, DUT_MSG_INFO,
1558 "%s: method_type is DataResponse",
1559 __func__);
1560 sigma_nan_data_response(dut, conn, cmd);
1561 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1562 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001563 } else {
1564 sigma_nan_config_enable(dut, conn, cmd);
1565 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1566 MAC_ADDR_STR,
1567 MAC_ADDR_ARRAY(global_nan_mac_addr));
1568 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1569 }
1570 }
1571
1572 return 0;
1573}
1574
1575
1576int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1577 struct sigma_cmd *cmd)
1578{
1579
1580 const char *program = get_param(cmd, "Program");
1581 const char *parameter = get_param(cmd, "Parameter");
1582 char resp_buf[100];
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001583 NanStatsRequest req;
1584 struct timespec abstime;
1585 u64 master_rank;
1586 u8 master_pref;
1587 u8 random_factor;
1588 u8 hop_count;
1589 u32 beacon_transmit_time;
1590 u32 ndp_channel_freq;
1591 u32 ndp_channel_freq2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001592
1593 if (program == NULL) {
1594 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name");
1595 return -1;
1596 }
1597 if (strcasecmp(program, "NAN") != 0) {
1598 send_resp(dut, conn, SIGMA_ERROR,
1599 "ErrorCode,Unsupported program");
1600 return 0;
1601 }
1602
1603 if (parameter == NULL) {
1604 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter");
1605 return -1;
1606 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001607
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001608 memset(&req, 0, sizeof(NanStatsRequest));
1609 req.stats_type = (NanStatsType) NAN_STATS_ID_DE_TIMING_SYNC;
1610 nan_stats_request(0, global_interface_handle, &req);
1611 /*
1612 * To ensure sta_get_events to get the events
1613 * only after joining the NAN cluster
1614 */
1615 abstime.tv_sec = 4;
1616 abstime.tv_nsec = 0;
1617 wait(abstime);
1618
1619 master_rank = global_nan_sync_stats.myRank;
1620 master_pref = (global_nan_sync_stats.myRank & 0xFF00000000000000) >> 56;
1621 random_factor = (global_nan_sync_stats.myRank & 0x00FF000000000000) >>
1622 48;
1623 hop_count = global_nan_sync_stats.currAmHopCount;
1624 beacon_transmit_time = global_nan_sync_stats.currAmBTT;
1625 ndp_channel_freq = global_nan_sync_stats.ndpChannelFreq;
1626 ndp_channel_freq2 = global_nan_sync_stats.ndpChannelFreq2;
1627
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001628 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001629 "%s: NanStatsRequest Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d ndp_channel_freq:%d ndp_channel_freq2:%d",
1630 __func__, master_pref, random_factor,
1631 hop_count, beacon_transmit_time,
1632 ndp_channel_freq, ndp_channel_freq2);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001633
1634 if (strcasecmp(parameter, "MasterPref") == 0) {
1635 snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001636 master_pref);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001637 } else if (strcasecmp(parameter, "MasterRank") == 0) {
1638 snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001639 master_rank);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001640 } else if (strcasecmp(parameter, "RandFactor") == 0) {
1641 snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001642 random_factor);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001643 } else if (strcasecmp(parameter, "HopCount") == 0) {
1644 snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001645 hop_count);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001646 } else if (strcasecmp(parameter, "BeaconTransTime") == 0) {
1647 snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001648 beacon_transmit_time);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001649 } else if (strcasecmp(parameter, "NANStatus") == 0) {
1650 if (nan_state == 1)
1651 snprintf(resp_buf, sizeof(resp_buf), "On");
1652 else
1653 snprintf(resp_buf, sizeof(resp_buf), "Off");
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001654 } else if (strcasecmp(parameter, "NDPChannel") == 0) {
1655 if (ndp_channel_freq != 0 && ndp_channel_freq2 != 0) {
1656 snprintf(resp_buf, sizeof(resp_buf),
1657 "ndpchannel,%d,ndpchannel,%d",
1658 freq_to_channel(ndp_channel_freq),
1659 freq_to_channel(ndp_channel_freq2));
1660 } else if (ndp_channel_freq != 0) {
1661 snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
1662 freq_to_channel(ndp_channel_freq));
1663 } else if (ndp_channel_freq2 != 0) {
1664 snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
1665 freq_to_channel(ndp_channel_freq2));
1666 } else {
1667 sigma_dut_print(dut, DUT_MSG_ERROR,
1668 "%s: No Negotiated NDP Channels", __func__);
1669 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001670 } else {
1671 send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
1672 return 0;
1673 }
1674
1675 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1676 return 0;
1677}
1678
1679
1680int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1681 struct sigma_cmd *cmd)
1682{
1683 const char *action = get_param(cmd, "Action");
1684
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001685 if (!action)
1686 return 0;
1687
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001688 /* Check action for start, stop and get events. */
1689 if (strcasecmp(action, "Start") == 0) {
1690 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1691 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1692 } else if (strcasecmp(action, "Stop") == 0) {
1693 event_anyresponse = 0;
1694 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1695 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1696 } else if (strcasecmp(action, "Get") == 0) {
1697 if (event_anyresponse == 1) {
1698 send_resp(dut, conn, SIGMA_COMPLETE,
1699 global_event_resp_buf);
1700 } else {
1701 send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE");
1702 }
1703 }
1704 return 0;
1705}
Rakesh Sunki4b75f962017-03-30 14:47:55 -07001706
1707#else /* #if NAN_CERT_VERSION */
1708
1709int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
1710 struct sigma_conn *conn,
1711 struct sigma_cmd *cmd)
1712{
1713 return 1;
1714}
1715
1716
1717int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1718 struct sigma_cmd *cmd)
1719{
1720 return 0;
1721
1722}
1723
1724
1725void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1726 struct sigma_cmd *cmd)
1727{
1728 return;
1729}
1730
1731
1732int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1733 struct sigma_cmd *cmd)
1734{
1735 return 0;
1736}
1737
1738
1739int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1740 struct sigma_cmd *cmd)
1741{
1742 return 0;
1743}
1744
1745#endif /* #if NAN_CERT_VERSION */