blob: 0c330e4bfabec91a037b1449530dd8373dc0cefa [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
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -070032#define DEFAULT_SVC "QNanCluster"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020033#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
34#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
35#ifndef ETH_ALEN
36#define ETH_ALEN 6
37#endif
38
39struct sigma_dut *global_dut = NULL;
40static char global_nan_mac_addr[ETH_ALEN];
Rakesh Sunki14cfcd22017-03-30 14:47:55 -070041static char global_peer_mac_addr[ETH_ALEN];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020042static char global_event_resp_buf[1024];
Rakesh Sunki42363682017-05-16 15:00:42 -070043static u8 global_publish_service_name[NAN_MAX_SERVICE_NAME_LEN];
44static u32 global_publish_service_name_len = 0;
Rakesh Sunki74f4f992017-08-16 15:21:52 -070045static u8 global_subscribe_service_name[NAN_MAX_SERVICE_NAME_LEN];
46static u32 global_subscribe_service_name_len = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020047
48static int nan_further_availability_tx(struct sigma_dut *dut,
49 struct sigma_conn *conn,
50 struct sigma_cmd *cmd);
51static int nan_further_availability_rx(struct sigma_dut *dut,
52 struct sigma_conn *conn,
53 struct sigma_cmd *cmd);
54
55
56void nan_hex_dump(struct sigma_dut *dut, uint8_t *data, size_t len)
57{
58 char buf[512];
59 uint16_t index;
60 uint8_t *ptr;
61 int pos;
62
63 memset(buf, 0, sizeof(buf));
64 ptr = data;
65 pos = 0;
66 for (index = 0; index < len; index++) {
Peng Xu6734e232017-10-04 10:10:33 -070067 pos += snprintf(&(buf[pos]), sizeof(buf) - pos,
68 "%02x ", *ptr++);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020069 if (pos > 508)
70 break;
71 }
72 sigma_dut_print(dut, DUT_MSG_INFO, "HEXDUMP len=[%d]", (int) len);
73 sigma_dut_print(dut, DUT_MSG_INFO, "buf:%s", buf);
74}
75
76
77int nan_parse_hex(unsigned char c)
78{
79 if (c >= '0' && c <= '9')
80 return c - '0';
81 if (c >= 'a' && c <= 'f')
82 return c - 'a' + 10;
83 if (c >= 'A' && c <= 'F')
84 return c - 'A' + 10;
85 return 0;
86}
87
88
89int nan_parse_token(const char *tokenIn, u8 *tokenOut, int *filterLen)
90{
91 int total_len = 0, len = 0;
92 char *saveptr = NULL;
93
94 tokenIn = strtok_r((char *) tokenIn, ":", &saveptr);
95 while (tokenIn != NULL) {
96 len = strlen(tokenIn);
97 if (len == 1 && *tokenIn == '*')
98 len = 0;
99 tokenOut[total_len++] = (u8) len;
100 if (len != 0)
101 memcpy((u8 *) tokenOut + total_len, tokenIn, len);
102 total_len += len;
103 tokenIn = strtok_r(NULL, ":", &saveptr);
104 }
105 *filterLen = total_len;
106 return 0;
107}
108
109
110int nan_parse_mac_address(struct sigma_dut *dut, const char *arg, u8 *addr)
111{
112 if (strlen(arg) != 17) {
113 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid mac address %s",
114 arg);
115 sigma_dut_print(dut, DUT_MSG_ERROR,
116 "expected format xx:xx:xx:xx:xx:xx");
117 return -1;
118 }
119
120 addr[0] = nan_parse_hex(arg[0]) << 4 | nan_parse_hex(arg[1]);
121 addr[1] = nan_parse_hex(arg[3]) << 4 | nan_parse_hex(arg[4]);
122 addr[2] = nan_parse_hex(arg[6]) << 4 | nan_parse_hex(arg[7]);
123 addr[3] = nan_parse_hex(arg[9]) << 4 | nan_parse_hex(arg[10]);
124 addr[4] = nan_parse_hex(arg[12]) << 4 | nan_parse_hex(arg[13]);
125 addr[5] = nan_parse_hex(arg[15]) << 4 | nan_parse_hex(arg[16]);
126
127 return 0;
128}
129
130
131int nan_parse_mac_address_list(struct sigma_dut *dut, const char *input,
132 u8 *output, u16 max_addr_allowed)
133{
134 /*
135 * Reads a list of mac address separated by space. Each MAC address
136 * should have the format of aa:bb:cc:dd:ee:ff.
137 */
138 char *saveptr;
139 char *token;
140 int i = 0;
141
142 for (i = 0; i < max_addr_allowed; i++) {
143 token = strtok_r((i == 0) ? (char *) input : NULL,
144 " ", &saveptr);
145 if (token) {
146 nan_parse_mac_address(dut, token, output);
147 output += NAN_MAC_ADDR_LEN;
148 } else
149 break;
150 }
151
152 sigma_dut_print(dut, DUT_MSG_INFO, "Num MacAddress:%d", i);
153
154 return i;
155}
156
157
158int nan_parse_hex_string(struct sigma_dut *dut, const char *input,
159 u8 *output, int *outputlen)
160{
161 int i = 0;
162 int j = 0;
163
164 for (i = 0; i < (int) strlen(input) && j < *outputlen; i += 2) {
165 output[j] = nan_parse_hex(input[i]);
166 if (i + 1 < (int) strlen(input)) {
167 output[j] = ((output[j] << 4) |
168 nan_parse_hex(input[i + 1]));
169 }
170 j++;
171 }
172 *outputlen = j;
173 sigma_dut_print(dut, DUT_MSG_INFO, "Input:%s inputlen:%d outputlen:%d",
174 input, (int) strlen(input), (int) *outputlen);
175 return 0;
176}
177
178
179int wait(struct timespec abstime)
180{
181 struct timeval now;
182
183 gettimeofday(&now, NULL);
184
185 abstime.tv_sec += now.tv_sec;
186 if (((abstime.tv_nsec + now.tv_usec * 1000) > 1000 * 1000 * 1000) ||
187 (abstime.tv_nsec + now.tv_usec * 1000 < 0)) {
188 abstime.tv_sec += 1;
189 abstime.tv_nsec += now.tv_usec * 1000;
190 abstime.tv_nsec -= 1000 * 1000 * 1000;
191 } else {
192 abstime.tv_nsec += now.tv_usec * 1000;
193 }
194
195 return pthread_cond_timedwait(&gCondition, &gMutex, &abstime);
196}
197
198
199int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
200 struct sigma_conn *conn,
201 struct sigma_cmd *cmd)
202{
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700203 const char *oper_chan = get_param(cmd, "oper_chn");
Rakesh Sunki7d37f412017-03-30 14:47:55 -0700204 const char *pmk = get_param(cmd, "PMK");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200205
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700206 if (oper_chan) {
207 sigma_dut_print(dut, DUT_MSG_INFO, "Operating Channel: %s",
208 oper_chan);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700209 dut->sta_channel = atoi(oper_chan);
Rakesh Sunki8dd1d882017-03-30 14:47:55 -0700210 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200211
Rakesh Sunki7d37f412017-03-30 14:47:55 -0700212 if (pmk) {
213 int pmk_len;
214
215 sigma_dut_print(dut, DUT_MSG_INFO, "%s given string pmk: %s",
216 __func__, pmk);
217 memset(dut->nan_pmk, 0, NAN_PMK_INFO_LEN);
218 dut->nan_pmk_len = 0;
219 pmk_len = NAN_PMK_INFO_LEN;
220 nan_parse_hex_string(dut, &pmk[2], &dut->nan_pmk[0], &pmk_len);
221 dut->nan_pmk_len = pmk_len;
222 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
223 __func__, dut->nan_pmk_len);
224 sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex pmk", __func__);
225 nan_hex_dump(dut, &dut->nan_pmk[0], dut->nan_pmk_len);
226 }
227
Rakesh Sunki14bff1d2017-03-30 14:47:55 -0700228 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200229 return 0;
230}
231
232
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700233void nan_print_further_availability_chan(struct sigma_dut *dut,
234 u8 num_chans,
235 NanFurtherAvailabilityChannel *fachan)
236{
237 int idx;
238
239 sigma_dut_print(dut, DUT_MSG_INFO,
240 "********Printing FurtherAvailabilityChan Info******");
241 sigma_dut_print(dut, DUT_MSG_INFO, "Numchans:%d", num_chans);
242 for (idx = 0; idx < num_chans; idx++) {
243 sigma_dut_print(dut, DUT_MSG_INFO,
244 "[%d]: NanAvailDuration:%d class_val:%02x channel:%d",
245 idx, fachan->entry_control,
246 fachan->class_val, fachan->channel);
247 sigma_dut_print(dut, DUT_MSG_INFO,
248 "[%d]: mapid:%d Availability bitmap:%08x",
249 idx, fachan->mapid,
250 fachan->avail_interval_bitmap);
251 }
252 sigma_dut_print(dut, DUT_MSG_INFO,
253 "*********************Done**********************");
254}
255
256
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200257int sigma_nan_enable(struct sigma_dut *dut, struct sigma_conn *conn,
258 struct sigma_cmd *cmd)
259{
260 const char *master_pref = get_param(cmd, "MasterPref");
261 const char *rand_fac = get_param(cmd, "RandFactor");
262 const char *hop_count = get_param(cmd, "HopCount");
263 const char *high_tsf = get_param(cmd, "HighTSF");
264 const char *sdftx_band = get_param(cmd, "SDFTxBand");
265 const char *oper_chan = get_param(cmd, "oper_chn");
266 const char *further_avail_ind = get_param(cmd, "FurtherAvailInd");
267 const char *band = get_param(cmd, "Band");
268 const char *only_5g = get_param(cmd, "5GOnly");
Rakesh Sunki38dd72e2017-03-30 14:47:55 -0700269 const char *nan_availability = get_param(cmd, "NANAvailability");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200270 struct timespec abstime;
271 NanEnableRequest req;
272
273 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200274 req.cluster_low = 0;
275 req.cluster_high = 0xFFFF;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700276 req.master_pref = 100;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200277
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700278 /* This is a debug hack to beacon in channel 11 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200279 if (oper_chan) {
280 req.config_2dot4g_support = 1;
281 req.support_2dot4g_val = 111;
282 }
283
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200284 if (master_pref) {
285 int master_pref_val = strtoul(master_pref, NULL, 0);
286
287 req.master_pref = master_pref_val;
288 }
289
290 if (rand_fac) {
291 int rand_fac_val = strtoul(rand_fac, NULL, 0);
292
293 req.config_random_factor_force = 1;
294 req.random_factor_force_val = rand_fac_val;
295 }
296
297 if (hop_count) {
298 int hop_count_val = strtoul(hop_count, NULL, 0);
299
300 req.config_hop_count_force = 1;
301 req.hop_count_force_val = hop_count_val;
302 }
303
304 if (sdftx_band) {
305 if (strcasecmp(sdftx_band, "5G") == 0) {
306 req.config_2dot4g_support = 1;
307 req.support_2dot4g_val = 0;
308 }
309 }
310
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700311 sigma_dut_print(dut, DUT_MSG_INFO,
312 "%s: Setting dual band 2.4 GHz and 5 GHz by default",
313 __func__);
314 /* Enable 2.4 GHz support */
315 req.config_2dot4g_support = 1;
316 req.support_2dot4g_val = 1;
317 req.config_2dot4g_beacons = 1;
318 req.beacon_2dot4g_val = 1;
319 req.config_2dot4g_sdf = 1;
320 req.sdf_2dot4g_val = 1;
321
322 /* Enable 5 GHz support */
323 req.config_support_5g = 1;
324 req.support_5g_val = 1;
325 req.config_5g_beacons = 1;
326 req.beacon_5g_val = 1;
327 req.config_5g_sdf = 1;
328 req.sdf_5g_val = 1;
329
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200330 if (band) {
331 if (strcasecmp(band, "24G") == 0) {
332 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700333 "Band 2.4 GHz selected, disable 5 GHz");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200334 /* Disable 5G support */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700335 req.config_support_5g = 1;
336 req.support_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200337 req.config_5g_beacons = 1;
338 req.beacon_5g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700339 req.config_5g_sdf = 1;
340 req.sdf_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200341 }
342 }
343
344 if (further_avail_ind) {
345 sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled");
346 if (strcasecmp(further_avail_ind, "tx") == 0) {
347 is_fam = 1;
348 nan_further_availability_tx(dut, conn, cmd);
349 return 0;
350 } else if (strcasecmp(further_avail_ind, "rx") == 0) {
351 nan_further_availability_rx(dut, conn, cmd);
352 return 0;
353 }
354 }
355
356 if (only_5g && atoi(only_5g)) {
357 sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled");
358 req.config_2dot4g_support = 1;
359 req.support_2dot4g_val = 1;
360 req.config_2dot4g_beacons = 1;
361 req.beacon_2dot4g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700362 req.config_2dot4g_sdf = 1;
363 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200364 }
365
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700366 nan_enable_request(0, global_interface_handle, &req);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700367
Rakesh Sunki38dd72e2017-03-30 14:47:55 -0700368 if (nan_availability) {
369 int cmd_len, size;
370 NanDebugParams cfg_debug;
371
372 sigma_dut_print(dut, DUT_MSG_INFO,
373 "%s given string nan_availability: %s",
374 __func__, nan_availability);
375 memset(&cfg_debug, 0, sizeof(NanDebugParams));
376 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY;
377 size = NAN_MAX_DEBUG_MESSAGE_DATA_LEN;
378 nan_parse_hex_string(dut, &nan_availability[2],
379 &cfg_debug.debug_cmd_data[0], &size);
380 sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex nan_availability",
381 __func__);
382 nan_hex_dump(dut, &cfg_debug.debug_cmd_data[0], size);
383 cmd_len = size + sizeof(u32);
384 nan_debug_command_config(0, global_interface_handle,
385 cfg_debug, cmd_len);
386 }
387
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700388 /* To ensure sta_get_events to get the events
389 * only after joining the NAN cluster. */
390 abstime.tv_sec = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200391 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700392 wait(abstime);
393
394 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200395}
396
397
398int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn,
399 struct sigma_cmd *cmd)
400{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200401 struct timespec abstime;
402
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700403 nan_disable_request(0, global_interface_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200404
405 abstime.tv_sec = 4;
406 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700407 wait(abstime);
408
409 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200410}
411
412
413int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn,
414 struct sigma_cmd *cmd)
415{
416 const char *master_pref = get_param(cmd, "MasterPref");
417 const char *rand_fac = get_param(cmd, "RandFactor");
418 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700419 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200420 struct timespec abstime;
421 NanConfigRequest req;
422
423 memset(&req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200424 req.config_rssi_proximity = 1;
425 req.rssi_proximity = 70;
426
427 if (master_pref) {
428 int master_pref_val = strtoul(master_pref, NULL, 0);
429
430 req.config_master_pref = 1;
431 req.master_pref = master_pref_val;
432 }
433
434 if (rand_fac) {
435 int rand_fac_val = strtoul(rand_fac, NULL, 0);
436
437 req.config_random_factor_force = 1;
438 req.random_factor_force_val = rand_fac_val;
439 }
440
441 if (hop_count) {
442 int hop_count_val = strtoul(hop_count, NULL, 0);
443
444 req.config_hop_count_force = 1;
445 req.hop_count_force_val = hop_count_val;
446 }
447
Rakesh Sunki107356c2017-03-30 14:47:55 -0700448 ret = nan_config_request(0, global_interface_handle, &req);
449 if (ret != WIFI_SUCCESS)
450 send_resp(dut, conn, SIGMA_ERROR, "NAN config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200451
452 abstime.tv_sec = 4;
453 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700454 wait(abstime);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200455
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700456 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200457}
458
459
460static int sigma_nan_subscribe_request(struct sigma_dut *dut,
461 struct sigma_conn *conn,
462 struct sigma_cmd *cmd)
463{
464 const char *subscribe_type = get_param(cmd, "SubscribeType");
465 const char *service_name = get_param(cmd, "ServiceName");
466 const char *disc_range = get_param(cmd, "DiscoveryRange");
467 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
468 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
469 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
470 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
471 const char *include_bit = get_param(cmd, "IncludeBit");
472 const char *mac = get_param(cmd, "MAC");
473 const char *srf_type = get_param(cmd, "SRFType");
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -0700474#if NAN_CERT_VERSION >= 3
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700475 const char *awake_dw_interval = get_param(cmd, "awakeDWint");
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -0700476#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200477 NanSubscribeRequest req;
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700478 NanConfigRequest config_req;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200479 int filter_len_rx = 0, filter_len_tx = 0;
480 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
481 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700482 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200483
484 memset(&req, 0, sizeof(NanSubscribeRequest));
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700485 memset(&config_req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200486 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -0700487 req.period = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200488 req.subscribe_type = 1;
489 req.serviceResponseFilter = 1; /* MAC */
490 req.serviceResponseInclude = 0;
491 req.ssiRequiredForMatchIndication = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700492 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200493 req.subscribe_count = 0;
494
Rakesh Sunki74f4f992017-08-16 15:21:52 -0700495 if (global_subscribe_service_name_len &&
496 service_name &&
497 strcasecmp((char *) global_subscribe_service_name,
498 service_name) == 0 &&
499 global_subscribe_id) {
500 req.subscribe_id = global_subscribe_id;
501 sigma_dut_print(dut, DUT_MSG_INFO,
502 "%s: updating subscribe_id = %d in subscribe request",
503 __func__, req.subscribe_id);
504 }
505
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200506 if (subscribe_type) {
507 if (strcasecmp(subscribe_type, "Active") == 0) {
508 req.subscribe_type = 1;
509 } else if (strcasecmp(subscribe_type, "Passive") == 0) {
510 req.subscribe_type = 0;
511 } else if (strcasecmp(subscribe_type, "Cancel") == 0) {
512 NanSubscribeCancelRequest req;
513
514 memset(&req, 0, sizeof(NanSubscribeCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700515 ret = nan_subscribe_cancel_request(
516 0, global_interface_handle, &req);
517 if (ret != WIFI_SUCCESS) {
518 send_resp(dut, conn, SIGMA_ERROR,
519 "NAN subscribe cancel request failed");
520 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200521 return 0;
522 }
523 }
524
525 if (disc_range)
526 req.rssi_threshold_flag = atoi(disc_range);
527
528 if (sdftx_dw)
529 req.subscribe_count = atoi(sdftx_dw);
530
531 /* Check this once again if config can be called here (TBD) */
532 if (discrange_ltd)
533 req.rssi_threshold_flag = atoi(discrange_ltd);
534
535 if (include_bit) {
536 int include_bit_val = atoi(include_bit);
537
538 req.serviceResponseInclude = include_bit_val;
539 sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d",
540 req.serviceResponseInclude);
541 }
542
543 if (srf_type) {
544 int srf_type_val = atoi(srf_type);
545
546 if (srf_type_val == 1)
547 req.serviceResponseFilter = 0; /* Bloom */
548 else
549 req.serviceResponseFilter = 1; /* MAC */
550 req.useServiceResponseFilter = 1;
551 sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d",
552 req.serviceResponseFilter);
553 }
554
555 if (mac) {
556 sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac);
557 req.num_intf_addr_present = nan_parse_mac_address_list(
558 dut, mac, &req.intf_addr[0][0],
559 NAN_MAX_SUBSCRIBE_MAX_ADDRESS);
560 }
561
562 memset(input_rx, 0, sizeof(input_rx));
563 memset(input_tx, 0, sizeof(input_tx));
564 if (rx_match_filter) {
565 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
566 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
567 filter_len_rx);
568 }
569 if (tx_match_filter) {
570 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
571 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
572 filter_len_tx);
573 }
574
575 if (tx_match_filter) {
576 req.tx_match_filter_len = filter_len_tx;
577 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
578 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
579 }
580 if (rx_match_filter) {
581 req.rx_match_filter_len = filter_len_rx;
582 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
583 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
584 }
585
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700586 if (service_name) {
587 strlcpy((char *) req.service_name, service_name,
588 strlen(service_name) + 1);
589 req.service_name_len = strlen(service_name);
Rakesh Sunki74f4f992017-08-16 15:21:52 -0700590 strlcpy((char *) global_subscribe_service_name, service_name,
591 sizeof(global_subscribe_service_name));
592 global_subscribe_service_name_len =
593 strlen((char *) global_subscribe_service_name);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700594 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200595
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -0700596#if NAN_CERT_VERSION >= 3
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700597 if (awake_dw_interval) {
598 int input_dw_interval_val = atoi(awake_dw_interval);
599 int awake_dw_int = 0;
600
601 if (input_dw_interval_val > NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL) {
602 sigma_dut_print(dut, DUT_MSG_INFO,
603 "%s: input active dw interval = %d overwritting dw interval to Max allowed dw interval 16",
604 __func__, input_dw_interval_val);
605 input_dw_interval_val =
606 NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL;
607 }
608 sigma_dut_print(dut, DUT_MSG_INFO,
609 "%s: input active DW interval = %d",
610 __func__, input_dw_interval_val);
611 /*
612 * Indicates the interval for Sync beacons and SDF's in 2.4 GHz
613 * or 5 GHz band. Valid values of DW Interval are: 1, 2, 3, 4,
614 * and 5; 0 is reserved. The SDF includes in OTA when enabled.
615 * The publish/subscribe period values don't override the device
616 * level configurations.
617 * input_dw_interval_val is provided by the user are in the
618 * format 2^n-1 = 1/2/4/8/16. Internal implementation expects n
619 * to be passed to indicate the awake_dw_interval.
620 */
621 if (input_dw_interval_val == 1 ||
622 input_dw_interval_val % 2 == 0) {
623 while (input_dw_interval_val > 0) {
624 input_dw_interval_val >>= 1;
625 awake_dw_int++;
626 }
627 }
628 sigma_dut_print(dut, DUT_MSG_INFO,
629 "%s:converted active DW interval = %d",
630 __func__, awake_dw_int);
631 config_req.config_dw.config_2dot4g_dw_band = 1;
632 config_req.config_dw.dw_2dot4g_interval_val = awake_dw_int;
633 config_req.config_dw.config_5g_dw_band = 1;
634 config_req.config_dw.dw_5g_interval_val = awake_dw_int;
635 ret = nan_config_request(0, global_interface_handle,
636 &config_req);
637 if (ret != WIFI_SUCCESS) {
638 sigma_dut_print(dut, DUT_MSG_ERROR,
639 "%s:NAN config request failed",
640 __func__);
641 return -2;
642 }
643 }
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -0700644#endif
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700645
Rakesh Sunki107356c2017-03-30 14:47:55 -0700646 ret = nan_subscribe_request(0, global_interface_handle, &req);
647 if (ret != WIFI_SUCCESS) {
648 send_resp(dut, conn, SIGMA_ERROR,
649 "NAN subscribe request failed");
650 }
651
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200652 return 0;
653}
654
655
Rakesh Sunkid7344c02017-03-30 14:47:55 -0700656static int sigma_ndp_configure_band(struct sigma_dut *dut,
657 struct sigma_conn *conn,
658 struct sigma_cmd *cmd,
659 NdpSupportedBand band_config_val)
660{
661 wifi_error ret;
662 NanDebugParams cfg_debug;
663 int size;
664
665 memset(&cfg_debug, 0, sizeof(NanDebugParams));
666 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS;
667 memcpy(cfg_debug.debug_cmd_data, &band_config_val, sizeof(int));
668 sigma_dut_print(dut, DUT_MSG_INFO, "%s:setting debug cmd=0x%x",
669 __func__, cfg_debug.cmd);
670 size = sizeof(u32) + sizeof(int);
671 ret = nan_debug_command_config(0, global_interface_handle, cfg_debug,
672 size);
673 if (ret != WIFI_SUCCESS)
674 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
675
676 return 0;
677}
678
679
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700680static int sigma_nan_data_request(struct sigma_dut *dut,
681 struct sigma_conn *conn,
682 struct sigma_cmd *cmd)
683{
684 const char *ndp_security = get_param(cmd, "DataPathSecurity");
685 const char *ndp_resp_mac = get_param(cmd, "RespNanMac");
686 const char *include_immutable = get_param(cmd, "includeimmutable");
687 const char *avoid_channel = get_param(cmd, "avoidchannel");
688 const char *invalid_nan_schedule = get_param(cmd, "InvalidNANSchedule");
689 const char *map_order = get_param(cmd, "maporder");
Rakesh Sunki8a4845d2017-05-16 15:27:13 -0700690#if NAN_CERT_VERSION >= 3
691 const char *qos_config = get_param(cmd, "QoS");
692#endif
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700693 wifi_error ret;
694 NanDataPathInitiatorRequest init_req;
695 NanDebugParams cfg_debug;
696 int size;
697
698 memset(&init_req, 0, sizeof(NanDataPathInitiatorRequest));
699
700 if (ndp_security) {
701 if (strcasecmp(ndp_security, "open") == 0)
702 init_req.ndp_cfg.security_cfg =
703 NAN_DP_CONFIG_NO_SECURITY;
704 else if (strcasecmp(ndp_security, "secure") == 0)
705 init_req.ndp_cfg.security_cfg = NAN_DP_CONFIG_SECURITY;
706 }
707
708 if (include_immutable) {
709 int include_immutable_val = 0;
710
711 memset(&cfg_debug, 0, sizeof(NanDebugParams));
712 cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE;
713 include_immutable_val = atoi(include_immutable);
714 memcpy(cfg_debug.debug_cmd_data, &include_immutable_val,
715 sizeof(int));
716 size = sizeof(u32) + sizeof(int);
717 nan_debug_command_config(0, global_interface_handle,
718 cfg_debug, size);
719 }
720
721 if (avoid_channel) {
722 int avoid_channel_freq = 0;
723
724 memset(&cfg_debug, 0, sizeof(NanDebugParams));
725 avoid_channel_freq = channel_to_freq(atoi(avoid_channel));
726 cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL;
727 memcpy(cfg_debug.debug_cmd_data, &avoid_channel_freq,
728 sizeof(int));
729 size = sizeof(u32) + sizeof(int);
730 nan_debug_command_config(0, global_interface_handle,
731 cfg_debug, size);
732 }
733
734 if (invalid_nan_schedule) {
735 int invalid_nan_schedule_type = 0;
736
737 memset(&cfg_debug, 0, sizeof(NanDebugParams));
738 invalid_nan_schedule_type = atoi(invalid_nan_schedule);
739 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_TYPE;
740 memcpy(cfg_debug.debug_cmd_data,
741 &invalid_nan_schedule_type, sizeof(int));
742 size = sizeof(u32) + sizeof(int);
743 sigma_dut_print(dut, DUT_MSG_INFO,
744 "%s: invalid schedule type: cmd type = %d and command data = %d",
745 __func__, cfg_debug.cmd,
746 invalid_nan_schedule_type);
747 nan_debug_command_config(0, global_interface_handle,
748 cfg_debug, size);
749 }
750
751 if (map_order) {
752 int map_order_val = 0;
753
754 memset(&cfg_debug, 0, sizeof(NanDebugParams));
755 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER;
756 map_order_val = atoi(map_order);
757 memcpy(cfg_debug.debug_cmd_data, &map_order_val, sizeof(int));
758 size = sizeof(u32) + sizeof(int);
759 sigma_dut_print(dut, DUT_MSG_INFO,
760 "%s: map order: cmd type = %d and command data = %d",
761 __func__,
Rakesh Sunki9eaa6772017-04-04 11:37:03 -0700762 cfg_debug.cmd, map_order_val);
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700763 nan_debug_command_config(0, global_interface_handle,
764 cfg_debug, size);
765 }
766
Rakesh Sunki8a4845d2017-05-16 15:27:13 -0700767#if NAN_CERT_VERSION >= 3
768 if (qos_config) {
769 u32 qos_config_val = 0;
770
771 memset(&cfg_debug, 0, sizeof(NanDebugParams));
772 cfg_debug.cmd = NAN_TEST_MODE_CMD_CONFIG_QOS;
773 qos_config_val = atoi(qos_config);
774 memcpy(cfg_debug.debug_cmd_data, &qos_config_val, sizeof(u32));
775 size = sizeof(u32) + sizeof(u32);
776 sigma_dut_print(dut, DUT_MSG_INFO,
777 "%s: qos config: cmd type = %d and command data = %d",
778 __func__, cfg_debug.cmd, qos_config_val);
779 nan_debug_command_config(0, global_interface_handle,
780 cfg_debug, size);
781 }
782#endif
783
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700784 /*
785 * Setting this flag, so that interface for ping6 command
786 * is set appropriately in traffic_send_ping().
787 */
788 dut->ndp_enable = 1;
789
790 /*
791 * Intended sleep after NAN data interface create
792 * before the NAN data request
793 */
794 sleep(4);
795
796 init_req.requestor_instance_id = global_match_handle;
797 strlcpy((char *) init_req.ndp_iface, "nan0",
798 sizeof(init_req.ndp_iface));
799
800 if (ndp_resp_mac) {
801 nan_parse_mac_address(dut, ndp_resp_mac,
802 init_req.peer_disc_mac_addr);
803 sigma_dut_print(
804 dut, DUT_MSG_INFO, "PEER MAC ADDR: " MAC_ADDR_STR,
805 MAC_ADDR_ARRAY(init_req.peer_disc_mac_addr));
806 } else {
807 memcpy(init_req.peer_disc_mac_addr, global_peer_mac_addr,
808 sizeof(init_req.peer_disc_mac_addr));
809 }
810
811 /* Not requesting the channel and letting FW decide */
812 if (dut->sta_channel == 0) {
813 init_req.channel_request_type = NAN_DP_CHANNEL_NOT_REQUESTED;
814 init_req.channel = 0;
815 } else {
816 init_req.channel_request_type = NAN_DP_FORCE_CHANNEL_SETUP;
817 init_req.channel = channel_to_freq(dut->sta_channel);
818 }
819 sigma_dut_print(dut, DUT_MSG_INFO,
820 "%s: Initiator Request: Channel = %d Channel Request Type = %d",
821 __func__, init_req.channel,
822 init_req.channel_request_type);
823
824 if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) {
Rakesh Sunki395b0152017-05-16 15:30:36 -0700825 init_req.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700826 memcpy(&init_req.key_info.body.pmk_info.pmk[0],
827 &dut->nan_pmk[0], NAN_PMK_INFO_LEN);
828 init_req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
829 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
830 __func__,
831 init_req.key_info.body.pmk_info.pmk_len);
832 }
833
834 ret = nan_data_request_initiator(0, global_interface_handle, &init_req);
835 if (ret != WIFI_SUCCESS) {
836 send_resp(dut, conn, SIGMA_ERROR,
837 "Unable to initiate nan data request");
838 return 0;
839 }
840
841 return 0;
842}
843
844
Rakesh Sunkia5cc2842017-03-30 14:47:55 -0700845static int sigma_nan_data_response(struct sigma_dut *dut,
846 struct sigma_conn *conn,
847 struct sigma_cmd *cmd)
848{
849 const char *ndl_response = get_param(cmd, "NDLresponse");
850 const char *m4_response_type = get_param(cmd, "M4ResponseType");
851 wifi_error ret;
852 NanDebugParams cfg_debug;
853 int size;
854
855 if (ndl_response) {
856 int auto_responder_mode_val = 0;
857
858 sigma_dut_print(dut, DUT_MSG_INFO,
859 "%s: ndl_response = (%s) is passed",
860 __func__, ndl_response);
861 memset(&cfg_debug, 0, sizeof(NanDebugParams));
862 cfg_debug.cmd = NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE;
863 if (strcasecmp(ndl_response, "Auto") == 0) {
864 auto_responder_mode_val = NAN_DATA_RESPONDER_MODE_AUTO;
865 } else if (strcasecmp(ndl_response, "Reject") == 0) {
866 auto_responder_mode_val =
867 NAN_DATA_RESPONDER_MODE_REJECT;
868 } else if (strcasecmp(ndl_response, "Accept") == 0) {
869 auto_responder_mode_val =
870 NAN_DATA_RESPONDER_MODE_ACCEPT;
871 } else if (strcasecmp(ndl_response, "Counter") == 0) {
872 auto_responder_mode_val =
873 NAN_DATA_RESPONDER_MODE_COUNTER;
874 } else {
875 sigma_dut_print(dut, DUT_MSG_ERROR,
876 "%s: Invalid ndl_response",
877 __func__);
878 return 0;
879 }
880 memcpy(cfg_debug.debug_cmd_data, &auto_responder_mode_val,
881 sizeof(int));
882 size = sizeof(u32) + sizeof(int);
883 ret = nan_debug_command_config(0, global_interface_handle,
884 cfg_debug, size);
885 if (ret != WIFI_SUCCESS) {
886 send_resp(dut, conn, SIGMA_ERROR,
887 "Nan config request failed");
888 }
889 }
890
891 if (m4_response_type) {
892 int m4_response_type_val = 0;
893
894 sigma_dut_print(dut, DUT_MSG_INFO,
895 "%s: m4_response_type = (%s) is passed",
896 __func__, m4_response_type);
897 memset(&cfg_debug, 0, sizeof(NanDebugParams));
898 cfg_debug.cmd = NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE;
899 if (strcasecmp(m4_response_type, "Accept") == 0)
900 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_ACCEPT;
901 else if (strcasecmp(m4_response_type, "Reject") == 0)
902 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_REJECT;
903 else if (strcasecmp(m4_response_type, "BadMic") == 0)
904 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_BADMIC;
905
906 memcpy(cfg_debug.debug_cmd_data, &m4_response_type_val,
907 sizeof(int));
908 size = sizeof(u32) + sizeof(int);
909 ret = nan_debug_command_config(0, global_interface_handle,
910 cfg_debug, size);
911 if (ret != WIFI_SUCCESS) {
912 send_resp(dut, conn, SIGMA_ERROR,
913 "Nan config request failed");
914 }
915 }
916
917 return 0;
918}
919
920
Rakesh Sunki8a630b82017-03-30 14:47:55 -0700921static int sigma_nan_data_end(struct sigma_dut *dut, struct sigma_cmd *cmd)
922{
923 const char *nmf_security_config = get_param(cmd, "Security");
924 NanDataPathEndRequest req;
925 NanDebugParams cfg_debug;
926 int size;
927
928 memset(&req, 0, sizeof(NanDataPathEndRequest));
929 memset(&cfg_debug, 0, sizeof(NanDebugParams));
930 if (nmf_security_config) {
931 int nmf_security_config_val = 0;
932
933 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_NMF_CLEAR_CONFIG;
934 if (strcasecmp(nmf_security_config, "open") == 0)
935 nmf_security_config_val = NAN_NMF_CLEAR_ENABLE;
936 else if (strcasecmp(nmf_security_config, "secure") == 0)
937 nmf_security_config_val = NAN_NMF_CLEAR_DISABLE;
938 memcpy(cfg_debug.debug_cmd_data,
939 &nmf_security_config_val, sizeof(int));
940 size = sizeof(u32) + sizeof(int);
941 sigma_dut_print(dut, DUT_MSG_INFO,
942 "%s: nmf_security_config_val -- cmd type = %d and command data = %d",
943 __func__, cfg_debug.cmd,
944 nmf_security_config_val);
945 nan_debug_command_config(0, global_interface_handle,
946 cfg_debug, size);
947 }
948
949 req.num_ndp_instances = 1;
950 req.ndp_instance_id[0] = global_ndp_instance_id;
951
952 nan_data_end(0, global_interface_handle, &req);
953 return 0;
954}
955
956
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -0700957static int sigma_nan_range_request(struct sigma_dut *dut,
958 struct sigma_cmd *cmd)
959{
960 const char *dest_mac = get_param(cmd, "destmac");
961 NanSubscribeRequest req;
962
963 memset(&req, 0, sizeof(NanSubscribeRequest));
964 req.period = 1;
Rakesh Sunki3834be52017-08-16 15:27:36 -0700965 req.subscribe_type = NAN_SUBSCRIBE_TYPE_PASSIVE;
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -0700966 req.serviceResponseFilter = NAN_SRF_ATTR_BLOOM_FILTER;
967 req.serviceResponseInclude = NAN_SRF_INCLUDE_RESPOND;
968 req.ssiRequiredForMatchIndication = NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
969 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
970 req.subscribe_count = 0;
971 strlcpy((char *) req.service_name, DEFAULT_SVC,
972 NAN_MAX_SERVICE_NAME_LEN);
973 req.service_name_len = strlen((char *) req.service_name);
974
975 req.subscribe_id = global_subscribe_id;
976 req.sdea_params.ranging_state = 1;
977 req.sdea_params.range_report = NAN_ENABLE_RANGE_REPORT;
978 req.range_response_cfg.requestor_instance_id = global_match_handle;
979 req.range_response_cfg.ranging_response = NAN_RANGE_REQUEST_ACCEPT;
980 req.ranging_cfg.config_ranging_indications =
981 NAN_RANGING_INDICATE_CONTINUOUS_MASK;
982 if (dest_mac) {
983 nan_parse_mac_address(dut, dest_mac,
984 req.range_response_cfg.peer_addr);
985 sigma_dut_print(
986 dut, DUT_MSG_INFO, "peer mac addr: " MAC_ADDR_STR,
987 MAC_ADDR_ARRAY(req.range_response_cfg.peer_addr));
988 }
989 nan_subscribe_request(0, global_interface_handle, &req);
990
991 return 0;
992}
993
994
995static int sigma_nan_cancel_range(struct sigma_dut *dut,
996 struct sigma_cmd *cmd)
997{
998 const char *dest_mac = get_param(cmd, "destmac");
999 NanPublishRequest req;
1000
1001 memset(&req, 0, sizeof(NanPublishRequest));
1002 req.ttl = 0;
1003 req.period = 1;
1004 req.publish_match_indicator = 1;
1005 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
1006 req.tx_type = NAN_TX_TYPE_BROADCAST;
1007 req.publish_count = 0;
1008 strlcpy((char *) req.service_name, DEFAULT_SVC,
1009 NAN_MAX_SERVICE_NAME_LEN);
1010 req.service_name_len = strlen((char *) req.service_name);
1011 req.publish_id = global_publish_id;
1012 req.range_response_cfg.ranging_response = NAN_RANGE_REQUEST_CANCEL;
1013 if (dest_mac) {
1014 nan_parse_mac_address(dut, dest_mac,
1015 req.range_response_cfg.peer_addr);
1016 sigma_dut_print(
1017 dut, DUT_MSG_INFO, "peer mac addr: " MAC_ADDR_STR,
1018 MAC_ADDR_ARRAY(req.range_response_cfg.peer_addr));
1019 }
1020 nan_publish_request(0, global_interface_handle, &req);
1021
1022 return 0;
1023}
1024
1025
Rakesh Sunkib2b65162017-03-30 14:47:55 -07001026static int sigma_nan_schedule_update(struct sigma_dut *dut,
1027 struct sigma_cmd *cmd)
1028{
1029 const char *schedule_update_type = get_param(cmd, "type");
1030 const char *channel_availability = get_param(cmd,
1031 "ChannelAvailability");
1032 const char *responder_nmi_mac = get_param(cmd, "ResponderNMI");
1033 NanDebugParams cfg_debug;
1034 int size = 0;
1035
1036 memset(&cfg_debug, 0, sizeof(NanDebugParams));
1037
1038 if (!schedule_update_type)
1039 return 0;
1040
1041 if (strcasecmp(schedule_update_type, "ULWnotify") == 0) {
1042 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY;
1043 size = sizeof(u32);
1044 sigma_dut_print(dut, DUT_MSG_INFO,
1045 "%s: Schedule Update cmd type = %d", __func__,
1046 cfg_debug.cmd);
1047 if (channel_availability) {
1048 int channel_availability_val;
1049
1050 channel_availability_val = atoi(channel_availability);
1051 size += sizeof(int);
1052 memcpy(cfg_debug.debug_cmd_data,
1053 &channel_availability_val, sizeof(int));
1054 sigma_dut_print(dut, DUT_MSG_INFO,
1055 "%s: Schedule Update cmd data = %d size = %d",
1056 __func__, channel_availability_val,
1057 size);
1058 }
1059 } else if (strcasecmp(schedule_update_type, "NDLnegotiate") == 0) {
1060 cfg_debug.cmd =
1061 NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE;
1062 size = sizeof(u32);
1063 sigma_dut_print(dut, DUT_MSG_INFO,
1064 "%s: Schedule Update cmd type = %d", __func__,
1065 cfg_debug.cmd);
1066 if (responder_nmi_mac) {
1067 u8 responder_nmi_mac_addr[NAN_MAC_ADDR_LEN];
1068
1069 nan_parse_mac_address(dut, responder_nmi_mac,
1070 responder_nmi_mac_addr);
1071 size += NAN_MAC_ADDR_LEN;
1072 memcpy(cfg_debug.debug_cmd_data, responder_nmi_mac_addr,
1073 NAN_MAC_ADDR_LEN);
1074 sigma_dut_print(dut, DUT_MSG_INFO,
1075 "%s: RESPONDER NMI MAC: "MAC_ADDR_STR,
1076 __func__,
1077 MAC_ADDR_ARRAY(responder_nmi_mac_addr));
1078 sigma_dut_print(dut, DUT_MSG_INFO,
1079 "%s: Schedule Update: cmd size = %d",
1080 __func__, size);
1081 }
1082 } else if (strcasecmp(schedule_update_type, "NDLnotify") == 0) {
1083 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY;
1084 size = sizeof(u32);
1085 sigma_dut_print(dut, DUT_MSG_INFO,
1086 "%s: Schedule Update cmd type = %d", __func__,
1087 cfg_debug.cmd);
1088 }
1089
1090 nan_debug_command_config(0, global_interface_handle, cfg_debug, size);
1091
1092 return 0;
1093}
1094
1095
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001096int config_post_disc_attr(void)
1097{
Rakesh Sunki107356c2017-03-30 14:47:55 -07001098 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001099 NanConfigRequest configReq;
1100
1101 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001102
1103 /* Configure Post disc attr */
1104 /* Make these defines and use correct enum */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001105 configReq.num_config_discovery_attr = 1;
1106 configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */
1107 configReq.discovery_attr_val[0].role = 0;
1108 configReq.discovery_attr_val[0].transmit_freq = 1;
1109 configReq.discovery_attr_val[0].duration = 0;
1110 configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001111
Rakesh Sunki107356c2017-03-30 14:47:55 -07001112 ret = nan_config_request(0, global_interface_handle, &configReq);
1113 if (ret != WIFI_SUCCESS) {
1114 sigma_dut_print(global_dut, DUT_MSG_INFO,
1115 "NAN config request failed while configuring post discovery attribute");
1116 }
1117
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001118 return 0;
1119}
1120
1121
1122int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn,
1123 struct sigma_cmd *cmd)
1124{
1125 const char *publish_type = get_param(cmd, "PublishType");
1126 const char *service_name = get_param(cmd, "ServiceName");
1127 const char *disc_range = get_param(cmd, "DiscoveryRange");
1128 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
1129 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
1130 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
1131 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001132 const char *ndp_enable = get_param(cmd, "DataPathFlag");
1133 const char *ndp_type = get_param(cmd, "DataPathType");
1134 const char *data_path_security = get_param(cmd, "datapathsecurity");
Rakesh Sunki48060402017-03-30 14:47:55 -07001135 const char *range_required = get_param(cmd, "rangerequired");
Rakesh Sunki8a4845d2017-05-16 15:27:13 -07001136#if NAN_CERT_VERSION >= 3
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -07001137 const char *awake_dw_interval = get_param(cmd, "awakeDWint");
Rakesh Sunki8a4845d2017-05-16 15:27:13 -07001138 const char *qos_config = get_param(cmd, "QoS");
1139#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001140 NanPublishRequest req;
Rakesh Sunkie6f66832017-05-16 15:22:48 -07001141 NanConfigRequest config_req;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001142 int filter_len_rx = 0, filter_len_tx = 0;
1143 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
1144 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -07001145 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001146
1147 memset(&req, 0, sizeof(NanPublishRequest));
Rakesh Sunkie6f66832017-05-16 15:22:48 -07001148 memset(&config_req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001149 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -07001150 req.period = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001151 req.publish_match_indicator = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001152 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
1153 req.tx_type = NAN_TX_TYPE_BROADCAST;
1154 req.publish_count = 0;
Rakesh Sunki0a0eea82017-03-30 14:47:55 -07001155 req.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_ALL;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001156
Rakesh Sunki42363682017-05-16 15:00:42 -07001157 if (global_publish_service_name_len &&
1158 service_name &&
1159 strcasecmp((char *) global_publish_service_name,
1160 service_name) == 0 &&
1161 global_publish_id) {
1162 req.publish_id = global_publish_id;
1163 sigma_dut_print(dut, DUT_MSG_INFO,
1164 "%s: updating publish_id = %d in publish request",
1165 __func__, req.publish_id);
1166 }
1167
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001168 if (service_name) {
1169 strlcpy((char *) req.service_name, service_name,
Rakesh Sunki42363682017-05-16 15:00:42 -07001170 sizeof(req.service_name));
1171 req.service_name_len = strlen((char *) req.service_name);
1172 strlcpy((char *) global_publish_service_name, service_name,
1173 sizeof(global_publish_service_name));
1174 global_publish_service_name_len =
1175 strlen((char *) global_publish_service_name);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001176 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001177
1178 if (publish_type) {
1179 if (strcasecmp(publish_type, "Solicited") == 0) {
1180 req.publish_type = NAN_PUBLISH_TYPE_SOLICITED;
Rakesh Sunki62644ab2017-03-30 14:47:55 -07001181 } else if (strcasecmp(publish_type, "Unsolicited") == 0) {
1182 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001183 } else if (strcasecmp(publish_type, "Cancel") == 0) {
1184 NanPublishCancelRequest req;
1185
1186 memset(&req, 0, sizeof(NanPublishCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -07001187 ret = nan_publish_cancel_request(
1188 0, global_interface_handle, &req);
1189 if (ret != WIFI_SUCCESS) {
1190 send_resp(dut, conn, SIGMA_ERROR,
1191 "Unable to cancel nan publish request");
1192 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001193 return 0;
1194 }
1195 }
1196
1197 if (disc_range)
1198 req.rssi_threshold_flag = atoi(disc_range);
1199
1200 if (sdftx_dw)
1201 req.publish_count = atoi(sdftx_dw);
1202
1203 if (discrange_ltd)
1204 req.rssi_threshold_flag = atoi(discrange_ltd);
1205
1206 memset(input_rx, 0, sizeof(input_rx));
1207 memset(input_tx, 0, sizeof(input_tx));
1208 if (rx_match_filter) {
1209 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
1210 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
1211 filter_len_rx);
1212 }
1213 if (tx_match_filter) {
1214 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
1215 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
1216 filter_len_tx);
1217 }
1218
1219 if (is_fam == 1) {
1220 config_post_disc_attr();
Rakesh Sunkif680e0f2017-03-30 14:47:55 -07001221 /*
1222 * 8-bit bitmap which allows the Host to associate this publish
1223 * with a particular Post-NAN Connectivity attribute which has
1224 * been sent down in a NanConfigureRequest/NanEnableRequest
1225 * message. If the DE fails to find a configured Post-NAN
1226 * connectivity attributes referenced by the bitmap, the DE will
1227 * return an error code to the Host. If the Publish is
1228 * configured to use a Post-NAN Connectivity attribute and the
1229 * Host does not refresh the Post-NAN Connectivity attribute the
1230 * Publish will be canceled and the Host will be sent a
1231 * PublishTerminatedIndication message.
1232 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001233 req.connmap = 0x10;
1234 }
1235
1236 if (tx_match_filter) {
1237 req.tx_match_filter_len = filter_len_tx;
1238 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
1239 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
1240 }
1241
1242 if (rx_match_filter) {
1243 req.rx_match_filter_len = filter_len_rx;
1244 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
1245 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
1246 }
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001247
1248 if (service_name) {
1249 strlcpy((char *) req.service_name, service_name,
1250 strlen(service_name) + 1);
1251 req.service_name_len = strlen(service_name);
1252 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001253
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001254 if (ndp_enable) {
1255 if (strcasecmp(ndp_enable, "enable") == 0)
1256 req.sdea_params.config_nan_data_path = 1;
1257 else
1258 req.sdea_params.config_nan_data_path = 0;
1259
1260 if (ndp_type)
1261 req.sdea_params.ndp_type = atoi(ndp_type);
1262
1263 if (data_path_security) {
1264 if (strcasecmp(data_path_security, "secure") == 0) {
1265 req.sdea_params.security_cfg =
1266 NAN_DP_CONFIG_SECURITY;
1267 } else if (strcasecmp(data_path_security, "open") ==
1268 0) {
1269 req.sdea_params.security_cfg =
1270 NAN_DP_CONFIG_NO_SECURITY;
1271 }
1272 }
1273
1274 if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) {
Rakesh Sunki395b0152017-05-16 15:30:36 -07001275 req.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001276 memcpy(&req.key_info.body.pmk_info.pmk[0],
1277 &dut->nan_pmk[0], NAN_PMK_INFO_LEN);
1278 req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
1279 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
1280 __func__, req.key_info.body.pmk_info.pmk_len);
1281 }
1282 }
Rakesh Sunki48060402017-03-30 14:47:55 -07001283 if (range_required && strcasecmp(range_required, "enable") == 0) {
1284 req.sdea_params.ranging_state = NAN_RANGING_ENABLE;
1285 req.sdea_params.range_report = NAN_ENABLE_RANGE_REPORT;
1286 }
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001287
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -07001288#if NAN_CERT_VERSION >= 3
Rakesh Sunkie6f66832017-05-16 15:22:48 -07001289 if (awake_dw_interval) {
1290 int input_dw_interval_val = atoi(awake_dw_interval);
1291 int awake_dw_int = 0;
1292
1293 if (input_dw_interval_val > NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL) {
1294 sigma_dut_print(dut, DUT_MSG_INFO,
1295 "%s: input active dw interval = %d overwritting dw interval to Max allowed dw interval 16",
1296 __func__, input_dw_interval_val);
1297 input_dw_interval_val =
1298 NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL;
1299 }
1300 sigma_dut_print(dut, DUT_MSG_INFO,
1301 "%s: input active DW interval = %d",
1302 __func__, input_dw_interval_val);
1303 /*
1304 * Indicates the interval for Sync beacons and SDF's in 2.4 GHz
1305 * or 5 GHz band. Valid values of DW Interval are: 1, 2, 3, 4,
1306 * and 5; 0 is reserved. The SDF includes in OTA when enabled.
1307 * The publish/subscribe period. values don't override the
1308 * device level configurations.
1309 * input_dw_interval_val is provided by the user are in the
1310 * format 2^n-1 = 1/2/4/8/16. Internal implementation expects n
1311 * to be passed to indicate the awake_dw_interval.
1312 */
1313 if (input_dw_interval_val == 1 ||
1314 input_dw_interval_val % 2 == 0) {
1315 while (input_dw_interval_val > 0) {
1316 input_dw_interval_val >>= 1;
1317 awake_dw_int++;
1318 }
1319 }
1320 sigma_dut_print(dut, DUT_MSG_INFO,
1321 "%s:converted active DW interval = %d",
1322 __func__, awake_dw_int);
1323 config_req.config_dw.config_2dot4g_dw_band = 1;
1324 config_req.config_dw.dw_2dot4g_interval_val = awake_dw_int;
1325 config_req.config_dw.config_5g_dw_band = 1;
1326 config_req.config_dw.dw_5g_interval_val = awake_dw_int;
1327 ret = nan_config_request(0, global_interface_handle,
1328 &config_req);
1329 if (ret != WIFI_SUCCESS) {
1330 sigma_dut_print(dut, DUT_MSG_ERROR,
1331 "%s:NAN config request failed",
1332 __func__);
1333 return -2;
1334 }
1335 }
1336
Rakesh Sunki8a4845d2017-05-16 15:27:13 -07001337 if (qos_config)
1338 req.sdea_params.qos_cfg = (NanQosCfgStatus) atoi(qos_config);
1339#endif
1340
Rakesh Sunki107356c2017-03-30 14:47:55 -07001341 ret = nan_publish_request(0, global_interface_handle, &req);
1342 if (ret != WIFI_SUCCESS)
1343 send_resp(dut, conn, SIGMA_ERROR, "Unable to publish");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001344
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001345 if (ndp_enable)
1346 dut->ndp_enable = 1;
1347
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001348 return 0;
1349}
1350
1351
1352static int nan_further_availability_rx(struct sigma_dut *dut,
1353 struct sigma_conn *conn,
1354 struct sigma_cmd *cmd)
1355{
1356 const char *master_pref = get_param(cmd, "MasterPref");
1357 const char *rand_fac = get_param(cmd, "RandFactor");
1358 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001359 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001360 struct timespec abstime;
1361
1362 NanEnableRequest req;
1363
1364 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001365 req.cluster_low = 0;
1366 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001367 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001368
1369 if (master_pref)
1370 req.master_pref = strtoul(master_pref, NULL, 0);
1371
1372 if (rand_fac) {
1373 int rand_fac_val = strtoul(rand_fac, NULL, 0);
1374
1375 req.config_random_factor_force = 1;
1376 req.random_factor_force_val = rand_fac_val;
1377 }
1378
1379 if (hop_count) {
1380 int hop_count_val = strtoul(hop_count, NULL, 0);
1381
1382 req.config_hop_count_force = 1;
1383 req.hop_count_force_val = hop_count_val;
1384 }
1385
Rakesh Sunki107356c2017-03-30 14:47:55 -07001386 ret = nan_enable_request(0, global_interface_handle, &req);
1387 if (ret != WIFI_SUCCESS) {
1388 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
1389 return 0;
1390 }
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001391
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001392 abstime.tv_sec = 4;
1393 abstime.tv_nsec = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001394 wait(abstime);
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001395
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001396 return 0;
1397}
1398
1399
1400static int nan_further_availability_tx(struct sigma_dut *dut,
1401 struct sigma_conn *conn,
1402 struct sigma_cmd *cmd)
1403{
1404 const char *master_pref = get_param(cmd, "MasterPref");
1405 const char *rand_fac = get_param(cmd, "RandFactor");
1406 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001407 wifi_error ret;
1408
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001409 NanEnableRequest req;
1410 NanConfigRequest configReq;
1411
1412 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001413 req.cluster_low = 0;
1414 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001415 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001416
1417 if (master_pref)
1418 req.master_pref = strtoul(master_pref, NULL, 0);
1419
1420 if (rand_fac) {
1421 int rand_fac_val = strtoul(rand_fac, NULL, 0);
1422
1423 req.config_random_factor_force = 1;
1424 req.random_factor_force_val = rand_fac_val;
1425 }
1426
1427 if (hop_count) {
1428 int hop_count_val = strtoul(hop_count, NULL, 0);
1429
1430 req.config_hop_count_force = 1;
1431 req.hop_count_force_val = hop_count_val;
1432 }
1433
Rakesh Sunki107356c2017-03-30 14:47:55 -07001434 ret = nan_enable_request(0, global_interface_handle, &req);
1435 if (ret != WIFI_SUCCESS) {
1436 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
1437 return 0;
1438 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001439
1440 /* Start the config of fam */
1441
1442 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001443
1444 configReq.config_fam = 1;
1445 configReq.fam_val.numchans = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001446 configReq.fam_val.famchan[0].entry_control = 0;
1447 configReq.fam_val.famchan[0].class_val = 81;
1448 configReq.fam_val.famchan[0].channel = 6;
1449 configReq.fam_val.famchan[0].mapid = 0;
1450 configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe;
1451
Rakesh Sunki107356c2017-03-30 14:47:55 -07001452 ret = nan_config_request(0, global_interface_handle, &configReq);
1453 if (ret != WIFI_SUCCESS)
1454 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001455
1456 return 0;
1457}
1458
1459
1460int sigma_nan_transmit_followup(struct sigma_dut *dut,
1461 struct sigma_conn *conn,
1462 struct sigma_cmd *cmd)
1463{
1464 const char *mac = get_param(cmd, "mac");
1465 const char *requestor_id = get_param(cmd, "RemoteInstanceId");
1466 const char *local_id = get_param(cmd, "LocalInstanceId");
1467 const char *service_name = get_param(cmd, "servicename");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001468 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001469 NanTransmitFollowupRequest req;
1470
1471 memset(&req, 0, sizeof(NanTransmitFollowupRequest));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001472 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001473 req.addr[0] = 0xFF;
1474 req.addr[1] = 0xFF;
1475 req.addr[2] = 0xFF;
1476 req.addr[3] = 0xFF;
1477 req.addr[4] = 0xFF;
1478 req.addr[5] = 0xFF;
1479 req.priority = NAN_TX_PRIORITY_NORMAL;
1480 req.dw_or_faw = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001481
1482 if (service_name)
1483 req.service_specific_info_len = strlen(service_name);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001484
1485 if (requestor_id) {
1486 /* int requestor_id_val = atoi(requestor_id); */
Rakesh Sunkifa417332017-08-16 15:41:32 -07001487 if (global_match_handle != 0) {
1488 req.requestor_instance_id = global_match_handle;
1489 } else {
1490 u32 requestor_id_val = atoi(requestor_id);
1491 requestor_id_val =
1492 (requestor_id_val << 24) | 0x0000FFFF;
1493 req.requestor_instance_id = requestor_id_val;
1494 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001495 }
1496 if (local_id) {
1497 /* int local_id_val = atoi(local_id); */
Rakesh Sunkifa417332017-08-16 15:41:32 -07001498 if (global_header_handle != 0)
1499 req.publish_subscribe_id = global_header_handle;
1500 else
1501 req.publish_subscribe_id = atoi(local_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001502 }
1503
1504 if (mac == NULL) {
1505 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address");
1506 return -1;
1507 }
1508 nan_parse_mac_address(dut, mac, req.addr);
1509
Rakesh Sunki107356c2017-03-30 14:47:55 -07001510 ret = nan_transmit_followup_request(0, global_interface_handle, &req);
1511 if (ret != WIFI_SUCCESS) {
1512 send_resp(dut, conn, SIGMA_ERROR,
1513 "Unable to complete nan transmit followup");
1514 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001515
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001516 return 0;
1517}
1518
Rakesh Sunki107356c2017-03-30 14:47:55 -07001519
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001520/* NotifyResponse invoked to notify the status of the Request */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001521void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001522{
1523 sigma_dut_print(global_dut, DUT_MSG_INFO,
Rakesh Sunkifdbd60b2017-03-30 14:47:55 -07001524 "%s: status %d response_type %d",
1525 __func__, rsp_data->status, rsp_data->response_type);
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001526 if (rsp_data->response_type == NAN_RESPONSE_STATS &&
1527 rsp_data->body.stats_response.stats_type ==
1528 NAN_STATS_ID_DE_TIMING_SYNC) {
1529 NanSyncStats *pSyncStats;
1530
1531 sigma_dut_print(global_dut, DUT_MSG_INFO,
1532 "%s: stats_type %d", __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001533 rsp_data->body.stats_response.stats_type);
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001534 pSyncStats = &rsp_data->body.stats_response.data.sync_stats;
1535 memcpy(&global_nan_sync_stats, pSyncStats,
1536 sizeof(NanSyncStats));
1537 pthread_cond_signal(&gCondition);
Rakesh Sunki4d5912d2017-03-30 14:47:55 -07001538 } else if (rsp_data->response_type == NAN_RESPONSE_PUBLISH) {
1539 sigma_dut_print(global_dut, DUT_MSG_INFO,
1540 "%s: publish_id %d\n",
1541 __func__,
1542 rsp_data->body.publish_response.publish_id);
1543 global_publish_id = rsp_data->body.publish_response.publish_id;
1544 } else if (rsp_data->response_type == NAN_RESPONSE_SUBSCRIBE) {
1545 sigma_dut_print(global_dut, DUT_MSG_INFO,
1546 "%s: subscribe_id %d\n",
1547 __func__,
1548 rsp_data->body.subscribe_response.subscribe_id);
1549 global_subscribe_id =
1550 rsp_data->body.subscribe_response.subscribe_id;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001551 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001552}
1553
1554
1555/* Events Callback */
1556void nan_event_publish_replied(NanPublishRepliedInd *event)
1557{
1558 sigma_dut_print(global_dut, DUT_MSG_INFO,
1559 "%s: handle %d " MAC_ADDR_STR " rssi:%d",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001560 __func__, event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001561 MAC_ADDR_ARRAY(event->addr), event->rssi_value);
1562 event_anyresponse = 1;
1563 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
Rakesh Sunkifa417332017-08-16 15:41:32 -07001564 "EventName,Replied,RemoteInstanceID,%d,LocalInstanceID,%d,mac," MAC_ADDR_STR" ",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001565 (event->requestor_instance_id >> 24),
Rakesh Sunkifa417332017-08-16 15:41:32 -07001566 (event->requestor_instance_id & 0xFFFF),
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001567 MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001568}
1569
1570
1571/* Events Callback */
1572void nan_event_publish_terminated(NanPublishTerminatedInd *event)
1573{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001574 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d",
1575 __func__, event->publish_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001576}
1577
1578
1579/* Events Callback */
1580void nan_event_match(NanMatchInd *event)
1581{
1582 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001583 "%s: Pub/Sub Id %d remote_requestor_id %08x "
1584 MAC_ADDR_STR
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001585 " rssi:%d",
1586 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001587 event->publish_subscribe_id,
1588 event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001589 MAC_ADDR_ARRAY(event->addr),
1590 event->rssi_value);
1591 event_anyresponse = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001592 global_header_handle = event->publish_subscribe_id;
1593 global_match_handle = event->requestor_instance_id;
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07001594 memcpy(global_peer_mac_addr, event->addr, sizeof(global_peer_mac_addr));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001595
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001596 /* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */
1597 /* global_pub_sub_handle = event->header.handle; */
1598 /* Print the SSI */
1599 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001600 nan_hex_dump(global_dut, event->service_specific_info,
1601 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001602 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1603 "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001604 MAC_ADDR_STR " ", (event->requestor_instance_id >> 24),
1605 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001606
1607 /* Print the match filter */
1608 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001609 nan_hex_dump(global_dut, event->sdf_match_filter,
1610 event->sdf_match_filter_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001611
1612 /* Print the conn_capability */
1613 sigma_dut_print(global_dut, DUT_MSG_INFO,
1614 "Printing PostConnectivity Capability");
1615 if (event->is_conn_capability_valid) {
1616 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s",
1617 event->conn_capability.is_wfd_supported ?
1618 "yes" : "no");
1619 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s",
1620 (event->conn_capability.is_wfds_supported ?
1621 "yes" : "no"));
1622 sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s",
1623 (event->conn_capability.is_tdls_supported ?
1624 "yes" : "no"));
1625 sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s",
1626 (event->conn_capability.is_ibss_supported ?
1627 "yes" : "no"));
1628 sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s",
1629 (event->conn_capability.is_mesh_supported ?
1630 "yes" : "no"));
1631 sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d",
1632 event->conn_capability.wlan_infra_field);
1633 } else {
1634 sigma_dut_print(global_dut, DUT_MSG_INFO,
1635 "PostConnectivity Capability not present");
1636 }
1637
1638 /* Print the discovery_attr */
1639 sigma_dut_print(global_dut, DUT_MSG_INFO,
1640 "Printing PostDiscovery Attribute");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001641 if (event->num_rx_discovery_attr) {
1642 int idx;
1643
1644 for (idx = 0; idx < event->num_rx_discovery_attr; idx++) {
1645 sigma_dut_print(global_dut, DUT_MSG_INFO,
1646 "PostDiscovery Attribute - %d", idx);
1647 sigma_dut_print(global_dut, DUT_MSG_INFO,
1648 "Conn Type:%d Device Role:%d"
1649 MAC_ADDR_STR,
1650 event->discovery_attr[idx].type,
1651 event->discovery_attr[idx].role,
1652 MAC_ADDR_ARRAY(event->discovery_attr[idx].addr));
1653 sigma_dut_print(global_dut, DUT_MSG_INFO,
1654 "Duration:%d MapId:%d "
1655 "avail_interval_bitmap:%04x",
1656 event->discovery_attr[idx].duration,
1657 event->discovery_attr[idx].mapid,
1658 event->discovery_attr[idx].avail_interval_bitmap);
1659 sigma_dut_print(global_dut, DUT_MSG_INFO,
1660 "Printing Mesh Id:");
1661 nan_hex_dump(global_dut,
1662 event->discovery_attr[idx].mesh_id,
1663 event->discovery_attr[idx].mesh_id_len);
1664 sigma_dut_print(global_dut, DUT_MSG_INFO,
1665 "Printing Infrastructure Ssid:");
1666 nan_hex_dump(global_dut,
1667 event->discovery_attr[idx].infrastructure_ssid_val,
1668 event->discovery_attr[idx].infrastructure_ssid_len);
1669 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001670 } else {
1671 sigma_dut_print(global_dut, DUT_MSG_INFO,
1672 "PostDiscovery attribute not present");
1673 }
1674
1675 /* Print the fam */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001676 if (event->num_chans) {
1677 nan_print_further_availability_chan(global_dut,
1678 event->num_chans,
1679 &event->famchan[0]);
1680 } else {
1681 sigma_dut_print(global_dut, DUT_MSG_INFO,
1682 "Further Availability Map not present");
1683 }
1684 if (event->cluster_attribute_len) {
1685 sigma_dut_print(global_dut, DUT_MSG_INFO,
1686 "Printing Cluster Attribute:");
1687 nan_hex_dump(global_dut, event->cluster_attribute,
1688 event->cluster_attribute_len);
1689 } else {
1690 sigma_dut_print(global_dut, DUT_MSG_INFO,
1691 "Cluster Attribute not present");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001692 }
1693}
1694
1695
1696/* Events Callback */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001697void nan_event_match_expired(NanMatchExpiredInd *event)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001698{
1699 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001700 "%s: publish_subscribe_id %d match_handle %08x",
1701 __func__, event->publish_subscribe_id,
1702 event->requestor_instance_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001703}
1704
1705
1706/* Events Callback */
1707void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event)
1708{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001709 sigma_dut_print(global_dut, DUT_MSG_INFO,
1710 "%s: Subscribe Id %d reason %d",
1711 __func__, event->subscribe_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001712}
1713
1714
1715/* Events Callback */
1716void nan_event_followup(NanFollowupInd *event)
1717{
1718 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001719 "%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d "
1720 MAC_ADDR_STR, __func__, event->publish_subscribe_id,
1721 event->requestor_instance_id, event->dw_or_faw,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001722 MAC_ADDR_ARRAY(event->addr));
1723
Rakesh Sunkifa417332017-08-16 15:41:32 -07001724 global_match_handle = event->requestor_instance_id;
1725 global_header_handle = event->publish_subscribe_id;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001726 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__);
1727 nan_hex_dump(global_dut, event->service_specific_info,
1728 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001729 event_anyresponse = 1;
1730 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1731 "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001732 MAC_ADDR_STR " ", event->requestor_instance_id >> 24,
1733 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001734}
1735
1736
1737/* Events Callback */
1738void nan_event_disceng_event(NanDiscEngEventInd *event)
1739{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001740 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d",
1741 __func__, event->event_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001742
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001743 if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001744 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster "
1745 MAC_ADDR_STR,
1746 __func__,
1747 MAC_ADDR_ARRAY(event->data.cluster.addr));
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001748 /* To ensure sta_get_events to get the events
1749 * only after joining the NAN cluster. */
1750 pthread_cond_signal(&gCondition);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001751 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001752 if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001753 sigma_dut_print(global_dut, DUT_MSG_INFO,
1754 "%s: Started cluster " MAC_ADDR_STR,
1755 __func__,
1756 MAC_ADDR_ARRAY(event->data.cluster.addr));
1757 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001758 if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) {
1759 sigma_dut_print(global_dut, DUT_MSG_INFO,
1760 "%s: Discovery Mac Address "
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001761 MAC_ADDR_STR,
1762 __func__,
1763 MAC_ADDR_ARRAY(event->data.mac_addr.addr));
1764 memcpy(global_nan_mac_addr, event->data.mac_addr.addr,
1765 sizeof(global_nan_mac_addr));
1766 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001767}
1768
1769
1770/* Events Callback */
1771void nan_event_disabled(NanDisabledInd *event)
1772{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001773 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d",
1774 __func__, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001775 /* pthread_cond_signal(&gCondition); */
1776}
1777
1778
Rakesh Sunki4c086672017-03-30 14:47:55 -07001779/* Events callback */
1780static void ndp_event_data_indication(NanDataPathRequestInd *event)
1781{
1782 sigma_dut_print(global_dut, DUT_MSG_INFO,
1783 "%s: Service Instance Id: %d Peer Discovery MAC ADDR "
1784 MAC_ADDR_STR
1785 " NDP Instance Id: %d App Info len %d App Info %s",
1786 __func__,
1787 event->service_instance_id,
1788 MAC_ADDR_ARRAY(event->peer_disc_mac_addr),
1789 event->ndp_instance_id,
1790 event->app_info.ndp_app_info_len,
1791 event->app_info.ndp_app_info);
1792
1793 global_ndp_instance_id = event->ndp_instance_id;
1794}
1795
1796
1797/* Events callback */
1798static void ndp_event_data_confirm(NanDataPathConfirmInd *event)
1799{
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07001800 char cmd[200];
1801 char ipv6_buf[100];
1802
Rakesh Sunki4c086672017-03-30 14:47:55 -07001803 sigma_dut_print(global_dut, DUT_MSG_INFO,
1804 "Received NDP Confirm Indication");
1805
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07001806 memset(cmd, 0, sizeof(cmd));
1807 memset(ipv6_buf, 0, sizeof(ipv6_buf));
1808
Rakesh Sunki4c086672017-03-30 14:47:55 -07001809 global_ndp_instance_id = event->ndp_instance_id;
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07001810
1811 if (event->rsp_code == NAN_DP_REQUEST_ACCEPT) {
1812 if (system("ifconfig nan0 up") != 0) {
1813 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1814 "Failed to set nan interface up");
1815 return;
1816 }
1817 if (system("ip -6 route add fe80::/64 dev nan0 table local") !=
1818 0) {
1819 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1820 "Failed to run:ip -6 route replace fe80::/64 dev nan0 table local");
1821 }
1822 convert_mac_addr_to_ipv6_lladdr(event->peer_ndi_mac_addr,
1823 ipv6_buf, sizeof(ipv6_buf));
1824 snprintf(cmd, sizeof(cmd),
1825 "ip -6 neighbor replace %s lladdr %02x:%02x:%02x:%02x:%02x:%02x nud permanent dev nan0",
1826 ipv6_buf, event->peer_ndi_mac_addr[0],
1827 event->peer_ndi_mac_addr[1],
1828 event->peer_ndi_mac_addr[2],
1829 event->peer_ndi_mac_addr[3],
1830 event->peer_ndi_mac_addr[4],
1831 event->peer_ndi_mac_addr[5]);
1832 sigma_dut_print(global_dut, DUT_MSG_INFO,
1833 "neighbor replace cmd = %s", cmd);
1834 if (system(cmd) != 0) {
1835 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1836 "Failed to run: ip -6 neighbor replace");
1837 return;
1838 }
Rakesh Sunki4c086672017-03-30 14:47:55 -07001839 }
1840}
1841
1842
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001843void * my_thread_function(void *ptr)
1844{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001845 wifi_event_loop(global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001846 pthread_exit(0);
1847 return (void *) NULL;
1848}
1849
1850
1851static NanCallbackHandler callbackHandler = {
1852 .NotifyResponse = nan_notify_response,
1853 .EventPublishReplied = nan_event_publish_replied,
1854 .EventPublishTerminated = nan_event_publish_terminated,
1855 .EventMatch = nan_event_match,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001856 .EventMatchExpired = nan_event_match_expired,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001857 .EventSubscribeTerminated = nan_event_subscribe_terminated,
1858 .EventFollowup = nan_event_followup,
1859 .EventDiscEngEvent = nan_event_disceng_event,
1860 .EventDisabled = nan_event_disabled,
Rakesh Sunki4c086672017-03-30 14:47:55 -07001861 .EventDataRequest = ndp_event_data_indication,
1862 .EventDataConfirm = ndp_event_data_confirm,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001863};
1864
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001865
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001866void nan_init(struct sigma_dut *dut)
1867{
1868 pthread_t thread1; /* thread variables */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001869 wifi_error err = wifi_initialize(&global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001870
1871 if (err) {
1872 printf("wifi hal initialize failed\n");
1873 return;
1874 }
1875
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001876 global_interface_handle = wifi_get_iface_handle(global_wifi_handle,
1877 (char *) "wlan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001878 /* create threads 1 */
1879 pthread_create(&thread1, NULL, &my_thread_function, NULL);
1880
1881 pthread_mutex_init(&gMutex, NULL);
1882 pthread_cond_init(&gCondition, NULL);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001883 if (global_interface_handle)
1884 nan_register_handler(global_interface_handle, callbackHandler);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001885}
1886
1887
1888void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1889 struct sigma_cmd *cmd)
1890{
1891 sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default");
1892
1893 if (nan_state == 0) {
1894 nan_init(dut);
1895 nan_state = 1;
1896 }
1897 is_fam = 0;
1898 event_anyresponse = 0;
1899 global_dut = dut;
Rakesh Sunki7d37f412017-03-30 14:47:55 -07001900 memset(&dut->nan_pmk[0], 0, NAN_PMK_INFO_LEN);
1901 dut->nan_pmk_len = 0;
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001902 dut->sta_channel = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001903 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001904 memset(&global_nan_sync_stats, 0, sizeof(global_nan_sync_stats));
Rakesh Sunki42363682017-05-16 15:00:42 -07001905 memset(global_publish_service_name, 0,
1906 sizeof(global_publish_service_name));
1907 global_publish_service_name_len = 0;
1908 global_publish_id = 0;
Rakesh Sunki0262cb52017-05-17 14:22:05 -07001909 global_subscribe_id = 0;
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001910
Rakesh Sunki8a630b82017-03-30 14:47:55 -07001911 sigma_nan_data_end(dut, cmd);
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001912 nan_data_interface_delete(0, global_interface_handle, (char *) "nan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001913 sigma_nan_disable(dut, conn, cmd);
Rakesh Sunkifa417332017-08-16 15:41:32 -07001914 global_header_handle = 0;
1915 global_match_handle = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001916}
1917
1918
1919int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1920 struct sigma_cmd *cmd)
1921{
1922 const char *program = get_param(cmd, "Prog");
1923 const char *nan_op = get_param(cmd, "NANOp");
1924 const char *method_type = get_param(cmd, "MethodType");
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001925 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001926 char resp_buf[100];
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001927 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001928
1929 if (program == NULL)
1930 return -1;
1931
1932 if (strcasecmp(program, "NAN") != 0) {
1933 send_resp(dut, conn, SIGMA_ERROR,
1934 "ErrorCode,Unsupported program");
1935 return 0;
1936 }
1937
1938 if (nan_op) {
Rakesh Sunkib5604ff2017-05-16 15:47:08 -07001939#if NAN_CERT_VERSION >= 3
1940 int size = 0;
1941 u32 device_type_val = 0;
1942 NanDebugParams cfg_debug;
1943
1944 memset(&cfg_debug, 0, sizeof(NanDebugParams));
1945 cfg_debug.cmd = NAN_TEST_MODE_CMD_DEVICE_TYPE;
1946 if (dut->device_type == STA_testbed)
1947 device_type_val = NAN_DEVICE_TYPE_TEST_BED;
1948 else if (dut->device_type == STA_dut)
1949 device_type_val = NAN_DEVICE_TYPE_DUT;
1950
1951 memcpy(cfg_debug.debug_cmd_data, &device_type_val, sizeof(u32));
1952 size = sizeof(u32) + sizeof(u32);
1953 sigma_dut_print(dut, DUT_MSG_INFO,
1954 "%s: Device Type: cmd type = %d and command data = %u",
1955 __func__, cfg_debug.cmd, device_type_val);
1956 nan_debug_command_config(0, global_interface_handle,
1957 cfg_debug, size);
1958#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001959 /*
1960 * NANOp has been specified.
1961 * We will build a nan_enable or nan_disable command.
1962 */
1963 if (strcasecmp(nan_op, "On") == 0) {
1964 if (sigma_nan_enable(dut, conn, cmd) == 0) {
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001965 ret = nan_data_interface_create(
1966 0, global_interface_handle,
1967 (char *) "nan0");
1968 if (ret != WIFI_SUCCESS) {
1969 sigma_dut_print(
1970 global_dut, DUT_MSG_ERROR,
1971 "Unable to create NAN data interface");
1972 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001973 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1974 MAC_ADDR_STR,
1975 MAC_ADDR_ARRAY(global_nan_mac_addr));
1976 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1977 } else {
1978 send_resp(dut, conn, SIGMA_ERROR,
1979 "NAN_ENABLE_FAILED");
1980 return -1;
1981 }
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001982
1983 if (band && strcasecmp(band, "24g") == 0) {
1984 sigma_dut_print(dut, DUT_MSG_INFO,
1985 "%s: Setting band to 2G Only",
1986 __func__);
1987 sigma_ndp_configure_band(
1988 dut, conn, cmd,
1989 NAN_DATA_PATH_SUPPORTED_BAND_2G);
1990 } else if (band && dut->sta_channel > 12) {
1991 sigma_ndp_configure_band(
1992 dut, conn, cmd,
1993 NAN_DATA_PATH_SUPPORT_DUAL_BAND);
1994 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001995 } else if (strcasecmp(nan_op, "Off") == 0) {
Rakesh Sunkibcf9ef32017-08-16 15:53:27 -07001996 nan_data_interface_delete(0,
1997 global_interface_handle, (char *) "nan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001998 sigma_nan_disable(dut, conn, cmd);
Rakesh Sunki42363682017-05-16 15:00:42 -07001999 memset(global_publish_service_name, 0,
2000 sizeof(global_publish_service_name));
2001 global_publish_service_name_len = 0;
2002 global_publish_id = 0;
Rakesh Sunki0262cb52017-05-17 14:22:05 -07002003 global_subscribe_id = 0;
Rakesh Sunkifa417332017-08-16 15:41:32 -07002004 global_header_handle = 0;
2005 global_match_handle = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002006 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2007 }
2008 }
2009 if (nan_state && nan_op == NULL) {
2010 if (method_type) {
2011 if (strcasecmp(method_type, "Publish") == 0) {
2012 sigma_nan_publish_request(dut, conn, cmd);
2013 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2014 }
2015 if (strcasecmp(method_type, "Subscribe") == 0) {
2016 sigma_nan_subscribe_request(dut, conn, cmd);
2017 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2018 }
2019 if (strcasecmp(method_type, "Followup") == 0) {
2020 sigma_nan_transmit_followup(dut, conn, cmd);
2021 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2022 }
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07002023 if (strcasecmp(method_type, "DataRequest") == 0) {
2024 sigma_nan_data_request(dut, conn, cmd);
2025 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2026 }
Rakesh Sunkia5cc2842017-03-30 14:47:55 -07002027 if (strcasecmp(method_type, "DataResponse") == 0) {
2028 sigma_dut_print(dut, DUT_MSG_INFO,
2029 "%s: method_type is DataResponse",
2030 __func__);
2031 sigma_nan_data_response(dut, conn, cmd);
2032 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2033 }
Rakesh Sunki8a630b82017-03-30 14:47:55 -07002034 if (strcasecmp(method_type, "DataEnd") == 0) {
2035 sigma_nan_data_end(dut, cmd);
2036 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2037 }
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -07002038 if (strcasecmp(method_type, "rangerequest") == 0) {
2039 sigma_dut_print(dut, DUT_MSG_INFO,
2040 "%s: method_type is rangerequest",
2041 __func__);
2042 sigma_nan_range_request(dut, cmd);
2043 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2044 }
2045 if (strcasecmp(method_type, "cancelrange") == 0) {
2046 sigma_dut_print(dut, DUT_MSG_INFO,
2047 "%s: method_type is cancelrange",
2048 __func__);
2049 sigma_nan_cancel_range(dut, cmd);
2050 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2051 }
Rakesh Sunkib2b65162017-03-30 14:47:55 -07002052 if (strcasecmp(method_type, "SchedUpdate") == 0) {
2053 sigma_dut_print(dut, DUT_MSG_INFO,
2054 "%s: method_type is SchedUpdate",
2055 __func__);
2056 sigma_nan_schedule_update(dut, cmd);
2057 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2058 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002059 } else {
2060 sigma_nan_config_enable(dut, conn, cmd);
2061 snprintf(resp_buf, sizeof(resp_buf), "mac,"
2062 MAC_ADDR_STR,
2063 MAC_ADDR_ARRAY(global_nan_mac_addr));
2064 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
2065 }
2066 }
2067
2068 return 0;
2069}
2070
2071
2072int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
2073 struct sigma_cmd *cmd)
2074{
2075
2076 const char *program = get_param(cmd, "Program");
2077 const char *parameter = get_param(cmd, "Parameter");
2078 char resp_buf[100];
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002079 NanStatsRequest req;
2080 struct timespec abstime;
2081 u64 master_rank;
2082 u8 master_pref;
2083 u8 random_factor;
2084 u8 hop_count;
2085 u32 beacon_transmit_time;
2086 u32 ndp_channel_freq;
2087 u32 ndp_channel_freq2;
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002088#if NAN_CERT_VERSION >= 3
2089 u32 sched_update_channel_freq;
2090#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002091
2092 if (program == NULL) {
2093 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name");
2094 return -1;
2095 }
2096 if (strcasecmp(program, "NAN") != 0) {
2097 send_resp(dut, conn, SIGMA_ERROR,
2098 "ErrorCode,Unsupported program");
2099 return 0;
2100 }
2101
2102 if (parameter == NULL) {
2103 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter");
2104 return -1;
2105 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002106
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002107 memset(&req, 0, sizeof(NanStatsRequest));
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002108 memset(resp_buf, 0, sizeof(resp_buf));
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002109 req.stats_type = (NanStatsType) NAN_STATS_ID_DE_TIMING_SYNC;
2110 nan_stats_request(0, global_interface_handle, &req);
2111 /*
2112 * To ensure sta_get_events to get the events
2113 * only after joining the NAN cluster
2114 */
2115 abstime.tv_sec = 4;
2116 abstime.tv_nsec = 0;
2117 wait(abstime);
2118
2119 master_rank = global_nan_sync_stats.myRank;
2120 master_pref = (global_nan_sync_stats.myRank & 0xFF00000000000000) >> 56;
2121 random_factor = (global_nan_sync_stats.myRank & 0x00FF000000000000) >>
2122 48;
2123 hop_count = global_nan_sync_stats.currAmHopCount;
2124 beacon_transmit_time = global_nan_sync_stats.currAmBTT;
2125 ndp_channel_freq = global_nan_sync_stats.ndpChannelFreq;
2126 ndp_channel_freq2 = global_nan_sync_stats.ndpChannelFreq2;
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002127#if NAN_CERT_VERSION >= 3
2128 sched_update_channel_freq =
2129 global_nan_sync_stats.schedUpdateChannelFreq;
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002130
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002131 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002132 "%s: NanStatsRequest Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d ndp_channel_freq:%d ndp_channel_freq2:%d sched_update_channel_freq:%d",
2133 __func__, master_pref, random_factor,
2134 hop_count, beacon_transmit_time,
2135 ndp_channel_freq, ndp_channel_freq2,
2136 sched_update_channel_freq);
2137#else /* #if NAN_CERT_VERSION >= 3 */
2138 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002139 "%s: NanStatsRequest Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d ndp_channel_freq:%d ndp_channel_freq2:%d",
2140 __func__, master_pref, random_factor,
2141 hop_count, beacon_transmit_time,
2142 ndp_channel_freq, ndp_channel_freq2);
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002143#endif /* #if NAN_CERT_VERSION >= 3 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002144
2145 if (strcasecmp(parameter, "MasterPref") == 0) {
2146 snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002147 master_pref);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002148 } else if (strcasecmp(parameter, "MasterRank") == 0) {
2149 snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002150 master_rank);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002151 } else if (strcasecmp(parameter, "RandFactor") == 0) {
2152 snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002153 random_factor);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002154 } else if (strcasecmp(parameter, "HopCount") == 0) {
2155 snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002156 hop_count);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002157 } else if (strcasecmp(parameter, "BeaconTransTime") == 0) {
2158 snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002159 beacon_transmit_time);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002160 } else if (strcasecmp(parameter, "NANStatus") == 0) {
2161 if (nan_state == 1)
2162 snprintf(resp_buf, sizeof(resp_buf), "On");
2163 else
2164 snprintf(resp_buf, sizeof(resp_buf), "Off");
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002165 } else if (strcasecmp(parameter, "NDPChannel") == 0) {
2166 if (ndp_channel_freq != 0 && ndp_channel_freq2 != 0) {
2167 snprintf(resp_buf, sizeof(resp_buf),
2168 "ndpchannel,%d,ndpchannel,%d",
2169 freq_to_channel(ndp_channel_freq),
2170 freq_to_channel(ndp_channel_freq2));
2171 } else if (ndp_channel_freq != 0) {
2172 snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
2173 freq_to_channel(ndp_channel_freq));
2174 } else if (ndp_channel_freq2 != 0) {
2175 snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
2176 freq_to_channel(ndp_channel_freq2));
2177 } else {
2178 sigma_dut_print(dut, DUT_MSG_ERROR,
2179 "%s: No Negotiated NDP Channels", __func__);
2180 }
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002181#if NAN_CERT_VERSION >= 3
2182 } else if (strcasecmp(parameter, "SchedUpdateChannel") == 0) {
2183 snprintf(resp_buf, sizeof(resp_buf), "schedupdatechannel,%d",
2184 freq_to_channel(sched_update_channel_freq));
2185#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002186 } else {
2187 send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
2188 return 0;
2189 }
2190
2191 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
2192 return 0;
2193}
2194
2195
2196int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
2197 struct sigma_cmd *cmd)
2198{
2199 const char *action = get_param(cmd, "Action");
2200
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07002201 if (!action)
2202 return 0;
2203
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002204 /* Check action for start, stop and get events. */
2205 if (strcasecmp(action, "Start") == 0) {
2206 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
2207 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
2208 } else if (strcasecmp(action, "Stop") == 0) {
2209 event_anyresponse = 0;
2210 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
2211 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
2212 } else if (strcasecmp(action, "Get") == 0) {
2213 if (event_anyresponse == 1) {
2214 send_resp(dut, conn, SIGMA_COMPLETE,
2215 global_event_resp_buf);
2216 } else {
2217 send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE");
2218 }
2219 }
2220 return 0;
2221}
Rakesh Sunki4b75f962017-03-30 14:47:55 -07002222
2223#else /* #if NAN_CERT_VERSION */
2224
2225int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
2226 struct sigma_conn *conn,
2227 struct sigma_cmd *cmd)
2228{
2229 return 1;
2230}
2231
2232
2233int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
2234 struct sigma_cmd *cmd)
2235{
2236 return 0;
2237
2238}
2239
2240
2241void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
2242 struct sigma_cmd *cmd)
2243{
2244 return;
2245}
2246
2247
2248int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
2249 struct sigma_cmd *cmd)
2250{
2251 return 0;
2252}
2253
2254
2255int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
2256 struct sigma_cmd *cmd)
2257{
2258 return 0;
2259}
2260
2261#endif /* #if NAN_CERT_VERSION */