blob: 18f23c6ec0667916141334c626b1e97260ba89e8 [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");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200263 const char *sdftx_band = get_param(cmd, "SDFTxBand");
264 const char *oper_chan = get_param(cmd, "oper_chn");
265 const char *further_avail_ind = get_param(cmd, "FurtherAvailInd");
266 const char *band = get_param(cmd, "Band");
267 const char *only_5g = get_param(cmd, "5GOnly");
Rakesh Sunki38dd72e2017-03-30 14:47:55 -0700268 const char *nan_availability = get_param(cmd, "NANAvailability");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200269 struct timespec abstime;
270 NanEnableRequest req;
271
272 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200273 req.cluster_low = 0;
274 req.cluster_high = 0xFFFF;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700275 req.master_pref = 100;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200276
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700277 /* This is a debug hack to beacon in channel 11 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200278 if (oper_chan) {
279 req.config_2dot4g_support = 1;
280 req.support_2dot4g_val = 111;
281 }
282
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200283 if (master_pref) {
284 int master_pref_val = strtoul(master_pref, NULL, 0);
285
286 req.master_pref = master_pref_val;
287 }
288
289 if (rand_fac) {
290 int rand_fac_val = strtoul(rand_fac, NULL, 0);
291
292 req.config_random_factor_force = 1;
293 req.random_factor_force_val = rand_fac_val;
294 }
295
296 if (hop_count) {
297 int hop_count_val = strtoul(hop_count, NULL, 0);
298
299 req.config_hop_count_force = 1;
300 req.hop_count_force_val = hop_count_val;
301 }
302
303 if (sdftx_band) {
304 if (strcasecmp(sdftx_band, "5G") == 0) {
305 req.config_2dot4g_support = 1;
306 req.support_2dot4g_val = 0;
307 }
308 }
309
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700310 sigma_dut_print(dut, DUT_MSG_INFO,
311 "%s: Setting dual band 2.4 GHz and 5 GHz by default",
312 __func__);
313 /* Enable 2.4 GHz support */
314 req.config_2dot4g_support = 1;
315 req.support_2dot4g_val = 1;
316 req.config_2dot4g_beacons = 1;
317 req.beacon_2dot4g_val = 1;
318 req.config_2dot4g_sdf = 1;
319 req.sdf_2dot4g_val = 1;
320
321 /* Enable 5 GHz support */
322 req.config_support_5g = 1;
323 req.support_5g_val = 1;
324 req.config_5g_beacons = 1;
325 req.beacon_5g_val = 1;
326 req.config_5g_sdf = 1;
327 req.sdf_5g_val = 1;
328
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200329 if (band) {
330 if (strcasecmp(band, "24G") == 0) {
331 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunki47a276a2017-03-30 14:47:55 -0700332 "Band 2.4 GHz selected, disable 5 GHz");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200333 /* Disable 5G support */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700334 req.config_support_5g = 1;
335 req.support_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200336 req.config_5g_beacons = 1;
337 req.beacon_5g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700338 req.config_5g_sdf = 1;
339 req.sdf_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200340 }
341 }
342
343 if (further_avail_ind) {
344 sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled");
345 if (strcasecmp(further_avail_ind, "tx") == 0) {
346 is_fam = 1;
347 nan_further_availability_tx(dut, conn, cmd);
348 return 0;
349 } else if (strcasecmp(further_avail_ind, "rx") == 0) {
350 nan_further_availability_rx(dut, conn, cmd);
351 return 0;
352 }
353 }
354
355 if (only_5g && atoi(only_5g)) {
356 sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled");
357 req.config_2dot4g_support = 1;
358 req.support_2dot4g_val = 1;
359 req.config_2dot4g_beacons = 1;
360 req.beacon_2dot4g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700361 req.config_2dot4g_sdf = 1;
362 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200363 }
364
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700365 nan_enable_request(0, global_interface_handle, &req);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700366
Rakesh Sunki38dd72e2017-03-30 14:47:55 -0700367 if (nan_availability) {
368 int cmd_len, size;
369 NanDebugParams cfg_debug;
370
371 sigma_dut_print(dut, DUT_MSG_INFO,
372 "%s given string nan_availability: %s",
373 __func__, nan_availability);
374 memset(&cfg_debug, 0, sizeof(NanDebugParams));
375 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY;
376 size = NAN_MAX_DEBUG_MESSAGE_DATA_LEN;
377 nan_parse_hex_string(dut, &nan_availability[2],
378 &cfg_debug.debug_cmd_data[0], &size);
379 sigma_dut_print(dut, DUT_MSG_INFO, "%s:hex nan_availability",
380 __func__);
381 nan_hex_dump(dut, &cfg_debug.debug_cmd_data[0], size);
382 cmd_len = size + sizeof(u32);
383 nan_debug_command_config(0, global_interface_handle,
384 cfg_debug, cmd_len);
385 }
386
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700387 /* To ensure sta_get_events to get the events
388 * only after joining the NAN cluster. */
389 abstime.tv_sec = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200390 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700391 wait(abstime);
392
393 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200394}
395
396
397int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn,
398 struct sigma_cmd *cmd)
399{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200400 struct timespec abstime;
401
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700402 nan_disable_request(0, global_interface_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200403
404 abstime.tv_sec = 4;
405 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700406 wait(abstime);
407
408 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200409}
410
411
412int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn,
413 struct sigma_cmd *cmd)
414{
415 const char *master_pref = get_param(cmd, "MasterPref");
416 const char *rand_fac = get_param(cmd, "RandFactor");
417 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700418 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200419 struct timespec abstime;
420 NanConfigRequest req;
421
422 memset(&req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200423 req.config_rssi_proximity = 1;
424 req.rssi_proximity = 70;
425
426 if (master_pref) {
427 int master_pref_val = strtoul(master_pref, NULL, 0);
428
429 req.config_master_pref = 1;
430 req.master_pref = master_pref_val;
431 }
432
433 if (rand_fac) {
434 int rand_fac_val = strtoul(rand_fac, NULL, 0);
435
436 req.config_random_factor_force = 1;
437 req.random_factor_force_val = rand_fac_val;
438 }
439
440 if (hop_count) {
441 int hop_count_val = strtoul(hop_count, NULL, 0);
442
443 req.config_hop_count_force = 1;
444 req.hop_count_force_val = hop_count_val;
445 }
446
Rakesh Sunki107356c2017-03-30 14:47:55 -0700447 ret = nan_config_request(0, global_interface_handle, &req);
448 if (ret != WIFI_SUCCESS)
449 send_resp(dut, conn, SIGMA_ERROR, "NAN config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200450
451 abstime.tv_sec = 4;
452 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700453 wait(abstime);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200454
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700455 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200456}
457
458
459static int sigma_nan_subscribe_request(struct sigma_dut *dut,
460 struct sigma_conn *conn,
461 struct sigma_cmd *cmd)
462{
463 const char *subscribe_type = get_param(cmd, "SubscribeType");
464 const char *service_name = get_param(cmd, "ServiceName");
465 const char *disc_range = get_param(cmd, "DiscoveryRange");
466 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
467 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
468 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
469 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
470 const char *include_bit = get_param(cmd, "IncludeBit");
471 const char *mac = get_param(cmd, "MAC");
472 const char *srf_type = get_param(cmd, "SRFType");
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -0700473#if NAN_CERT_VERSION >= 3
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700474 const char *awake_dw_interval = get_param(cmd, "awakeDWint");
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -0700475#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200476 NanSubscribeRequest req;
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700477 NanConfigRequest config_req;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200478 int filter_len_rx = 0, filter_len_tx = 0;
479 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
480 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700481 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200482
483 memset(&req, 0, sizeof(NanSubscribeRequest));
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700484 memset(&config_req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200485 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -0700486 req.period = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200487 req.subscribe_type = 1;
488 req.serviceResponseFilter = 1; /* MAC */
489 req.serviceResponseInclude = 0;
490 req.ssiRequiredForMatchIndication = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700491 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200492 req.subscribe_count = 0;
493
Rakesh Sunki74f4f992017-08-16 15:21:52 -0700494 if (global_subscribe_service_name_len &&
495 service_name &&
496 strcasecmp((char *) global_subscribe_service_name,
497 service_name) == 0 &&
498 global_subscribe_id) {
499 req.subscribe_id = global_subscribe_id;
500 sigma_dut_print(dut, DUT_MSG_INFO,
501 "%s: updating subscribe_id = %d in subscribe request",
502 __func__, req.subscribe_id);
503 }
504
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200505 if (subscribe_type) {
506 if (strcasecmp(subscribe_type, "Active") == 0) {
507 req.subscribe_type = 1;
508 } else if (strcasecmp(subscribe_type, "Passive") == 0) {
509 req.subscribe_type = 0;
510 } else if (strcasecmp(subscribe_type, "Cancel") == 0) {
511 NanSubscribeCancelRequest req;
512
513 memset(&req, 0, sizeof(NanSubscribeCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700514 ret = nan_subscribe_cancel_request(
515 0, global_interface_handle, &req);
516 if (ret != WIFI_SUCCESS) {
517 send_resp(dut, conn, SIGMA_ERROR,
518 "NAN subscribe cancel request failed");
519 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200520 return 0;
521 }
522 }
523
524 if (disc_range)
525 req.rssi_threshold_flag = atoi(disc_range);
526
527 if (sdftx_dw)
528 req.subscribe_count = atoi(sdftx_dw);
529
530 /* Check this once again if config can be called here (TBD) */
531 if (discrange_ltd)
532 req.rssi_threshold_flag = atoi(discrange_ltd);
533
534 if (include_bit) {
535 int include_bit_val = atoi(include_bit);
536
537 req.serviceResponseInclude = include_bit_val;
538 sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d",
539 req.serviceResponseInclude);
540 }
541
542 if (srf_type) {
543 int srf_type_val = atoi(srf_type);
544
545 if (srf_type_val == 1)
546 req.serviceResponseFilter = 0; /* Bloom */
547 else
548 req.serviceResponseFilter = 1; /* MAC */
549 req.useServiceResponseFilter = 1;
550 sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d",
551 req.serviceResponseFilter);
552 }
553
554 if (mac) {
555 sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac);
556 req.num_intf_addr_present = nan_parse_mac_address_list(
557 dut, mac, &req.intf_addr[0][0],
558 NAN_MAX_SUBSCRIBE_MAX_ADDRESS);
559 }
560
561 memset(input_rx, 0, sizeof(input_rx));
562 memset(input_tx, 0, sizeof(input_tx));
563 if (rx_match_filter) {
564 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
565 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
566 filter_len_rx);
567 }
568 if (tx_match_filter) {
569 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
570 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
571 filter_len_tx);
572 }
573
574 if (tx_match_filter) {
575 req.tx_match_filter_len = filter_len_tx;
576 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
577 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
578 }
579 if (rx_match_filter) {
580 req.rx_match_filter_len = filter_len_rx;
581 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
582 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
583 }
584
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700585 if (service_name) {
586 strlcpy((char *) req.service_name, service_name,
587 strlen(service_name) + 1);
588 req.service_name_len = strlen(service_name);
Rakesh Sunki74f4f992017-08-16 15:21:52 -0700589 strlcpy((char *) global_subscribe_service_name, service_name,
590 sizeof(global_subscribe_service_name));
591 global_subscribe_service_name_len =
592 strlen((char *) global_subscribe_service_name);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700593 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200594
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -0700595#if NAN_CERT_VERSION >= 3
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700596 if (awake_dw_interval) {
597 int input_dw_interval_val = atoi(awake_dw_interval);
598 int awake_dw_int = 0;
599
600 if (input_dw_interval_val > NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL) {
601 sigma_dut_print(dut, DUT_MSG_INFO,
602 "%s: input active dw interval = %d overwritting dw interval to Max allowed dw interval 16",
603 __func__, input_dw_interval_val);
604 input_dw_interval_val =
605 NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL;
606 }
607 sigma_dut_print(dut, DUT_MSG_INFO,
608 "%s: input active DW interval = %d",
609 __func__, input_dw_interval_val);
610 /*
611 * Indicates the interval for Sync beacons and SDF's in 2.4 GHz
612 * or 5 GHz band. Valid values of DW Interval are: 1, 2, 3, 4,
613 * and 5; 0 is reserved. The SDF includes in OTA when enabled.
614 * The publish/subscribe period values don't override the device
615 * level configurations.
616 * input_dw_interval_val is provided by the user are in the
617 * format 2^n-1 = 1/2/4/8/16. Internal implementation expects n
618 * to be passed to indicate the awake_dw_interval.
619 */
620 if (input_dw_interval_val == 1 ||
621 input_dw_interval_val % 2 == 0) {
622 while (input_dw_interval_val > 0) {
623 input_dw_interval_val >>= 1;
624 awake_dw_int++;
625 }
626 }
627 sigma_dut_print(dut, DUT_MSG_INFO,
628 "%s:converted active DW interval = %d",
629 __func__, awake_dw_int);
630 config_req.config_dw.config_2dot4g_dw_band = 1;
631 config_req.config_dw.dw_2dot4g_interval_val = awake_dw_int;
632 config_req.config_dw.config_5g_dw_band = 1;
633 config_req.config_dw.dw_5g_interval_val = awake_dw_int;
634 ret = nan_config_request(0, global_interface_handle,
635 &config_req);
636 if (ret != WIFI_SUCCESS) {
637 sigma_dut_print(dut, DUT_MSG_ERROR,
638 "%s:NAN config request failed",
639 __func__);
640 return -2;
641 }
642 }
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -0700643#endif
Rakesh Sunkie6f66832017-05-16 15:22:48 -0700644
Rakesh Sunki107356c2017-03-30 14:47:55 -0700645 ret = nan_subscribe_request(0, global_interface_handle, &req);
646 if (ret != WIFI_SUCCESS) {
647 send_resp(dut, conn, SIGMA_ERROR,
648 "NAN subscribe request failed");
649 }
650
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200651 return 0;
652}
653
654
Rakesh Sunkid7344c02017-03-30 14:47:55 -0700655static int sigma_ndp_configure_band(struct sigma_dut *dut,
656 struct sigma_conn *conn,
657 struct sigma_cmd *cmd,
658 NdpSupportedBand band_config_val)
659{
660 wifi_error ret;
661 NanDebugParams cfg_debug;
662 int size;
663
664 memset(&cfg_debug, 0, sizeof(NanDebugParams));
665 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS;
666 memcpy(cfg_debug.debug_cmd_data, &band_config_val, sizeof(int));
667 sigma_dut_print(dut, DUT_MSG_INFO, "%s:setting debug cmd=0x%x",
668 __func__, cfg_debug.cmd);
669 size = sizeof(u32) + sizeof(int);
670 ret = nan_debug_command_config(0, global_interface_handle, cfg_debug,
671 size);
672 if (ret != WIFI_SUCCESS)
673 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
674
675 return 0;
676}
677
678
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700679static int sigma_nan_data_request(struct sigma_dut *dut,
680 struct sigma_conn *conn,
681 struct sigma_cmd *cmd)
682{
683 const char *ndp_security = get_param(cmd, "DataPathSecurity");
684 const char *ndp_resp_mac = get_param(cmd, "RespNanMac");
685 const char *include_immutable = get_param(cmd, "includeimmutable");
686 const char *avoid_channel = get_param(cmd, "avoidchannel");
687 const char *invalid_nan_schedule = get_param(cmd, "InvalidNANSchedule");
688 const char *map_order = get_param(cmd, "maporder");
Rakesh Sunki8a4845d2017-05-16 15:27:13 -0700689#if NAN_CERT_VERSION >= 3
690 const char *qos_config = get_param(cmd, "QoS");
691#endif
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700692 wifi_error ret;
693 NanDataPathInitiatorRequest init_req;
694 NanDebugParams cfg_debug;
695 int size;
696
697 memset(&init_req, 0, sizeof(NanDataPathInitiatorRequest));
698
699 if (ndp_security) {
700 if (strcasecmp(ndp_security, "open") == 0)
701 init_req.ndp_cfg.security_cfg =
702 NAN_DP_CONFIG_NO_SECURITY;
703 else if (strcasecmp(ndp_security, "secure") == 0)
704 init_req.ndp_cfg.security_cfg = NAN_DP_CONFIG_SECURITY;
705 }
706
707 if (include_immutable) {
708 int include_immutable_val = 0;
709
710 memset(&cfg_debug, 0, sizeof(NanDebugParams));
711 cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE;
712 include_immutable_val = atoi(include_immutable);
713 memcpy(cfg_debug.debug_cmd_data, &include_immutable_val,
714 sizeof(int));
715 size = sizeof(u32) + sizeof(int);
716 nan_debug_command_config(0, global_interface_handle,
717 cfg_debug, size);
718 }
719
720 if (avoid_channel) {
721 int avoid_channel_freq = 0;
722
723 memset(&cfg_debug, 0, sizeof(NanDebugParams));
724 avoid_channel_freq = channel_to_freq(atoi(avoid_channel));
725 cfg_debug.cmd = NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL;
726 memcpy(cfg_debug.debug_cmd_data, &avoid_channel_freq,
727 sizeof(int));
728 size = sizeof(u32) + sizeof(int);
729 nan_debug_command_config(0, global_interface_handle,
730 cfg_debug, size);
731 }
732
733 if (invalid_nan_schedule) {
734 int invalid_nan_schedule_type = 0;
735
736 memset(&cfg_debug, 0, sizeof(NanDebugParams));
737 invalid_nan_schedule_type = atoi(invalid_nan_schedule);
738 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_TYPE;
739 memcpy(cfg_debug.debug_cmd_data,
740 &invalid_nan_schedule_type, sizeof(int));
741 size = sizeof(u32) + sizeof(int);
742 sigma_dut_print(dut, DUT_MSG_INFO,
743 "%s: invalid schedule type: cmd type = %d and command data = %d",
744 __func__, cfg_debug.cmd,
745 invalid_nan_schedule_type);
746 nan_debug_command_config(0, global_interface_handle,
747 cfg_debug, size);
748 }
749
750 if (map_order) {
751 int map_order_val = 0;
752
753 memset(&cfg_debug, 0, sizeof(NanDebugParams));
754 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER;
755 map_order_val = atoi(map_order);
756 memcpy(cfg_debug.debug_cmd_data, &map_order_val, sizeof(int));
757 size = sizeof(u32) + sizeof(int);
758 sigma_dut_print(dut, DUT_MSG_INFO,
759 "%s: map order: cmd type = %d and command data = %d",
760 __func__,
Rakesh Sunki9eaa6772017-04-04 11:37:03 -0700761 cfg_debug.cmd, map_order_val);
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700762 nan_debug_command_config(0, global_interface_handle,
763 cfg_debug, size);
764 }
765
Rakesh Sunki8a4845d2017-05-16 15:27:13 -0700766#if NAN_CERT_VERSION >= 3
767 if (qos_config) {
768 u32 qos_config_val = 0;
769
770 memset(&cfg_debug, 0, sizeof(NanDebugParams));
771 cfg_debug.cmd = NAN_TEST_MODE_CMD_CONFIG_QOS;
772 qos_config_val = atoi(qos_config);
773 memcpy(cfg_debug.debug_cmd_data, &qos_config_val, sizeof(u32));
774 size = sizeof(u32) + sizeof(u32);
775 sigma_dut_print(dut, DUT_MSG_INFO,
776 "%s: qos config: cmd type = %d and command data = %d",
777 __func__, cfg_debug.cmd, qos_config_val);
778 nan_debug_command_config(0, global_interface_handle,
779 cfg_debug, size);
780 }
781#endif
782
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700783 /*
784 * Setting this flag, so that interface for ping6 command
785 * is set appropriately in traffic_send_ping().
786 */
787 dut->ndp_enable = 1;
788
789 /*
790 * Intended sleep after NAN data interface create
791 * before the NAN data request
792 */
793 sleep(4);
794
795 init_req.requestor_instance_id = global_match_handle;
796 strlcpy((char *) init_req.ndp_iface, "nan0",
797 sizeof(init_req.ndp_iface));
798
799 if (ndp_resp_mac) {
800 nan_parse_mac_address(dut, ndp_resp_mac,
801 init_req.peer_disc_mac_addr);
802 sigma_dut_print(
803 dut, DUT_MSG_INFO, "PEER MAC ADDR: " MAC_ADDR_STR,
804 MAC_ADDR_ARRAY(init_req.peer_disc_mac_addr));
805 } else {
806 memcpy(init_req.peer_disc_mac_addr, global_peer_mac_addr,
807 sizeof(init_req.peer_disc_mac_addr));
808 }
809
810 /* Not requesting the channel and letting FW decide */
811 if (dut->sta_channel == 0) {
812 init_req.channel_request_type = NAN_DP_CHANNEL_NOT_REQUESTED;
813 init_req.channel = 0;
814 } else {
815 init_req.channel_request_type = NAN_DP_FORCE_CHANNEL_SETUP;
816 init_req.channel = channel_to_freq(dut->sta_channel);
817 }
818 sigma_dut_print(dut, DUT_MSG_INFO,
819 "%s: Initiator Request: Channel = %d Channel Request Type = %d",
820 __func__, init_req.channel,
821 init_req.channel_request_type);
822
823 if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) {
Rakesh Sunki395b0152017-05-16 15:30:36 -0700824 init_req.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
Rakesh Sunki14cfcd22017-03-30 14:47:55 -0700825 memcpy(&init_req.key_info.body.pmk_info.pmk[0],
826 &dut->nan_pmk[0], NAN_PMK_INFO_LEN);
827 init_req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
828 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
829 __func__,
830 init_req.key_info.body.pmk_info.pmk_len);
831 }
832
833 ret = nan_data_request_initiator(0, global_interface_handle, &init_req);
834 if (ret != WIFI_SUCCESS) {
835 send_resp(dut, conn, SIGMA_ERROR,
836 "Unable to initiate nan data request");
837 return 0;
838 }
839
840 return 0;
841}
842
843
Rakesh Sunkia5cc2842017-03-30 14:47:55 -0700844static int sigma_nan_data_response(struct sigma_dut *dut,
845 struct sigma_conn *conn,
846 struct sigma_cmd *cmd)
847{
848 const char *ndl_response = get_param(cmd, "NDLresponse");
849 const char *m4_response_type = get_param(cmd, "M4ResponseType");
850 wifi_error ret;
851 NanDebugParams cfg_debug;
852 int size;
853
854 if (ndl_response) {
855 int auto_responder_mode_val = 0;
856
857 sigma_dut_print(dut, DUT_MSG_INFO,
858 "%s: ndl_response = (%s) is passed",
859 __func__, ndl_response);
860 memset(&cfg_debug, 0, sizeof(NanDebugParams));
861 cfg_debug.cmd = NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE;
862 if (strcasecmp(ndl_response, "Auto") == 0) {
863 auto_responder_mode_val = NAN_DATA_RESPONDER_MODE_AUTO;
864 } else if (strcasecmp(ndl_response, "Reject") == 0) {
865 auto_responder_mode_val =
866 NAN_DATA_RESPONDER_MODE_REJECT;
867 } else if (strcasecmp(ndl_response, "Accept") == 0) {
868 auto_responder_mode_val =
869 NAN_DATA_RESPONDER_MODE_ACCEPT;
870 } else if (strcasecmp(ndl_response, "Counter") == 0) {
871 auto_responder_mode_val =
872 NAN_DATA_RESPONDER_MODE_COUNTER;
873 } else {
874 sigma_dut_print(dut, DUT_MSG_ERROR,
875 "%s: Invalid ndl_response",
876 __func__);
877 return 0;
878 }
879 memcpy(cfg_debug.debug_cmd_data, &auto_responder_mode_val,
880 sizeof(int));
881 size = sizeof(u32) + sizeof(int);
882 ret = nan_debug_command_config(0, global_interface_handle,
883 cfg_debug, size);
884 if (ret != WIFI_SUCCESS) {
885 send_resp(dut, conn, SIGMA_ERROR,
886 "Nan config request failed");
887 }
888 }
889
890 if (m4_response_type) {
891 int m4_response_type_val = 0;
892
893 sigma_dut_print(dut, DUT_MSG_INFO,
894 "%s: m4_response_type = (%s) is passed",
895 __func__, m4_response_type);
896 memset(&cfg_debug, 0, sizeof(NanDebugParams));
897 cfg_debug.cmd = NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE;
898 if (strcasecmp(m4_response_type, "Accept") == 0)
899 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_ACCEPT;
900 else if (strcasecmp(m4_response_type, "Reject") == 0)
901 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_REJECT;
902 else if (strcasecmp(m4_response_type, "BadMic") == 0)
903 m4_response_type_val = NAN_DATA_PATH_M4_RESPONSE_BADMIC;
904
905 memcpy(cfg_debug.debug_cmd_data, &m4_response_type_val,
906 sizeof(int));
907 size = sizeof(u32) + sizeof(int);
908 ret = nan_debug_command_config(0, global_interface_handle,
909 cfg_debug, size);
910 if (ret != WIFI_SUCCESS) {
911 send_resp(dut, conn, SIGMA_ERROR,
912 "Nan config request failed");
913 }
914 }
915
916 return 0;
917}
918
919
Rakesh Sunki8a630b82017-03-30 14:47:55 -0700920static int sigma_nan_data_end(struct sigma_dut *dut, struct sigma_cmd *cmd)
921{
922 const char *nmf_security_config = get_param(cmd, "Security");
923 NanDataPathEndRequest req;
924 NanDebugParams cfg_debug;
925 int size;
926
927 memset(&req, 0, sizeof(NanDataPathEndRequest));
928 memset(&cfg_debug, 0, sizeof(NanDebugParams));
929 if (nmf_security_config) {
930 int nmf_security_config_val = 0;
931
932 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_NMF_CLEAR_CONFIG;
933 if (strcasecmp(nmf_security_config, "open") == 0)
934 nmf_security_config_val = NAN_NMF_CLEAR_ENABLE;
935 else if (strcasecmp(nmf_security_config, "secure") == 0)
936 nmf_security_config_val = NAN_NMF_CLEAR_DISABLE;
937 memcpy(cfg_debug.debug_cmd_data,
938 &nmf_security_config_val, sizeof(int));
939 size = sizeof(u32) + sizeof(int);
940 sigma_dut_print(dut, DUT_MSG_INFO,
941 "%s: nmf_security_config_val -- cmd type = %d and command data = %d",
942 __func__, cfg_debug.cmd,
943 nmf_security_config_val);
944 nan_debug_command_config(0, global_interface_handle,
945 cfg_debug, size);
946 }
947
948 req.num_ndp_instances = 1;
949 req.ndp_instance_id[0] = global_ndp_instance_id;
950
951 nan_data_end(0, global_interface_handle, &req);
952 return 0;
953}
954
955
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -0700956static int sigma_nan_range_request(struct sigma_dut *dut,
957 struct sigma_cmd *cmd)
958{
959 const char *dest_mac = get_param(cmd, "destmac");
960 NanSubscribeRequest req;
961
962 memset(&req, 0, sizeof(NanSubscribeRequest));
963 req.period = 1;
Rakesh Sunki3834be52017-08-16 15:27:36 -0700964 req.subscribe_type = NAN_SUBSCRIBE_TYPE_PASSIVE;
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -0700965 req.serviceResponseFilter = NAN_SRF_ATTR_BLOOM_FILTER;
966 req.serviceResponseInclude = NAN_SRF_INCLUDE_RESPOND;
967 req.ssiRequiredForMatchIndication = NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
968 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
969 req.subscribe_count = 0;
970 strlcpy((char *) req.service_name, DEFAULT_SVC,
971 NAN_MAX_SERVICE_NAME_LEN);
972 req.service_name_len = strlen((char *) req.service_name);
973
974 req.subscribe_id = global_subscribe_id;
975 req.sdea_params.ranging_state = 1;
976 req.sdea_params.range_report = NAN_ENABLE_RANGE_REPORT;
977 req.range_response_cfg.requestor_instance_id = global_match_handle;
978 req.range_response_cfg.ranging_response = NAN_RANGE_REQUEST_ACCEPT;
979 req.ranging_cfg.config_ranging_indications =
980 NAN_RANGING_INDICATE_CONTINUOUS_MASK;
981 if (dest_mac) {
982 nan_parse_mac_address(dut, dest_mac,
983 req.range_response_cfg.peer_addr);
984 sigma_dut_print(
985 dut, DUT_MSG_INFO, "peer mac addr: " MAC_ADDR_STR,
986 MAC_ADDR_ARRAY(req.range_response_cfg.peer_addr));
987 }
988 nan_subscribe_request(0, global_interface_handle, &req);
989
990 return 0;
991}
992
993
994static int sigma_nan_cancel_range(struct sigma_dut *dut,
995 struct sigma_cmd *cmd)
996{
997 const char *dest_mac = get_param(cmd, "destmac");
998 NanPublishRequest req;
999
1000 memset(&req, 0, sizeof(NanPublishRequest));
1001 req.ttl = 0;
1002 req.period = 1;
1003 req.publish_match_indicator = 1;
1004 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
1005 req.tx_type = NAN_TX_TYPE_BROADCAST;
1006 req.publish_count = 0;
1007 strlcpy((char *) req.service_name, DEFAULT_SVC,
1008 NAN_MAX_SERVICE_NAME_LEN);
1009 req.service_name_len = strlen((char *) req.service_name);
1010 req.publish_id = global_publish_id;
1011 req.range_response_cfg.ranging_response = NAN_RANGE_REQUEST_CANCEL;
1012 if (dest_mac) {
1013 nan_parse_mac_address(dut, dest_mac,
1014 req.range_response_cfg.peer_addr);
1015 sigma_dut_print(
1016 dut, DUT_MSG_INFO, "peer mac addr: " MAC_ADDR_STR,
1017 MAC_ADDR_ARRAY(req.range_response_cfg.peer_addr));
1018 }
1019 nan_publish_request(0, global_interface_handle, &req);
1020
1021 return 0;
1022}
1023
1024
Rakesh Sunkib2b65162017-03-30 14:47:55 -07001025static int sigma_nan_schedule_update(struct sigma_dut *dut,
1026 struct sigma_cmd *cmd)
1027{
1028 const char *schedule_update_type = get_param(cmd, "type");
1029 const char *channel_availability = get_param(cmd,
1030 "ChannelAvailability");
1031 const char *responder_nmi_mac = get_param(cmd, "ResponderNMI");
1032 NanDebugParams cfg_debug;
1033 int size = 0;
1034
1035 memset(&cfg_debug, 0, sizeof(NanDebugParams));
1036
1037 if (!schedule_update_type)
1038 return 0;
1039
1040 if (strcasecmp(schedule_update_type, "ULWnotify") == 0) {
1041 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY;
1042 size = sizeof(u32);
1043 sigma_dut_print(dut, DUT_MSG_INFO,
1044 "%s: Schedule Update cmd type = %d", __func__,
1045 cfg_debug.cmd);
1046 if (channel_availability) {
1047 int channel_availability_val;
1048
1049 channel_availability_val = atoi(channel_availability);
1050 size += sizeof(int);
1051 memcpy(cfg_debug.debug_cmd_data,
1052 &channel_availability_val, sizeof(int));
1053 sigma_dut_print(dut, DUT_MSG_INFO,
1054 "%s: Schedule Update cmd data = %d size = %d",
1055 __func__, channel_availability_val,
1056 size);
1057 }
1058 } else if (strcasecmp(schedule_update_type, "NDLnegotiate") == 0) {
1059 cfg_debug.cmd =
1060 NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE;
1061 size = sizeof(u32);
1062 sigma_dut_print(dut, DUT_MSG_INFO,
1063 "%s: Schedule Update cmd type = %d", __func__,
1064 cfg_debug.cmd);
1065 if (responder_nmi_mac) {
1066 u8 responder_nmi_mac_addr[NAN_MAC_ADDR_LEN];
1067
1068 nan_parse_mac_address(dut, responder_nmi_mac,
1069 responder_nmi_mac_addr);
1070 size += NAN_MAC_ADDR_LEN;
1071 memcpy(cfg_debug.debug_cmd_data, responder_nmi_mac_addr,
1072 NAN_MAC_ADDR_LEN);
1073 sigma_dut_print(dut, DUT_MSG_INFO,
1074 "%s: RESPONDER NMI MAC: "MAC_ADDR_STR,
1075 __func__,
1076 MAC_ADDR_ARRAY(responder_nmi_mac_addr));
1077 sigma_dut_print(dut, DUT_MSG_INFO,
1078 "%s: Schedule Update: cmd size = %d",
1079 __func__, size);
1080 }
1081 } else if (strcasecmp(schedule_update_type, "NDLnotify") == 0) {
1082 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY;
1083 size = sizeof(u32);
1084 sigma_dut_print(dut, DUT_MSG_INFO,
1085 "%s: Schedule Update cmd type = %d", __func__,
1086 cfg_debug.cmd);
1087 }
1088
1089 nan_debug_command_config(0, global_interface_handle, cfg_debug, size);
1090
1091 return 0;
1092}
1093
1094
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001095int config_post_disc_attr(void)
1096{
Rakesh Sunki107356c2017-03-30 14:47:55 -07001097 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001098 NanConfigRequest configReq;
1099
1100 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001101
1102 /* Configure Post disc attr */
1103 /* Make these defines and use correct enum */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001104 configReq.num_config_discovery_attr = 1;
1105 configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */
1106 configReq.discovery_attr_val[0].role = 0;
1107 configReq.discovery_attr_val[0].transmit_freq = 1;
1108 configReq.discovery_attr_val[0].duration = 0;
1109 configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001110
Rakesh Sunki107356c2017-03-30 14:47:55 -07001111 ret = nan_config_request(0, global_interface_handle, &configReq);
1112 if (ret != WIFI_SUCCESS) {
1113 sigma_dut_print(global_dut, DUT_MSG_INFO,
1114 "NAN config request failed while configuring post discovery attribute");
1115 }
1116
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001117 return 0;
1118}
1119
1120
1121int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn,
1122 struct sigma_cmd *cmd)
1123{
1124 const char *publish_type = get_param(cmd, "PublishType");
1125 const char *service_name = get_param(cmd, "ServiceName");
1126 const char *disc_range = get_param(cmd, "DiscoveryRange");
1127 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
1128 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
1129 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
1130 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001131 const char *ndp_enable = get_param(cmd, "DataPathFlag");
1132 const char *ndp_type = get_param(cmd, "DataPathType");
1133 const char *data_path_security = get_param(cmd, "datapathsecurity");
Rakesh Sunki48060402017-03-30 14:47:55 -07001134 const char *range_required = get_param(cmd, "rangerequired");
Rakesh Sunki8a4845d2017-05-16 15:27:13 -07001135#if NAN_CERT_VERSION >= 3
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -07001136 const char *awake_dw_interval = get_param(cmd, "awakeDWint");
Rakesh Sunki8a4845d2017-05-16 15:27:13 -07001137 const char *qos_config = get_param(cmd, "QoS");
1138#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001139 NanPublishRequest req;
Rakesh Sunkie6f66832017-05-16 15:22:48 -07001140 NanConfigRequest config_req;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001141 int filter_len_rx = 0, filter_len_tx = 0;
1142 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
1143 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -07001144 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001145
1146 memset(&req, 0, sizeof(NanPublishRequest));
Rakesh Sunkie6f66832017-05-16 15:22:48 -07001147 memset(&config_req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001148 req.ttl = 0;
Rakesh Sunki4625de72017-03-30 14:47:55 -07001149 req.period = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001150 req.publish_match_indicator = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001151 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
1152 req.tx_type = NAN_TX_TYPE_BROADCAST;
1153 req.publish_count = 0;
Rakesh Sunki0a0eea82017-03-30 14:47:55 -07001154 req.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_ALL;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001155
Rakesh Sunki42363682017-05-16 15:00:42 -07001156 if (global_publish_service_name_len &&
1157 service_name &&
1158 strcasecmp((char *) global_publish_service_name,
1159 service_name) == 0 &&
1160 global_publish_id) {
1161 req.publish_id = global_publish_id;
1162 sigma_dut_print(dut, DUT_MSG_INFO,
1163 "%s: updating publish_id = %d in publish request",
1164 __func__, req.publish_id);
1165 }
1166
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001167 if (service_name) {
1168 strlcpy((char *) req.service_name, service_name,
Rakesh Sunki42363682017-05-16 15:00:42 -07001169 sizeof(req.service_name));
1170 req.service_name_len = strlen((char *) req.service_name);
1171 strlcpy((char *) global_publish_service_name, service_name,
1172 sizeof(global_publish_service_name));
1173 global_publish_service_name_len =
1174 strlen((char *) global_publish_service_name);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001175 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001176
1177 if (publish_type) {
1178 if (strcasecmp(publish_type, "Solicited") == 0) {
1179 req.publish_type = NAN_PUBLISH_TYPE_SOLICITED;
Rakesh Sunki62644ab2017-03-30 14:47:55 -07001180 } else if (strcasecmp(publish_type, "Unsolicited") == 0) {
1181 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001182 } else if (strcasecmp(publish_type, "Cancel") == 0) {
1183 NanPublishCancelRequest req;
1184
1185 memset(&req, 0, sizeof(NanPublishCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -07001186 ret = nan_publish_cancel_request(
1187 0, global_interface_handle, &req);
1188 if (ret != WIFI_SUCCESS) {
1189 send_resp(dut, conn, SIGMA_ERROR,
1190 "Unable to cancel nan publish request");
1191 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001192 return 0;
1193 }
1194 }
1195
1196 if (disc_range)
1197 req.rssi_threshold_flag = atoi(disc_range);
1198
1199 if (sdftx_dw)
1200 req.publish_count = atoi(sdftx_dw);
1201
1202 if (discrange_ltd)
1203 req.rssi_threshold_flag = atoi(discrange_ltd);
1204
1205 memset(input_rx, 0, sizeof(input_rx));
1206 memset(input_tx, 0, sizeof(input_tx));
1207 if (rx_match_filter) {
1208 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
1209 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
1210 filter_len_rx);
1211 }
1212 if (tx_match_filter) {
1213 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
1214 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
1215 filter_len_tx);
1216 }
1217
1218 if (is_fam == 1) {
1219 config_post_disc_attr();
Rakesh Sunkif680e0f2017-03-30 14:47:55 -07001220 /*
1221 * 8-bit bitmap which allows the Host to associate this publish
1222 * with a particular Post-NAN Connectivity attribute which has
1223 * been sent down in a NanConfigureRequest/NanEnableRequest
1224 * message. If the DE fails to find a configured Post-NAN
1225 * connectivity attributes referenced by the bitmap, the DE will
1226 * return an error code to the Host. If the Publish is
1227 * configured to use a Post-NAN Connectivity attribute and the
1228 * Host does not refresh the Post-NAN Connectivity attribute the
1229 * Publish will be canceled and the Host will be sent a
1230 * PublishTerminatedIndication message.
1231 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001232 req.connmap = 0x10;
1233 }
1234
1235 if (tx_match_filter) {
1236 req.tx_match_filter_len = filter_len_tx;
1237 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
1238 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
1239 }
1240
1241 if (rx_match_filter) {
1242 req.rx_match_filter_len = filter_len_rx;
1243 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
1244 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
1245 }
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001246
1247 if (service_name) {
1248 strlcpy((char *) req.service_name, service_name,
1249 strlen(service_name) + 1);
1250 req.service_name_len = strlen(service_name);
1251 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001252
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001253 if (ndp_enable) {
1254 if (strcasecmp(ndp_enable, "enable") == 0)
1255 req.sdea_params.config_nan_data_path = 1;
1256 else
1257 req.sdea_params.config_nan_data_path = 0;
1258
1259 if (ndp_type)
1260 req.sdea_params.ndp_type = atoi(ndp_type);
1261
1262 if (data_path_security) {
1263 if (strcasecmp(data_path_security, "secure") == 0) {
1264 req.sdea_params.security_cfg =
1265 NAN_DP_CONFIG_SECURITY;
1266 } else if (strcasecmp(data_path_security, "open") ==
1267 0) {
1268 req.sdea_params.security_cfg =
1269 NAN_DP_CONFIG_NO_SECURITY;
1270 }
1271 }
1272
1273 if (dut->nan_pmk_len == NAN_PMK_INFO_LEN) {
Rakesh Sunki395b0152017-05-16 15:30:36 -07001274 req.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001275 memcpy(&req.key_info.body.pmk_info.pmk[0],
1276 &dut->nan_pmk[0], NAN_PMK_INFO_LEN);
1277 req.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
1278 sigma_dut_print(dut, DUT_MSG_INFO, "%s: pmk len = %d",
1279 __func__, req.key_info.body.pmk_info.pmk_len);
1280 }
1281 }
Rakesh Sunki48060402017-03-30 14:47:55 -07001282 if (range_required && strcasecmp(range_required, "enable") == 0) {
1283 req.sdea_params.ranging_state = NAN_RANGING_ENABLE;
1284 req.sdea_params.range_report = NAN_ENABLE_RANGE_REPORT;
1285 }
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001286
Rakesh Sunkiff76d8c2017-06-06 12:29:34 -07001287#if NAN_CERT_VERSION >= 3
Rakesh Sunkie6f66832017-05-16 15:22:48 -07001288 if (awake_dw_interval) {
1289 int input_dw_interval_val = atoi(awake_dw_interval);
1290 int awake_dw_int = 0;
1291
1292 if (input_dw_interval_val > NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL) {
1293 sigma_dut_print(dut, DUT_MSG_INFO,
1294 "%s: input active dw interval = %d overwritting dw interval to Max allowed dw interval 16",
1295 __func__, input_dw_interval_val);
1296 input_dw_interval_val =
1297 NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL;
1298 }
1299 sigma_dut_print(dut, DUT_MSG_INFO,
1300 "%s: input active DW interval = %d",
1301 __func__, input_dw_interval_val);
1302 /*
1303 * Indicates the interval for Sync beacons and SDF's in 2.4 GHz
1304 * or 5 GHz band. Valid values of DW Interval are: 1, 2, 3, 4,
1305 * and 5; 0 is reserved. The SDF includes in OTA when enabled.
1306 * The publish/subscribe period. values don't override the
1307 * device level configurations.
1308 * input_dw_interval_val is provided by the user are in the
1309 * format 2^n-1 = 1/2/4/8/16. Internal implementation expects n
1310 * to be passed to indicate the awake_dw_interval.
1311 */
1312 if (input_dw_interval_val == 1 ||
1313 input_dw_interval_val % 2 == 0) {
1314 while (input_dw_interval_val > 0) {
1315 input_dw_interval_val >>= 1;
1316 awake_dw_int++;
1317 }
1318 }
1319 sigma_dut_print(dut, DUT_MSG_INFO,
1320 "%s:converted active DW interval = %d",
1321 __func__, awake_dw_int);
1322 config_req.config_dw.config_2dot4g_dw_band = 1;
1323 config_req.config_dw.dw_2dot4g_interval_val = awake_dw_int;
1324 config_req.config_dw.config_5g_dw_band = 1;
1325 config_req.config_dw.dw_5g_interval_val = awake_dw_int;
1326 ret = nan_config_request(0, global_interface_handle,
1327 &config_req);
1328 if (ret != WIFI_SUCCESS) {
1329 sigma_dut_print(dut, DUT_MSG_ERROR,
1330 "%s:NAN config request failed",
1331 __func__);
1332 return -2;
1333 }
1334 }
1335
Rakesh Sunki8a4845d2017-05-16 15:27:13 -07001336 if (qos_config)
1337 req.sdea_params.qos_cfg = (NanQosCfgStatus) atoi(qos_config);
1338#endif
1339
Rakesh Sunki107356c2017-03-30 14:47:55 -07001340 ret = nan_publish_request(0, global_interface_handle, &req);
1341 if (ret != WIFI_SUCCESS)
1342 send_resp(dut, conn, SIGMA_ERROR, "Unable to publish");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001343
Rakesh Sunki1a5afb92017-03-30 14:47:55 -07001344 if (ndp_enable)
1345 dut->ndp_enable = 1;
1346
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001347 return 0;
1348}
1349
1350
1351static int nan_further_availability_rx(struct sigma_dut *dut,
1352 struct sigma_conn *conn,
1353 struct sigma_cmd *cmd)
1354{
1355 const char *master_pref = get_param(cmd, "MasterPref");
1356 const char *rand_fac = get_param(cmd, "RandFactor");
1357 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001358 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001359 struct timespec abstime;
1360
1361 NanEnableRequest req;
1362
1363 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001364 req.cluster_low = 0;
1365 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001366 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001367
1368 if (master_pref)
1369 req.master_pref = strtoul(master_pref, NULL, 0);
1370
1371 if (rand_fac) {
1372 int rand_fac_val = strtoul(rand_fac, NULL, 0);
1373
1374 req.config_random_factor_force = 1;
1375 req.random_factor_force_val = rand_fac_val;
1376 }
1377
1378 if (hop_count) {
1379 int hop_count_val = strtoul(hop_count, NULL, 0);
1380
1381 req.config_hop_count_force = 1;
1382 req.hop_count_force_val = hop_count_val;
1383 }
1384
Rakesh Sunki107356c2017-03-30 14:47:55 -07001385 ret = nan_enable_request(0, global_interface_handle, &req);
1386 if (ret != WIFI_SUCCESS) {
1387 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
1388 return 0;
1389 }
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001390
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001391 abstime.tv_sec = 4;
1392 abstime.tv_nsec = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001393 wait(abstime);
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001394
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001395 return 0;
1396}
1397
1398
1399static int nan_further_availability_tx(struct sigma_dut *dut,
1400 struct sigma_conn *conn,
1401 struct sigma_cmd *cmd)
1402{
1403 const char *master_pref = get_param(cmd, "MasterPref");
1404 const char *rand_fac = get_param(cmd, "RandFactor");
1405 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001406 wifi_error ret;
1407
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001408 NanEnableRequest req;
1409 NanConfigRequest configReq;
1410
1411 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001412 req.cluster_low = 0;
1413 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001414 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001415
1416 if (master_pref)
1417 req.master_pref = strtoul(master_pref, NULL, 0);
1418
1419 if (rand_fac) {
1420 int rand_fac_val = strtoul(rand_fac, NULL, 0);
1421
1422 req.config_random_factor_force = 1;
1423 req.random_factor_force_val = rand_fac_val;
1424 }
1425
1426 if (hop_count) {
1427 int hop_count_val = strtoul(hop_count, NULL, 0);
1428
1429 req.config_hop_count_force = 1;
1430 req.hop_count_force_val = hop_count_val;
1431 }
1432
Rakesh Sunki107356c2017-03-30 14:47:55 -07001433 ret = nan_enable_request(0, global_interface_handle, &req);
1434 if (ret != WIFI_SUCCESS) {
1435 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
1436 return 0;
1437 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001438
1439 /* Start the config of fam */
1440
1441 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001442
1443 configReq.config_fam = 1;
1444 configReq.fam_val.numchans = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001445 configReq.fam_val.famchan[0].entry_control = 0;
1446 configReq.fam_val.famchan[0].class_val = 81;
1447 configReq.fam_val.famchan[0].channel = 6;
1448 configReq.fam_val.famchan[0].mapid = 0;
1449 configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe;
1450
Rakesh Sunki107356c2017-03-30 14:47:55 -07001451 ret = nan_config_request(0, global_interface_handle, &configReq);
1452 if (ret != WIFI_SUCCESS)
1453 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001454
1455 return 0;
1456}
1457
1458
1459int sigma_nan_transmit_followup(struct sigma_dut *dut,
1460 struct sigma_conn *conn,
1461 struct sigma_cmd *cmd)
1462{
1463 const char *mac = get_param(cmd, "mac");
1464 const char *requestor_id = get_param(cmd, "RemoteInstanceId");
1465 const char *local_id = get_param(cmd, "LocalInstanceId");
1466 const char *service_name = get_param(cmd, "servicename");
Rakesh Sunki107356c2017-03-30 14:47:55 -07001467 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001468 NanTransmitFollowupRequest req;
1469
1470 memset(&req, 0, sizeof(NanTransmitFollowupRequest));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001471 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001472 req.addr[0] = 0xFF;
1473 req.addr[1] = 0xFF;
1474 req.addr[2] = 0xFF;
1475 req.addr[3] = 0xFF;
1476 req.addr[4] = 0xFF;
1477 req.addr[5] = 0xFF;
1478 req.priority = NAN_TX_PRIORITY_NORMAL;
1479 req.dw_or_faw = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001480
1481 if (service_name)
1482 req.service_specific_info_len = strlen(service_name);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001483
1484 if (requestor_id) {
1485 /* int requestor_id_val = atoi(requestor_id); */
Rakesh Sunkifa417332017-08-16 15:41:32 -07001486 if (global_match_handle != 0) {
1487 req.requestor_instance_id = global_match_handle;
1488 } else {
1489 u32 requestor_id_val = atoi(requestor_id);
1490 requestor_id_val =
1491 (requestor_id_val << 24) | 0x0000FFFF;
1492 req.requestor_instance_id = requestor_id_val;
1493 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001494 }
1495 if (local_id) {
1496 /* int local_id_val = atoi(local_id); */
Rakesh Sunkifa417332017-08-16 15:41:32 -07001497 if (global_header_handle != 0)
1498 req.publish_subscribe_id = global_header_handle;
1499 else
1500 req.publish_subscribe_id = atoi(local_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001501 }
1502
1503 if (mac == NULL) {
1504 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address");
1505 return -1;
1506 }
1507 nan_parse_mac_address(dut, mac, req.addr);
1508
Rakesh Sunki107356c2017-03-30 14:47:55 -07001509 ret = nan_transmit_followup_request(0, global_interface_handle, &req);
1510 if (ret != WIFI_SUCCESS) {
1511 send_resp(dut, conn, SIGMA_ERROR,
1512 "Unable to complete nan transmit followup");
1513 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001514
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001515 return 0;
1516}
1517
Rakesh Sunki107356c2017-03-30 14:47:55 -07001518
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001519/* NotifyResponse invoked to notify the status of the Request */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001520void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001521{
1522 sigma_dut_print(global_dut, DUT_MSG_INFO,
Rakesh Sunkifdbd60b2017-03-30 14:47:55 -07001523 "%s: status %d response_type %d",
1524 __func__, rsp_data->status, rsp_data->response_type);
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001525 if (rsp_data->response_type == NAN_RESPONSE_STATS &&
1526 rsp_data->body.stats_response.stats_type ==
1527 NAN_STATS_ID_DE_TIMING_SYNC) {
1528 NanSyncStats *pSyncStats;
1529
1530 sigma_dut_print(global_dut, DUT_MSG_INFO,
1531 "%s: stats_type %d", __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001532 rsp_data->body.stats_response.stats_type);
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001533 pSyncStats = &rsp_data->body.stats_response.data.sync_stats;
1534 memcpy(&global_nan_sync_stats, pSyncStats,
1535 sizeof(NanSyncStats));
1536 pthread_cond_signal(&gCondition);
Rakesh Sunki4d5912d2017-03-30 14:47:55 -07001537 } else if (rsp_data->response_type == NAN_RESPONSE_PUBLISH) {
1538 sigma_dut_print(global_dut, DUT_MSG_INFO,
1539 "%s: publish_id %d\n",
1540 __func__,
1541 rsp_data->body.publish_response.publish_id);
1542 global_publish_id = rsp_data->body.publish_response.publish_id;
1543 } else if (rsp_data->response_type == NAN_RESPONSE_SUBSCRIBE) {
1544 sigma_dut_print(global_dut, DUT_MSG_INFO,
1545 "%s: subscribe_id %d\n",
1546 __func__,
1547 rsp_data->body.subscribe_response.subscribe_id);
1548 global_subscribe_id =
1549 rsp_data->body.subscribe_response.subscribe_id;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001550 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001551}
1552
1553
1554/* Events Callback */
1555void nan_event_publish_replied(NanPublishRepliedInd *event)
1556{
1557 sigma_dut_print(global_dut, DUT_MSG_INFO,
1558 "%s: handle %d " MAC_ADDR_STR " rssi:%d",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001559 __func__, event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001560 MAC_ADDR_ARRAY(event->addr), event->rssi_value);
1561 event_anyresponse = 1;
1562 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
Rakesh Sunkifa417332017-08-16 15:41:32 -07001563 "EventName,Replied,RemoteInstanceID,%d,LocalInstanceID,%d,mac," MAC_ADDR_STR" ",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001564 (event->requestor_instance_id >> 24),
Rakesh Sunkifa417332017-08-16 15:41:32 -07001565 (event->requestor_instance_id & 0xFFFF),
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001566 MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001567}
1568
1569
1570/* Events Callback */
1571void nan_event_publish_terminated(NanPublishTerminatedInd *event)
1572{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001573 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d",
1574 __func__, event->publish_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001575}
1576
1577
1578/* Events Callback */
1579void nan_event_match(NanMatchInd *event)
1580{
1581 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001582 "%s: Pub/Sub Id %d remote_requestor_id %08x "
1583 MAC_ADDR_STR
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001584 " rssi:%d",
1585 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001586 event->publish_subscribe_id,
1587 event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001588 MAC_ADDR_ARRAY(event->addr),
1589 event->rssi_value);
1590 event_anyresponse = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001591 global_header_handle = event->publish_subscribe_id;
1592 global_match_handle = event->requestor_instance_id;
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07001593 memcpy(global_peer_mac_addr, event->addr, sizeof(global_peer_mac_addr));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001594
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001595 /* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */
1596 /* global_pub_sub_handle = event->header.handle; */
1597 /* Print the SSI */
1598 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001599 nan_hex_dump(global_dut, event->service_specific_info,
1600 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001601 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1602 "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001603 MAC_ADDR_STR " ", (event->requestor_instance_id >> 24),
1604 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001605
1606 /* Print the match filter */
1607 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001608 nan_hex_dump(global_dut, event->sdf_match_filter,
1609 event->sdf_match_filter_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001610
1611 /* Print the conn_capability */
1612 sigma_dut_print(global_dut, DUT_MSG_INFO,
1613 "Printing PostConnectivity Capability");
1614 if (event->is_conn_capability_valid) {
1615 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s",
1616 event->conn_capability.is_wfd_supported ?
1617 "yes" : "no");
1618 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s",
1619 (event->conn_capability.is_wfds_supported ?
1620 "yes" : "no"));
1621 sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s",
1622 (event->conn_capability.is_tdls_supported ?
1623 "yes" : "no"));
1624 sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s",
1625 (event->conn_capability.is_ibss_supported ?
1626 "yes" : "no"));
1627 sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s",
1628 (event->conn_capability.is_mesh_supported ?
1629 "yes" : "no"));
1630 sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d",
1631 event->conn_capability.wlan_infra_field);
1632 } else {
1633 sigma_dut_print(global_dut, DUT_MSG_INFO,
1634 "PostConnectivity Capability not present");
1635 }
1636
1637 /* Print the discovery_attr */
1638 sigma_dut_print(global_dut, DUT_MSG_INFO,
1639 "Printing PostDiscovery Attribute");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001640 if (event->num_rx_discovery_attr) {
1641 int idx;
1642
1643 for (idx = 0; idx < event->num_rx_discovery_attr; idx++) {
1644 sigma_dut_print(global_dut, DUT_MSG_INFO,
1645 "PostDiscovery Attribute - %d", idx);
1646 sigma_dut_print(global_dut, DUT_MSG_INFO,
1647 "Conn Type:%d Device Role:%d"
1648 MAC_ADDR_STR,
1649 event->discovery_attr[idx].type,
1650 event->discovery_attr[idx].role,
1651 MAC_ADDR_ARRAY(event->discovery_attr[idx].addr));
1652 sigma_dut_print(global_dut, DUT_MSG_INFO,
1653 "Duration:%d MapId:%d "
1654 "avail_interval_bitmap:%04x",
1655 event->discovery_attr[idx].duration,
1656 event->discovery_attr[idx].mapid,
1657 event->discovery_attr[idx].avail_interval_bitmap);
1658 sigma_dut_print(global_dut, DUT_MSG_INFO,
1659 "Printing Mesh Id:");
1660 nan_hex_dump(global_dut,
1661 event->discovery_attr[idx].mesh_id,
1662 event->discovery_attr[idx].mesh_id_len);
1663 sigma_dut_print(global_dut, DUT_MSG_INFO,
1664 "Printing Infrastructure Ssid:");
1665 nan_hex_dump(global_dut,
1666 event->discovery_attr[idx].infrastructure_ssid_val,
1667 event->discovery_attr[idx].infrastructure_ssid_len);
1668 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001669 } else {
1670 sigma_dut_print(global_dut, DUT_MSG_INFO,
1671 "PostDiscovery attribute not present");
1672 }
1673
1674 /* Print the fam */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001675 if (event->num_chans) {
1676 nan_print_further_availability_chan(global_dut,
1677 event->num_chans,
1678 &event->famchan[0]);
1679 } else {
1680 sigma_dut_print(global_dut, DUT_MSG_INFO,
1681 "Further Availability Map not present");
1682 }
1683 if (event->cluster_attribute_len) {
1684 sigma_dut_print(global_dut, DUT_MSG_INFO,
1685 "Printing Cluster Attribute:");
1686 nan_hex_dump(global_dut, event->cluster_attribute,
1687 event->cluster_attribute_len);
1688 } else {
1689 sigma_dut_print(global_dut, DUT_MSG_INFO,
1690 "Cluster Attribute not present");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001691 }
1692}
1693
1694
1695/* Events Callback */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001696void nan_event_match_expired(NanMatchExpiredInd *event)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001697{
1698 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001699 "%s: publish_subscribe_id %d match_handle %08x",
1700 __func__, event->publish_subscribe_id,
1701 event->requestor_instance_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001702}
1703
1704
1705/* Events Callback */
1706void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event)
1707{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001708 sigma_dut_print(global_dut, DUT_MSG_INFO,
1709 "%s: Subscribe Id %d reason %d",
1710 __func__, event->subscribe_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001711}
1712
1713
1714/* Events Callback */
1715void nan_event_followup(NanFollowupInd *event)
1716{
1717 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001718 "%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d "
1719 MAC_ADDR_STR, __func__, event->publish_subscribe_id,
1720 event->requestor_instance_id, event->dw_or_faw,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001721 MAC_ADDR_ARRAY(event->addr));
1722
Rakesh Sunkifa417332017-08-16 15:41:32 -07001723 global_match_handle = event->requestor_instance_id;
1724 global_header_handle = event->publish_subscribe_id;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001725 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__);
1726 nan_hex_dump(global_dut, event->service_specific_info,
1727 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001728 event_anyresponse = 1;
1729 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1730 "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001731 MAC_ADDR_STR " ", event->requestor_instance_id >> 24,
1732 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001733}
1734
1735
1736/* Events Callback */
1737void nan_event_disceng_event(NanDiscEngEventInd *event)
1738{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001739 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d",
1740 __func__, event->event_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001741
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001742 if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001743 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster "
1744 MAC_ADDR_STR,
1745 __func__,
1746 MAC_ADDR_ARRAY(event->data.cluster.addr));
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001747 /* To ensure sta_get_events to get the events
1748 * only after joining the NAN cluster. */
1749 pthread_cond_signal(&gCondition);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001750 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001751 if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001752 sigma_dut_print(global_dut, DUT_MSG_INFO,
1753 "%s: Started cluster " MAC_ADDR_STR,
1754 __func__,
1755 MAC_ADDR_ARRAY(event->data.cluster.addr));
1756 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001757 if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) {
1758 sigma_dut_print(global_dut, DUT_MSG_INFO,
1759 "%s: Discovery Mac Address "
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001760 MAC_ADDR_STR,
1761 __func__,
1762 MAC_ADDR_ARRAY(event->data.mac_addr.addr));
1763 memcpy(global_nan_mac_addr, event->data.mac_addr.addr,
1764 sizeof(global_nan_mac_addr));
1765 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001766}
1767
1768
1769/* Events Callback */
1770void nan_event_disabled(NanDisabledInd *event)
1771{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001772 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d",
1773 __func__, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001774 /* pthread_cond_signal(&gCondition); */
1775}
1776
1777
Rakesh Sunki4c086672017-03-30 14:47:55 -07001778/* Events callback */
1779static void ndp_event_data_indication(NanDataPathRequestInd *event)
1780{
1781 sigma_dut_print(global_dut, DUT_MSG_INFO,
1782 "%s: Service Instance Id: %d Peer Discovery MAC ADDR "
1783 MAC_ADDR_STR
1784 " NDP Instance Id: %d App Info len %d App Info %s",
1785 __func__,
1786 event->service_instance_id,
1787 MAC_ADDR_ARRAY(event->peer_disc_mac_addr),
1788 event->ndp_instance_id,
1789 event->app_info.ndp_app_info_len,
1790 event->app_info.ndp_app_info);
1791
1792 global_ndp_instance_id = event->ndp_instance_id;
1793}
1794
1795
1796/* Events callback */
1797static void ndp_event_data_confirm(NanDataPathConfirmInd *event)
1798{
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07001799 char cmd[200];
1800 char ipv6_buf[100];
1801
Rakesh Sunki4c086672017-03-30 14:47:55 -07001802 sigma_dut_print(global_dut, DUT_MSG_INFO,
1803 "Received NDP Confirm Indication");
1804
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07001805 memset(cmd, 0, sizeof(cmd));
1806 memset(ipv6_buf, 0, sizeof(ipv6_buf));
1807
Rakesh Sunki4c086672017-03-30 14:47:55 -07001808 global_ndp_instance_id = event->ndp_instance_id;
Rakesh Sunki8f8e74b2017-05-16 15:42:12 -07001809
1810 if (event->rsp_code == NAN_DP_REQUEST_ACCEPT) {
1811 if (system("ifconfig nan0 up") != 0) {
1812 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1813 "Failed to set nan interface up");
1814 return;
1815 }
1816 if (system("ip -6 route add fe80::/64 dev nan0 table local") !=
1817 0) {
1818 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1819 "Failed to run:ip -6 route replace fe80::/64 dev nan0 table local");
1820 }
1821 convert_mac_addr_to_ipv6_lladdr(event->peer_ndi_mac_addr,
1822 ipv6_buf, sizeof(ipv6_buf));
1823 snprintf(cmd, sizeof(cmd),
1824 "ip -6 neighbor replace %s lladdr %02x:%02x:%02x:%02x:%02x:%02x nud permanent dev nan0",
1825 ipv6_buf, event->peer_ndi_mac_addr[0],
1826 event->peer_ndi_mac_addr[1],
1827 event->peer_ndi_mac_addr[2],
1828 event->peer_ndi_mac_addr[3],
1829 event->peer_ndi_mac_addr[4],
1830 event->peer_ndi_mac_addr[5]);
1831 sigma_dut_print(global_dut, DUT_MSG_INFO,
1832 "neighbor replace cmd = %s", cmd);
1833 if (system(cmd) != 0) {
1834 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1835 "Failed to run: ip -6 neighbor replace");
1836 return;
1837 }
Rakesh Sunki4c086672017-03-30 14:47:55 -07001838 }
1839}
1840
1841
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001842void * my_thread_function(void *ptr)
1843{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001844 wifi_event_loop(global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001845 pthread_exit(0);
1846 return (void *) NULL;
1847}
1848
1849
1850static NanCallbackHandler callbackHandler = {
1851 .NotifyResponse = nan_notify_response,
1852 .EventPublishReplied = nan_event_publish_replied,
1853 .EventPublishTerminated = nan_event_publish_terminated,
1854 .EventMatch = nan_event_match,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001855 .EventMatchExpired = nan_event_match_expired,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001856 .EventSubscribeTerminated = nan_event_subscribe_terminated,
1857 .EventFollowup = nan_event_followup,
1858 .EventDiscEngEvent = nan_event_disceng_event,
1859 .EventDisabled = nan_event_disabled,
Rakesh Sunki4c086672017-03-30 14:47:55 -07001860 .EventDataRequest = ndp_event_data_indication,
1861 .EventDataConfirm = ndp_event_data_confirm,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001862};
1863
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001864
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001865void nan_init(struct sigma_dut *dut)
1866{
1867 pthread_t thread1; /* thread variables */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001868 wifi_error err = wifi_initialize(&global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001869
1870 if (err) {
1871 printf("wifi hal initialize failed\n");
1872 return;
1873 }
1874
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001875 global_interface_handle = wifi_get_iface_handle(global_wifi_handle,
1876 (char *) "wlan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001877 /* create threads 1 */
1878 pthread_create(&thread1, NULL, &my_thread_function, NULL);
1879
1880 pthread_mutex_init(&gMutex, NULL);
1881 pthread_cond_init(&gCondition, NULL);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001882 if (global_interface_handle)
1883 nan_register_handler(global_interface_handle, callbackHandler);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001884}
1885
1886
1887void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1888 struct sigma_cmd *cmd)
1889{
1890 sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default");
1891
Anurag Das2052daa2018-08-31 14:35:25 +05301892#ifdef ANDROID
1893 if (dut->nanservicediscoveryinprogress) {
1894 char *argv[5];
1895 pid_t pid;
1896
1897 argv[0] = "am";
1898 argv[1] = "broadcast";
1899 argv[2] = "-a";
1900 argv[3] = "org.codeaurora.nanservicediscovery.close";
1901 argv[4] = NULL;
1902
1903 pid = fork();
1904 if (pid == -1) {
1905 sigma_dut_print(dut, DUT_MSG_ERROR, "fork: %s",
1906 strerror(errno));
1907 } else if (pid == 0) {
1908 execv("/system/bin/am", argv);
1909 sigma_dut_print(dut, DUT_MSG_ERROR, "execv: %s",
1910 strerror(errno));
1911 exit(0);
1912 }
1913 dut->nanservicediscoveryinprogress = 0;
1914 }
1915#endif /* ANDROID */
1916
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001917 if (nan_state == 0) {
1918 nan_init(dut);
1919 nan_state = 1;
1920 }
1921 is_fam = 0;
1922 event_anyresponse = 0;
1923 global_dut = dut;
Rakesh Sunki7d37f412017-03-30 14:47:55 -07001924 memset(&dut->nan_pmk[0], 0, NAN_PMK_INFO_LEN);
1925 dut->nan_pmk_len = 0;
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001926 dut->sta_channel = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001927 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
Rakesh Sunkid51e8982017-03-30 14:47:55 -07001928 memset(&global_nan_sync_stats, 0, sizeof(global_nan_sync_stats));
Rakesh Sunki42363682017-05-16 15:00:42 -07001929 memset(global_publish_service_name, 0,
1930 sizeof(global_publish_service_name));
1931 global_publish_service_name_len = 0;
1932 global_publish_id = 0;
Rakesh Sunki0262cb52017-05-17 14:22:05 -07001933 global_subscribe_id = 0;
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001934
Rakesh Sunki8a630b82017-03-30 14:47:55 -07001935 sigma_nan_data_end(dut, cmd);
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001936 nan_data_interface_delete(0, global_interface_handle, (char *) "nan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001937 sigma_nan_disable(dut, conn, cmd);
Rakesh Sunkifa417332017-08-16 15:41:32 -07001938 global_header_handle = 0;
1939 global_match_handle = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001940}
1941
1942
1943int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1944 struct sigma_cmd *cmd)
1945{
1946 const char *program = get_param(cmd, "Prog");
1947 const char *nan_op = get_param(cmd, "NANOp");
1948 const char *method_type = get_param(cmd, "MethodType");
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001949 const char *band = get_param(cmd, "band");
Anurag Das2052daa2018-08-31 14:35:25 +05301950 const char *disc_mac_addr = get_param(cmd, "DiscoveryMacAddress");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001951 char resp_buf[100];
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001952 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001953
1954 if (program == NULL)
1955 return -1;
1956
1957 if (strcasecmp(program, "NAN") != 0) {
1958 send_resp(dut, conn, SIGMA_ERROR,
1959 "ErrorCode,Unsupported program");
1960 return 0;
1961 }
1962
1963 if (nan_op) {
Rakesh Sunkib5604ff2017-05-16 15:47:08 -07001964#if NAN_CERT_VERSION >= 3
1965 int size = 0;
1966 u32 device_type_val = 0;
1967 NanDebugParams cfg_debug;
1968
1969 memset(&cfg_debug, 0, sizeof(NanDebugParams));
1970 cfg_debug.cmd = NAN_TEST_MODE_CMD_DEVICE_TYPE;
1971 if (dut->device_type == STA_testbed)
1972 device_type_val = NAN_DEVICE_TYPE_TEST_BED;
1973 else if (dut->device_type == STA_dut)
1974 device_type_val = NAN_DEVICE_TYPE_DUT;
1975
1976 memcpy(cfg_debug.debug_cmd_data, &device_type_val, sizeof(u32));
1977 size = sizeof(u32) + sizeof(u32);
1978 sigma_dut_print(dut, DUT_MSG_INFO,
1979 "%s: Device Type: cmd type = %d and command data = %u",
1980 __func__, cfg_debug.cmd, device_type_val);
1981 nan_debug_command_config(0, global_interface_handle,
1982 cfg_debug, size);
1983#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001984 /*
1985 * NANOp has been specified.
1986 * We will build a nan_enable or nan_disable command.
1987 */
1988 if (strcasecmp(nan_op, "On") == 0) {
1989 if (sigma_nan_enable(dut, conn, cmd) == 0) {
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001990 ret = nan_data_interface_create(
1991 0, global_interface_handle,
1992 (char *) "nan0");
1993 if (ret != WIFI_SUCCESS) {
1994 sigma_dut_print(
1995 global_dut, DUT_MSG_ERROR,
1996 "Unable to create NAN data interface");
1997 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001998 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1999 MAC_ADDR_STR,
2000 MAC_ADDR_ARRAY(global_nan_mac_addr));
2001 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
2002 } else {
2003 send_resp(dut, conn, SIGMA_ERROR,
2004 "NAN_ENABLE_FAILED");
2005 return -1;
2006 }
Rakesh Sunkid7344c02017-03-30 14:47:55 -07002007
2008 if (band && strcasecmp(band, "24g") == 0) {
2009 sigma_dut_print(dut, DUT_MSG_INFO,
2010 "%s: Setting band to 2G Only",
2011 __func__);
2012 sigma_ndp_configure_band(
2013 dut, conn, cmd,
2014 NAN_DATA_PATH_SUPPORTED_BAND_2G);
2015 } else if (band && dut->sta_channel > 12) {
2016 sigma_ndp_configure_band(
2017 dut, conn, cmd,
2018 NAN_DATA_PATH_SUPPORT_DUAL_BAND);
2019 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002020 } else if (strcasecmp(nan_op, "Off") == 0) {
Rakesh Sunkibcf9ef32017-08-16 15:53:27 -07002021 nan_data_interface_delete(0,
2022 global_interface_handle, (char *) "nan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002023 sigma_nan_disable(dut, conn, cmd);
Rakesh Sunki42363682017-05-16 15:00:42 -07002024 memset(global_publish_service_name, 0,
2025 sizeof(global_publish_service_name));
2026 global_publish_service_name_len = 0;
2027 global_publish_id = 0;
Rakesh Sunki0262cb52017-05-17 14:22:05 -07002028 global_subscribe_id = 0;
Rakesh Sunkifa417332017-08-16 15:41:32 -07002029 global_header_handle = 0;
2030 global_match_handle = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002031 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2032 }
2033 }
2034 if (nan_state && nan_op == NULL) {
2035 if (method_type) {
2036 if (strcasecmp(method_type, "Publish") == 0) {
2037 sigma_nan_publish_request(dut, conn, cmd);
2038 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2039 }
2040 if (strcasecmp(method_type, "Subscribe") == 0) {
2041 sigma_nan_subscribe_request(dut, conn, cmd);
2042 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2043 }
2044 if (strcasecmp(method_type, "Followup") == 0) {
2045 sigma_nan_transmit_followup(dut, conn, cmd);
2046 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2047 }
Rakesh Sunki14cfcd22017-03-30 14:47:55 -07002048 if (strcasecmp(method_type, "DataRequest") == 0) {
2049 sigma_nan_data_request(dut, conn, cmd);
2050 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2051 }
Rakesh Sunkia5cc2842017-03-30 14:47:55 -07002052 if (strcasecmp(method_type, "DataResponse") == 0) {
2053 sigma_dut_print(dut, DUT_MSG_INFO,
2054 "%s: method_type is DataResponse",
2055 __func__);
2056 sigma_nan_data_response(dut, conn, cmd);
2057 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2058 }
Rakesh Sunki8a630b82017-03-30 14:47:55 -07002059 if (strcasecmp(method_type, "DataEnd") == 0) {
2060 sigma_nan_data_end(dut, cmd);
2061 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2062 }
Rakesh Sunkid5e9b4d2017-03-30 14:47:55 -07002063 if (strcasecmp(method_type, "rangerequest") == 0) {
2064 sigma_dut_print(dut, DUT_MSG_INFO,
2065 "%s: method_type is rangerequest",
2066 __func__);
2067 sigma_nan_range_request(dut, cmd);
2068 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2069 }
2070 if (strcasecmp(method_type, "cancelrange") == 0) {
2071 sigma_dut_print(dut, DUT_MSG_INFO,
2072 "%s: method_type is cancelrange",
2073 __func__);
2074 sigma_nan_cancel_range(dut, cmd);
2075 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2076 }
Rakesh Sunkib2b65162017-03-30 14:47:55 -07002077 if (strcasecmp(method_type, "SchedUpdate") == 0) {
2078 sigma_dut_print(dut, DUT_MSG_INFO,
2079 "%s: method_type is SchedUpdate",
2080 __func__);
2081 sigma_nan_schedule_update(dut, cmd);
2082 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
2083 }
Anurag Das2052daa2018-08-31 14:35:25 +05302084 } else if (disc_mac_addr &&
2085 strcasecmp(disc_mac_addr, "GET") == 0) {
2086 snprintf(resp_buf, sizeof(resp_buf), "mac,"
2087 MAC_ADDR_STR,
2088 MAC_ADDR_ARRAY(global_nan_mac_addr));
2089 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002090 } else {
2091 sigma_nan_config_enable(dut, conn, cmd);
2092 snprintf(resp_buf, sizeof(resp_buf), "mac,"
2093 MAC_ADDR_STR,
2094 MAC_ADDR_ARRAY(global_nan_mac_addr));
2095 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
2096 }
2097 }
2098
2099 return 0;
2100}
2101
2102
2103int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
2104 struct sigma_cmd *cmd)
2105{
2106
2107 const char *program = get_param(cmd, "Program");
2108 const char *parameter = get_param(cmd, "Parameter");
2109 char resp_buf[100];
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002110 NanStatsRequest req;
2111 struct timespec abstime;
2112 u64 master_rank;
2113 u8 master_pref;
2114 u8 random_factor;
2115 u8 hop_count;
2116 u32 beacon_transmit_time;
2117 u32 ndp_channel_freq;
2118 u32 ndp_channel_freq2;
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002119#if NAN_CERT_VERSION >= 3
2120 u32 sched_update_channel_freq;
2121#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002122
2123 if (program == NULL) {
2124 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name");
2125 return -1;
2126 }
2127 if (strcasecmp(program, "NAN") != 0) {
2128 send_resp(dut, conn, SIGMA_ERROR,
2129 "ErrorCode,Unsupported program");
2130 return 0;
2131 }
2132
2133 if (parameter == NULL) {
2134 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter");
2135 return -1;
2136 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002137
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002138 memset(&req, 0, sizeof(NanStatsRequest));
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002139 memset(resp_buf, 0, sizeof(resp_buf));
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002140 req.stats_type = (NanStatsType) NAN_STATS_ID_DE_TIMING_SYNC;
2141 nan_stats_request(0, global_interface_handle, &req);
2142 /*
2143 * To ensure sta_get_events to get the events
2144 * only after joining the NAN cluster
2145 */
2146 abstime.tv_sec = 4;
2147 abstime.tv_nsec = 0;
2148 wait(abstime);
2149
2150 master_rank = global_nan_sync_stats.myRank;
2151 master_pref = (global_nan_sync_stats.myRank & 0xFF00000000000000) >> 56;
2152 random_factor = (global_nan_sync_stats.myRank & 0x00FF000000000000) >>
2153 48;
2154 hop_count = global_nan_sync_stats.currAmHopCount;
2155 beacon_transmit_time = global_nan_sync_stats.currAmBTT;
2156 ndp_channel_freq = global_nan_sync_stats.ndpChannelFreq;
2157 ndp_channel_freq2 = global_nan_sync_stats.ndpChannelFreq2;
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002158#if NAN_CERT_VERSION >= 3
2159 sched_update_channel_freq =
2160 global_nan_sync_stats.schedUpdateChannelFreq;
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002161
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002162 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002163 "%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",
2164 __func__, master_pref, random_factor,
2165 hop_count, beacon_transmit_time,
2166 ndp_channel_freq, ndp_channel_freq2,
2167 sched_update_channel_freq);
2168#else /* #if NAN_CERT_VERSION >= 3 */
2169 sigma_dut_print(dut, DUT_MSG_INFO,
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002170 "%s: NanStatsRequest Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d ndp_channel_freq:%d ndp_channel_freq2:%d",
2171 __func__, master_pref, random_factor,
2172 hop_count, beacon_transmit_time,
2173 ndp_channel_freq, ndp_channel_freq2);
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002174#endif /* #if NAN_CERT_VERSION >= 3 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002175
2176 if (strcasecmp(parameter, "MasterPref") == 0) {
2177 snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002178 master_pref);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002179 } else if (strcasecmp(parameter, "MasterRank") == 0) {
2180 snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002181 master_rank);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002182 } else if (strcasecmp(parameter, "RandFactor") == 0) {
2183 snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002184 random_factor);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002185 } else if (strcasecmp(parameter, "HopCount") == 0) {
2186 snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002187 hop_count);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002188 } else if (strcasecmp(parameter, "BeaconTransTime") == 0) {
2189 snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x",
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002190 beacon_transmit_time);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002191 } else if (strcasecmp(parameter, "NANStatus") == 0) {
2192 if (nan_state == 1)
2193 snprintf(resp_buf, sizeof(resp_buf), "On");
2194 else
2195 snprintf(resp_buf, sizeof(resp_buf), "Off");
Rakesh Sunkid51e8982017-03-30 14:47:55 -07002196 } else if (strcasecmp(parameter, "NDPChannel") == 0) {
2197 if (ndp_channel_freq != 0 && ndp_channel_freq2 != 0) {
2198 snprintf(resp_buf, sizeof(resp_buf),
2199 "ndpchannel,%d,ndpchannel,%d",
2200 freq_to_channel(ndp_channel_freq),
2201 freq_to_channel(ndp_channel_freq2));
2202 } else if (ndp_channel_freq != 0) {
2203 snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
2204 freq_to_channel(ndp_channel_freq));
2205 } else if (ndp_channel_freq2 != 0) {
2206 snprintf(resp_buf, sizeof(resp_buf), "ndpchannel,%d",
2207 freq_to_channel(ndp_channel_freq2));
2208 } else {
2209 sigma_dut_print(dut, DUT_MSG_ERROR,
2210 "%s: No Negotiated NDP Channels", __func__);
2211 }
Rakesh Sunkia3b59662017-05-16 15:52:33 -07002212#if NAN_CERT_VERSION >= 3
2213 } else if (strcasecmp(parameter, "SchedUpdateChannel") == 0) {
2214 snprintf(resp_buf, sizeof(resp_buf), "schedupdatechannel,%d",
2215 freq_to_channel(sched_update_channel_freq));
2216#endif
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002217 } else {
2218 send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
2219 return 0;
2220 }
2221
2222 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
2223 return 0;
2224}
2225
2226
2227int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
2228 struct sigma_cmd *cmd)
2229{
2230 const char *action = get_param(cmd, "Action");
2231
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07002232 if (!action)
2233 return 0;
2234
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002235 /* Check action for start, stop and get events. */
2236 if (strcasecmp(action, "Start") == 0) {
2237 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
2238 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
2239 } else if (strcasecmp(action, "Stop") == 0) {
2240 event_anyresponse = 0;
2241 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
2242 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
2243 } else if (strcasecmp(action, "Get") == 0) {
2244 if (event_anyresponse == 1) {
2245 send_resp(dut, conn, SIGMA_COMPLETE,
2246 global_event_resp_buf);
2247 } else {
2248 send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE");
2249 }
2250 }
2251 return 0;
2252}
Rakesh Sunki4b75f962017-03-30 14:47:55 -07002253
2254#else /* #if NAN_CERT_VERSION */
2255
2256int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
2257 struct sigma_conn *conn,
2258 struct sigma_cmd *cmd)
2259{
2260 return 1;
2261}
2262
2263
2264int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
2265 struct sigma_cmd *cmd)
2266{
2267 return 0;
2268
2269}
2270
2271
2272void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
2273 struct sigma_cmd *cmd)
2274{
2275 return;
2276}
2277
2278
2279int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
2280 struct sigma_cmd *cmd)
2281{
2282 return 0;
2283}
2284
2285
2286int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
2287 struct sigma_cmd *cmd)
2288{
2289 return 0;
2290}
2291
2292#endif /* #if NAN_CERT_VERSION */