blob: edbccb85df9eedc3b1681e60f8cb7e66e132aa3d [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (NAN functionality)
Rakesh Sunki4b75f962017-03-30 14:47:55 -07003 * Copyright (c) 2014-2017, Qualcomm Atheros, Inc.
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004 * All Rights Reserved.
5 * Licensed under the Clear BSD license. See README for more details.
6 */
7
8#include "sigma_dut.h"
9#include <sys/stat.h>
10#include "wpa_ctrl.h"
11#include "wpa_helpers.h"
12#include "wifi_hal.h"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -070013#include "nan_cert.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014
Rakesh Sunki4b75f962017-03-30 14:47:55 -070015#if NAN_CERT_VERSION >= 2
16
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017pthread_cond_t gCondition;
18pthread_mutex_t gMutex;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -070019wifi_handle global_wifi_handle;
20wifi_interface_handle global_interface_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020021static int nan_state = 0;
22static int event_anyresponse = 0;
23static int is_fam = 0;
24
Rakesh Sunki4c086672017-03-30 14:47:55 -070025static uint16_t global_ndp_instance_id = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020026uint16_t global_header_handle = 0;
27uint32_t global_match_handle = 0;
28
29#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
30#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
31#ifndef ETH_ALEN
32#define ETH_ALEN 6
33#endif
34
35struct sigma_dut *global_dut = NULL;
36static char global_nan_mac_addr[ETH_ALEN];
37static char global_event_resp_buf[1024];
38
39static int nan_further_availability_tx(struct sigma_dut *dut,
40 struct sigma_conn *conn,
41 struct sigma_cmd *cmd);
42static int nan_further_availability_rx(struct sigma_dut *dut,
43 struct sigma_conn *conn,
44 struct sigma_cmd *cmd);
45
46
47void nan_hex_dump(struct sigma_dut *dut, uint8_t *data, size_t len)
48{
49 char buf[512];
50 uint16_t index;
51 uint8_t *ptr;
52 int pos;
53
54 memset(buf, 0, sizeof(buf));
55 ptr = data;
56 pos = 0;
57 for (index = 0; index < len; index++) {
58 pos += sprintf(&(buf[pos]), "%02x ", *ptr++);
59 if (pos > 508)
60 break;
61 }
62 sigma_dut_print(dut, DUT_MSG_INFO, "HEXDUMP len=[%d]", (int) len);
63 sigma_dut_print(dut, DUT_MSG_INFO, "buf:%s", buf);
64}
65
66
67int nan_parse_hex(unsigned char c)
68{
69 if (c >= '0' && c <= '9')
70 return c - '0';
71 if (c >= 'a' && c <= 'f')
72 return c - 'a' + 10;
73 if (c >= 'A' && c <= 'F')
74 return c - 'A' + 10;
75 return 0;
76}
77
78
79int nan_parse_token(const char *tokenIn, u8 *tokenOut, int *filterLen)
80{
81 int total_len = 0, len = 0;
82 char *saveptr = NULL;
83
84 tokenIn = strtok_r((char *) tokenIn, ":", &saveptr);
85 while (tokenIn != NULL) {
86 len = strlen(tokenIn);
87 if (len == 1 && *tokenIn == '*')
88 len = 0;
89 tokenOut[total_len++] = (u8) len;
90 if (len != 0)
91 memcpy((u8 *) tokenOut + total_len, tokenIn, len);
92 total_len += len;
93 tokenIn = strtok_r(NULL, ":", &saveptr);
94 }
95 *filterLen = total_len;
96 return 0;
97}
98
99
100int nan_parse_mac_address(struct sigma_dut *dut, const char *arg, u8 *addr)
101{
102 if (strlen(arg) != 17) {
103 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid mac address %s",
104 arg);
105 sigma_dut_print(dut, DUT_MSG_ERROR,
106 "expected format xx:xx:xx:xx:xx:xx");
107 return -1;
108 }
109
110 addr[0] = nan_parse_hex(arg[0]) << 4 | nan_parse_hex(arg[1]);
111 addr[1] = nan_parse_hex(arg[3]) << 4 | nan_parse_hex(arg[4]);
112 addr[2] = nan_parse_hex(arg[6]) << 4 | nan_parse_hex(arg[7]);
113 addr[3] = nan_parse_hex(arg[9]) << 4 | nan_parse_hex(arg[10]);
114 addr[4] = nan_parse_hex(arg[12]) << 4 | nan_parse_hex(arg[13]);
115 addr[5] = nan_parse_hex(arg[15]) << 4 | nan_parse_hex(arg[16]);
116
117 return 0;
118}
119
120
121int nan_parse_mac_address_list(struct sigma_dut *dut, const char *input,
122 u8 *output, u16 max_addr_allowed)
123{
124 /*
125 * Reads a list of mac address separated by space. Each MAC address
126 * should have the format of aa:bb:cc:dd:ee:ff.
127 */
128 char *saveptr;
129 char *token;
130 int i = 0;
131
132 for (i = 0; i < max_addr_allowed; i++) {
133 token = strtok_r((i == 0) ? (char *) input : NULL,
134 " ", &saveptr);
135 if (token) {
136 nan_parse_mac_address(dut, token, output);
137 output += NAN_MAC_ADDR_LEN;
138 } else
139 break;
140 }
141
142 sigma_dut_print(dut, DUT_MSG_INFO, "Num MacAddress:%d", i);
143
144 return i;
145}
146
147
148int nan_parse_hex_string(struct sigma_dut *dut, const char *input,
149 u8 *output, int *outputlen)
150{
151 int i = 0;
152 int j = 0;
153
154 for (i = 0; i < (int) strlen(input) && j < *outputlen; i += 2) {
155 output[j] = nan_parse_hex(input[i]);
156 if (i + 1 < (int) strlen(input)) {
157 output[j] = ((output[j] << 4) |
158 nan_parse_hex(input[i + 1]));
159 }
160 j++;
161 }
162 *outputlen = j;
163 sigma_dut_print(dut, DUT_MSG_INFO, "Input:%s inputlen:%d outputlen:%d",
164 input, (int) strlen(input), (int) *outputlen);
165 return 0;
166}
167
168
169int wait(struct timespec abstime)
170{
171 struct timeval now;
172
173 gettimeofday(&now, NULL);
174
175 abstime.tv_sec += now.tv_sec;
176 if (((abstime.tv_nsec + now.tv_usec * 1000) > 1000 * 1000 * 1000) ||
177 (abstime.tv_nsec + now.tv_usec * 1000 < 0)) {
178 abstime.tv_sec += 1;
179 abstime.tv_nsec += now.tv_usec * 1000;
180 abstime.tv_nsec -= 1000 * 1000 * 1000;
181 } else {
182 abstime.tv_nsec += now.tv_usec * 1000;
183 }
184
185 return pthread_cond_timedwait(&gCondition, &gMutex, &abstime);
186}
187
188
189int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
190 struct sigma_conn *conn,
191 struct sigma_cmd *cmd)
192{
193 const char *oper_chan = get_param(cmd, "oper_chan");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200194
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700195 if (oper_chan)
196 dut->sta_channel = atoi(oper_chan);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200197
198 return 0;
199}
200
201
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700202void nan_print_further_availability_chan(struct sigma_dut *dut,
203 u8 num_chans,
204 NanFurtherAvailabilityChannel *fachan)
205{
206 int idx;
207
208 sigma_dut_print(dut, DUT_MSG_INFO,
209 "********Printing FurtherAvailabilityChan Info******");
210 sigma_dut_print(dut, DUT_MSG_INFO, "Numchans:%d", num_chans);
211 for (idx = 0; idx < num_chans; idx++) {
212 sigma_dut_print(dut, DUT_MSG_INFO,
213 "[%d]: NanAvailDuration:%d class_val:%02x channel:%d",
214 idx, fachan->entry_control,
215 fachan->class_val, fachan->channel);
216 sigma_dut_print(dut, DUT_MSG_INFO,
217 "[%d]: mapid:%d Availability bitmap:%08x",
218 idx, fachan->mapid,
219 fachan->avail_interval_bitmap);
220 }
221 sigma_dut_print(dut, DUT_MSG_INFO,
222 "*********************Done**********************");
223}
224
225
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200226int sigma_nan_enable(struct sigma_dut *dut, struct sigma_conn *conn,
227 struct sigma_cmd *cmd)
228{
229 const char *master_pref = get_param(cmd, "MasterPref");
230 const char *rand_fac = get_param(cmd, "RandFactor");
231 const char *hop_count = get_param(cmd, "HopCount");
232 const char *high_tsf = get_param(cmd, "HighTSF");
233 const char *sdftx_band = get_param(cmd, "SDFTxBand");
234 const char *oper_chan = get_param(cmd, "oper_chn");
235 const char *further_avail_ind = get_param(cmd, "FurtherAvailInd");
236 const char *band = get_param(cmd, "Band");
237 const char *only_5g = get_param(cmd, "5GOnly");
238 struct timespec abstime;
239 NanEnableRequest req;
240
241 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200242 req.cluster_low = 0;
243 req.cluster_high = 0xFFFF;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700244 req.master_pref = 100;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200245
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700246 /* This is a debug hack to beacon in channel 11 */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200247 if (oper_chan) {
248 req.config_2dot4g_support = 1;
249 req.support_2dot4g_val = 111;
250 }
251
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200252 if (master_pref) {
253 int master_pref_val = strtoul(master_pref, NULL, 0);
254
255 req.master_pref = master_pref_val;
256 }
257
258 if (rand_fac) {
259 int rand_fac_val = strtoul(rand_fac, NULL, 0);
260
261 req.config_random_factor_force = 1;
262 req.random_factor_force_val = rand_fac_val;
263 }
264
265 if (hop_count) {
266 int hop_count_val = strtoul(hop_count, NULL, 0);
267
268 req.config_hop_count_force = 1;
269 req.hop_count_force_val = hop_count_val;
270 }
271
272 if (sdftx_band) {
273 if (strcasecmp(sdftx_band, "5G") == 0) {
274 req.config_2dot4g_support = 1;
275 req.support_2dot4g_val = 0;
276 }
277 }
278
279 if (band) {
280 if (strcasecmp(band, "24G") == 0) {
281 sigma_dut_print(dut, DUT_MSG_INFO,
282 "Band 2.4GHz selected");
283 /* Enable 2.4G support */
284 req.config_2dot4g_support = 1;
285 req.support_2dot4g_val = 1;
286 req.config_2dot4g_beacons = 1;
287 req.beacon_2dot4g_val = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700288 req.config_2dot4g_sdf = 1;
289 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200290
291 /* Disable 5G support */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700292 req.config_support_5g = 1;
293 req.support_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200294 req.config_5g_beacons = 1;
295 req.beacon_5g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700296 req.config_5g_sdf = 1;
297 req.sdf_5g_val = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200298 }
299 }
300
301 if (further_avail_ind) {
302 sigma_dut_print(dut, DUT_MSG_INFO, "FAM Test Enabled");
303 if (strcasecmp(further_avail_ind, "tx") == 0) {
304 is_fam = 1;
305 nan_further_availability_tx(dut, conn, cmd);
306 return 0;
307 } else if (strcasecmp(further_avail_ind, "rx") == 0) {
308 nan_further_availability_rx(dut, conn, cmd);
309 return 0;
310 }
311 }
312
313 if (only_5g && atoi(only_5g)) {
314 sigma_dut_print(dut, DUT_MSG_INFO, "5GHz only enabled");
315 req.config_2dot4g_support = 1;
316 req.support_2dot4g_val = 1;
317 req.config_2dot4g_beacons = 1;
318 req.beacon_2dot4g_val = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700319 req.config_2dot4g_sdf = 1;
320 req.sdf_2dot4g_val = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200321 }
322
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700323 nan_enable_request(0, global_interface_handle, &req);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700324
325 /* To ensure sta_get_events to get the events
326 * only after joining the NAN cluster. */
327 abstime.tv_sec = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200328 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700329 wait(abstime);
330
331 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200332}
333
334
335int sigma_nan_disable(struct sigma_dut *dut, struct sigma_conn *conn,
336 struct sigma_cmd *cmd)
337{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200338 struct timespec abstime;
339
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700340 nan_disable_request(0, global_interface_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200341
342 abstime.tv_sec = 4;
343 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700344 wait(abstime);
345
346 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200347}
348
349
350int sigma_nan_config_enable(struct sigma_dut *dut, struct sigma_conn *conn,
351 struct sigma_cmd *cmd)
352{
353 const char *master_pref = get_param(cmd, "MasterPref");
354 const char *rand_fac = get_param(cmd, "RandFactor");
355 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700356 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200357 struct timespec abstime;
358 NanConfigRequest req;
359
360 memset(&req, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200361 req.config_rssi_proximity = 1;
362 req.rssi_proximity = 70;
363
364 if (master_pref) {
365 int master_pref_val = strtoul(master_pref, NULL, 0);
366
367 req.config_master_pref = 1;
368 req.master_pref = master_pref_val;
369 }
370
371 if (rand_fac) {
372 int rand_fac_val = strtoul(rand_fac, NULL, 0);
373
374 req.config_random_factor_force = 1;
375 req.random_factor_force_val = rand_fac_val;
376 }
377
378 if (hop_count) {
379 int hop_count_val = strtoul(hop_count, NULL, 0);
380
381 req.config_hop_count_force = 1;
382 req.hop_count_force_val = hop_count_val;
383 }
384
Rakesh Sunki107356c2017-03-30 14:47:55 -0700385 ret = nan_config_request(0, global_interface_handle, &req);
386 if (ret != WIFI_SUCCESS)
387 send_resp(dut, conn, SIGMA_ERROR, "NAN config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200388
389 abstime.tv_sec = 4;
390 abstime.tv_nsec = 0;
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700391 wait(abstime);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200392
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700393 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200394}
395
396
397static int sigma_nan_subscribe_request(struct sigma_dut *dut,
398 struct sigma_conn *conn,
399 struct sigma_cmd *cmd)
400{
401 const char *subscribe_type = get_param(cmd, "SubscribeType");
402 const char *service_name = get_param(cmd, "ServiceName");
403 const char *disc_range = get_param(cmd, "DiscoveryRange");
404 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
405 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
406 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
407 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
408 const char *include_bit = get_param(cmd, "IncludeBit");
409 const char *mac = get_param(cmd, "MAC");
410 const char *srf_type = get_param(cmd, "SRFType");
411 NanSubscribeRequest req;
412 int filter_len_rx = 0, filter_len_tx = 0;
413 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
414 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700415 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200416
417 memset(&req, 0, sizeof(NanSubscribeRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200418 req.ttl = 0;
419 req.period = 1000;
420 req.subscribe_type = 1;
421 req.serviceResponseFilter = 1; /* MAC */
422 req.serviceResponseInclude = 0;
423 req.ssiRequiredForMatchIndication = 0;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700424 req.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200425 req.subscribe_count = 0;
426
427 if (subscribe_type) {
428 if (strcasecmp(subscribe_type, "Active") == 0) {
429 req.subscribe_type = 1;
430 } else if (strcasecmp(subscribe_type, "Passive") == 0) {
431 req.subscribe_type = 0;
432 } else if (strcasecmp(subscribe_type, "Cancel") == 0) {
433 NanSubscribeCancelRequest req;
434
435 memset(&req, 0, sizeof(NanSubscribeCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700436 ret = nan_subscribe_cancel_request(
437 0, global_interface_handle, &req);
438 if (ret != WIFI_SUCCESS) {
439 send_resp(dut, conn, SIGMA_ERROR,
440 "NAN subscribe cancel request failed");
441 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200442 return 0;
443 }
444 }
445
446 if (disc_range)
447 req.rssi_threshold_flag = atoi(disc_range);
448
449 if (sdftx_dw)
450 req.subscribe_count = atoi(sdftx_dw);
451
452 /* Check this once again if config can be called here (TBD) */
453 if (discrange_ltd)
454 req.rssi_threshold_flag = atoi(discrange_ltd);
455
456 if (include_bit) {
457 int include_bit_val = atoi(include_bit);
458
459 req.serviceResponseInclude = include_bit_val;
460 sigma_dut_print(dut, DUT_MSG_INFO, "Includebit set %d",
461 req.serviceResponseInclude);
462 }
463
464 if (srf_type) {
465 int srf_type_val = atoi(srf_type);
466
467 if (srf_type_val == 1)
468 req.serviceResponseFilter = 0; /* Bloom */
469 else
470 req.serviceResponseFilter = 1; /* MAC */
471 req.useServiceResponseFilter = 1;
472 sigma_dut_print(dut, DUT_MSG_INFO, "srfFilter %d",
473 req.serviceResponseFilter);
474 }
475
476 if (mac) {
477 sigma_dut_print(dut, DUT_MSG_INFO, "MAC_ADDR List %s", mac);
478 req.num_intf_addr_present = nan_parse_mac_address_list(
479 dut, mac, &req.intf_addr[0][0],
480 NAN_MAX_SUBSCRIBE_MAX_ADDRESS);
481 }
482
483 memset(input_rx, 0, sizeof(input_rx));
484 memset(input_tx, 0, sizeof(input_tx));
485 if (rx_match_filter) {
486 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
487 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
488 filter_len_rx);
489 }
490 if (tx_match_filter) {
491 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
492 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
493 filter_len_tx);
494 }
495
496 if (tx_match_filter) {
497 req.tx_match_filter_len = filter_len_tx;
498 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
499 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
500 }
501 if (rx_match_filter) {
502 req.rx_match_filter_len = filter_len_rx;
503 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
504 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
505 }
506
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700507 if (service_name) {
508 strlcpy((char *) req.service_name, service_name,
509 strlen(service_name) + 1);
510 req.service_name_len = strlen(service_name);
511 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200512
Rakesh Sunki107356c2017-03-30 14:47:55 -0700513 ret = nan_subscribe_request(0, global_interface_handle, &req);
514 if (ret != WIFI_SUCCESS) {
515 send_resp(dut, conn, SIGMA_ERROR,
516 "NAN subscribe request failed");
517 }
518
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200519 return 0;
520}
521
522
Rakesh Sunkid7344c02017-03-30 14:47:55 -0700523static int sigma_ndp_configure_band(struct sigma_dut *dut,
524 struct sigma_conn *conn,
525 struct sigma_cmd *cmd,
526 NdpSupportedBand band_config_val)
527{
528 wifi_error ret;
529 NanDebugParams cfg_debug;
530 int size;
531
532 memset(&cfg_debug, 0, sizeof(NanDebugParams));
533 cfg_debug.cmd = NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS;
534 memcpy(cfg_debug.debug_cmd_data, &band_config_val, sizeof(int));
535 sigma_dut_print(dut, DUT_MSG_INFO, "%s:setting debug cmd=0x%x",
536 __func__, cfg_debug.cmd);
537 size = sizeof(u32) + sizeof(int);
538 ret = nan_debug_command_config(0, global_interface_handle, cfg_debug,
539 size);
540 if (ret != WIFI_SUCCESS)
541 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
542
543 return 0;
544}
545
546
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200547int config_post_disc_attr(void)
548{
Rakesh Sunki107356c2017-03-30 14:47:55 -0700549 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200550 NanConfigRequest configReq;
551
552 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200553
554 /* Configure Post disc attr */
555 /* Make these defines and use correct enum */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700556 configReq.num_config_discovery_attr = 1;
557 configReq.discovery_attr_val[0].type = 4; /* Further Nan discovery */
558 configReq.discovery_attr_val[0].role = 0;
559 configReq.discovery_attr_val[0].transmit_freq = 1;
560 configReq.discovery_attr_val[0].duration = 0;
561 configReq.discovery_attr_val[0].avail_interval_bitmap = 0x00000008;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200562
Rakesh Sunki107356c2017-03-30 14:47:55 -0700563 ret = nan_config_request(0, global_interface_handle, &configReq);
564 if (ret != WIFI_SUCCESS) {
565 sigma_dut_print(global_dut, DUT_MSG_INFO,
566 "NAN config request failed while configuring post discovery attribute");
567 }
568
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200569 return 0;
570}
571
572
573int sigma_nan_publish_request(struct sigma_dut *dut, struct sigma_conn *conn,
574 struct sigma_cmd *cmd)
575{
576 const char *publish_type = get_param(cmd, "PublishType");
577 const char *service_name = get_param(cmd, "ServiceName");
578 const char *disc_range = get_param(cmd, "DiscoveryRange");
579 const char *rx_match_filter = get_param(cmd, "rxMatchFilter");
580 const char *tx_match_filter = get_param(cmd, "txMatchFilter");
581 const char *sdftx_dw = get_param(cmd, "SDFTxDW");
582 const char *discrange_ltd = get_param(cmd, "DiscRangeLtd");
583 NanPublishRequest req;
584 int filter_len_rx = 0, filter_len_tx = 0;
585 u8 input_rx[NAN_MAX_MATCH_FILTER_LEN];
586 u8 input_tx[NAN_MAX_MATCH_FILTER_LEN];
Rakesh Sunki107356c2017-03-30 14:47:55 -0700587 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200588
589 memset(&req, 0, sizeof(NanPublishRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200590 req.ttl = 0;
591 req.period = 500;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700592 req.publish_match_indicator = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200593 req.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
594 req.tx_type = NAN_TX_TYPE_BROADCAST;
595 req.publish_count = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700596
597 if (service_name) {
598 strlcpy((char *) req.service_name, service_name,
599 strlen(service_name) + 1);
600 req.service_name_len = strlen(service_name);
601 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200602
603 if (publish_type) {
604 if (strcasecmp(publish_type, "Solicited") == 0) {
605 req.publish_type = NAN_PUBLISH_TYPE_SOLICITED;
606 } else if (strcasecmp(publish_type, "Cancel") == 0) {
607 NanPublishCancelRequest req;
608
609 memset(&req, 0, sizeof(NanPublishCancelRequest));
Rakesh Sunki107356c2017-03-30 14:47:55 -0700610 ret = nan_publish_cancel_request(
611 0, global_interface_handle, &req);
612 if (ret != WIFI_SUCCESS) {
613 send_resp(dut, conn, SIGMA_ERROR,
614 "Unable to cancel nan publish request");
615 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200616 return 0;
617 }
618 }
619
620 if (disc_range)
621 req.rssi_threshold_flag = atoi(disc_range);
622
623 if (sdftx_dw)
624 req.publish_count = atoi(sdftx_dw);
625
626 if (discrange_ltd)
627 req.rssi_threshold_flag = atoi(discrange_ltd);
628
629 memset(input_rx, 0, sizeof(input_rx));
630 memset(input_tx, 0, sizeof(input_tx));
631 if (rx_match_filter) {
632 nan_parse_token(rx_match_filter, input_rx, &filter_len_rx);
633 sigma_dut_print(dut, DUT_MSG_INFO, "RxFilterLen %d",
634 filter_len_rx);
635 }
636 if (tx_match_filter) {
637 nan_parse_token(tx_match_filter, input_tx, &filter_len_tx);
638 sigma_dut_print(dut, DUT_MSG_INFO, "TxFilterLen %d",
639 filter_len_tx);
640 }
641
642 if (is_fam == 1) {
643 config_post_disc_attr();
644 /* TODO: Add comments regarding this step */
645 req.connmap = 0x10;
646 }
647
648 if (tx_match_filter) {
649 req.tx_match_filter_len = filter_len_tx;
650 memcpy(req.tx_match_filter, input_tx, filter_len_tx);
651 nan_hex_dump(dut, req.tx_match_filter, filter_len_tx);
652 }
653
654 if (rx_match_filter) {
655 req.rx_match_filter_len = filter_len_rx;
656 memcpy(req.rx_match_filter, input_rx, filter_len_rx);
657 nan_hex_dump(dut, req.rx_match_filter, filter_len_rx);
658 }
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700659
660 if (service_name) {
661 strlcpy((char *) req.service_name, service_name,
662 strlen(service_name) + 1);
663 req.service_name_len = strlen(service_name);
664 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200665
Rakesh Sunki107356c2017-03-30 14:47:55 -0700666 ret = nan_publish_request(0, global_interface_handle, &req);
667 if (ret != WIFI_SUCCESS)
668 send_resp(dut, conn, SIGMA_ERROR, "Unable to publish");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200669
670 return 0;
671}
672
673
674static int nan_further_availability_rx(struct sigma_dut *dut,
675 struct sigma_conn *conn,
676 struct sigma_cmd *cmd)
677{
678 const char *master_pref = get_param(cmd, "MasterPref");
679 const char *rand_fac = get_param(cmd, "RandFactor");
680 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700681 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200682 struct timespec abstime;
683
684 NanEnableRequest req;
685
686 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200687 req.cluster_low = 0;
688 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200689 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200690
691 if (master_pref)
692 req.master_pref = strtoul(master_pref, NULL, 0);
693
694 if (rand_fac) {
695 int rand_fac_val = strtoul(rand_fac, NULL, 0);
696
697 req.config_random_factor_force = 1;
698 req.random_factor_force_val = rand_fac_val;
699 }
700
701 if (hop_count) {
702 int hop_count_val = strtoul(hop_count, NULL, 0);
703
704 req.config_hop_count_force = 1;
705 req.hop_count_force_val = hop_count_val;
706 }
707
Rakesh Sunki107356c2017-03-30 14:47:55 -0700708 ret = nan_enable_request(0, global_interface_handle, &req);
709 if (ret != WIFI_SUCCESS) {
710 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
711 return 0;
712 }
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700713
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200714 abstime.tv_sec = 4;
715 abstime.tv_nsec = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200716 wait(abstime);
Kantesh Mundaragi116be192016-10-19 17:10:52 -0700717
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200718 return 0;
719}
720
721
722static int nan_further_availability_tx(struct sigma_dut *dut,
723 struct sigma_conn *conn,
724 struct sigma_cmd *cmd)
725{
726 const char *master_pref = get_param(cmd, "MasterPref");
727 const char *rand_fac = get_param(cmd, "RandFactor");
728 const char *hop_count = get_param(cmd, "HopCount");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700729 wifi_error ret;
730
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200731 NanEnableRequest req;
732 NanConfigRequest configReq;
733
734 memset(&req, 0, sizeof(NanEnableRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200735 req.cluster_low = 0;
736 req.cluster_high = 0xFFFF;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200737 req.master_pref = 30;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200738
739 if (master_pref)
740 req.master_pref = strtoul(master_pref, NULL, 0);
741
742 if (rand_fac) {
743 int rand_fac_val = strtoul(rand_fac, NULL, 0);
744
745 req.config_random_factor_force = 1;
746 req.random_factor_force_val = rand_fac_val;
747 }
748
749 if (hop_count) {
750 int hop_count_val = strtoul(hop_count, NULL, 0);
751
752 req.config_hop_count_force = 1;
753 req.hop_count_force_val = hop_count_val;
754 }
755
Rakesh Sunki107356c2017-03-30 14:47:55 -0700756 ret = nan_enable_request(0, global_interface_handle, &req);
757 if (ret != WIFI_SUCCESS) {
758 send_resp(dut, conn, SIGMA_ERROR, "Unable to enable nan");
759 return 0;
760 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200761
762 /* Start the config of fam */
763
764 memset(&configReq, 0, sizeof(NanConfigRequest));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200765
766 configReq.config_fam = 1;
767 configReq.fam_val.numchans = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700768 configReq.fam_val.famchan[0].entry_control = 0;
769 configReq.fam_val.famchan[0].class_val = 81;
770 configReq.fam_val.famchan[0].channel = 6;
771 configReq.fam_val.famchan[0].mapid = 0;
772 configReq.fam_val.famchan[0].avail_interval_bitmap = 0x7ffffffe;
773
Rakesh Sunki107356c2017-03-30 14:47:55 -0700774 ret = nan_config_request(0, global_interface_handle, &configReq);
775 if (ret != WIFI_SUCCESS)
776 send_resp(dut, conn, SIGMA_ERROR, "Nan config request failed");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200777
778 return 0;
779}
780
781
782int sigma_nan_transmit_followup(struct sigma_dut *dut,
783 struct sigma_conn *conn,
784 struct sigma_cmd *cmd)
785{
786 const char *mac = get_param(cmd, "mac");
787 const char *requestor_id = get_param(cmd, "RemoteInstanceId");
788 const char *local_id = get_param(cmd, "LocalInstanceId");
789 const char *service_name = get_param(cmd, "servicename");
Rakesh Sunki107356c2017-03-30 14:47:55 -0700790 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200791 NanTransmitFollowupRequest req;
792
793 memset(&req, 0, sizeof(NanTransmitFollowupRequest));
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700794 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200795 req.addr[0] = 0xFF;
796 req.addr[1] = 0xFF;
797 req.addr[2] = 0xFF;
798 req.addr[3] = 0xFF;
799 req.addr[4] = 0xFF;
800 req.addr[5] = 0xFF;
801 req.priority = NAN_TX_PRIORITY_NORMAL;
802 req.dw_or_faw = 0;
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -0700803
804 if (service_name)
805 req.service_specific_info_len = strlen(service_name);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200806
807 if (requestor_id) {
808 /* int requestor_id_val = atoi(requestor_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700809 req.requestor_instance_id = global_match_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200810 }
811 if (local_id) {
812 /* int local_id_val = atoi(local_id); */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700813 req.publish_subscribe_id = global_header_handle;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200814 }
815
816 if (mac == NULL) {
817 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid MAC Address");
818 return -1;
819 }
820 nan_parse_mac_address(dut, mac, req.addr);
821
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200822 if (requestor_id)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700823 req.requestor_instance_id = strtoul(requestor_id, NULL, 0);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200824
Rakesh Sunki107356c2017-03-30 14:47:55 -0700825 ret = nan_transmit_followup_request(0, global_interface_handle, &req);
826 if (ret != WIFI_SUCCESS) {
827 send_resp(dut, conn, SIGMA_ERROR,
828 "Unable to complete nan transmit followup");
829 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700830
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200831 return 0;
832}
833
Rakesh Sunki107356c2017-03-30 14:47:55 -0700834
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200835/* NotifyResponse invoked to notify the status of the Request */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700836void nan_notify_response(transaction_id id, NanResponseMsg *rsp_data)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200837{
838 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700839 "%s: status %d value %d response_type %d",
840 __func__,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200841 rsp_data->status, rsp_data->value,
842 rsp_data->response_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200843 if (rsp_data->response_type == NAN_RESPONSE_STATS) {
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700844 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: stats_type %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200845 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700846 rsp_data->body.stats_response.stats_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200847 }
848#if 0
849 if (rsp_data->response_type == NAN_RESPONSE_CONFIG &&
850 rsp_data->status == 0)
851 pthread_cond_signal(&gCondition);
852#endif
853}
854
855
856/* Events Callback */
857void nan_event_publish_replied(NanPublishRepliedInd *event)
858{
859 sigma_dut_print(global_dut, DUT_MSG_INFO,
860 "%s: handle %d " MAC_ADDR_STR " rssi:%d",
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700861 __func__, event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200862 MAC_ADDR_ARRAY(event->addr), event->rssi_value);
863 event_anyresponse = 1;
864 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700865 "EventName,Replied,RemoteInstanceID %d,mac," MAC_ADDR_STR,
866 (event->requestor_instance_id >> 24),
867 MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200868}
869
870
871/* Events Callback */
872void nan_event_publish_terminated(NanPublishTerminatedInd *event)
873{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700874 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: publish_id %d reason %d",
875 __func__, event->publish_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200876}
877
878
879/* Events Callback */
880void nan_event_match(NanMatchInd *event)
881{
882 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700883 "%s: Pub/Sub Id %d remote_requestor_id %08x "
884 MAC_ADDR_STR
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200885 " rssi:%d",
886 __func__,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700887 event->publish_subscribe_id,
888 event->requestor_instance_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200889 MAC_ADDR_ARRAY(event->addr),
890 event->rssi_value);
891 event_anyresponse = 1;
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700892 global_header_handle = event->publish_subscribe_id;
893 global_match_handle = event->requestor_instance_id;
894
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200895 /* memset(event_resp_buf, 0, sizeof(event_resp_buf)); */
896 /* global_pub_sub_handle = event->header.handle; */
897 /* Print the SSI */
898 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing SSI:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700899 nan_hex_dump(global_dut, event->service_specific_info,
900 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200901 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
902 "EventName,DiscoveryResult,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700903 MAC_ADDR_STR " ", (event->requestor_instance_id >> 24),
904 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200905
906 /* Print the match filter */
907 sigma_dut_print(global_dut, DUT_MSG_INFO, "Printing sdf match filter:");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700908 nan_hex_dump(global_dut, event->sdf_match_filter,
909 event->sdf_match_filter_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200910
911 /* Print the conn_capability */
912 sigma_dut_print(global_dut, DUT_MSG_INFO,
913 "Printing PostConnectivity Capability");
914 if (event->is_conn_capability_valid) {
915 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfd supported:%s",
916 event->conn_capability.is_wfd_supported ?
917 "yes" : "no");
918 sigma_dut_print(global_dut, DUT_MSG_INFO, "Wfds supported:%s",
919 (event->conn_capability.is_wfds_supported ?
920 "yes" : "no"));
921 sigma_dut_print(global_dut, DUT_MSG_INFO, "TDLS supported:%s",
922 (event->conn_capability.is_tdls_supported ?
923 "yes" : "no"));
924 sigma_dut_print(global_dut, DUT_MSG_INFO, "IBSS supported:%s",
925 (event->conn_capability.is_ibss_supported ?
926 "yes" : "no"));
927 sigma_dut_print(global_dut, DUT_MSG_INFO, "Mesh supported:%s",
928 (event->conn_capability.is_mesh_supported ?
929 "yes" : "no"));
930 sigma_dut_print(global_dut, DUT_MSG_INFO, "Infra Field:%d",
931 event->conn_capability.wlan_infra_field);
932 } else {
933 sigma_dut_print(global_dut, DUT_MSG_INFO,
934 "PostConnectivity Capability not present");
935 }
936
937 /* Print the discovery_attr */
938 sigma_dut_print(global_dut, DUT_MSG_INFO,
939 "Printing PostDiscovery Attribute");
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700940 if (event->num_rx_discovery_attr) {
941 int idx;
942
943 for (idx = 0; idx < event->num_rx_discovery_attr; idx++) {
944 sigma_dut_print(global_dut, DUT_MSG_INFO,
945 "PostDiscovery Attribute - %d", idx);
946 sigma_dut_print(global_dut, DUT_MSG_INFO,
947 "Conn Type:%d Device Role:%d"
948 MAC_ADDR_STR,
949 event->discovery_attr[idx].type,
950 event->discovery_attr[idx].role,
951 MAC_ADDR_ARRAY(event->discovery_attr[idx].addr));
952 sigma_dut_print(global_dut, DUT_MSG_INFO,
953 "Duration:%d MapId:%d "
954 "avail_interval_bitmap:%04x",
955 event->discovery_attr[idx].duration,
956 event->discovery_attr[idx].mapid,
957 event->discovery_attr[idx].avail_interval_bitmap);
958 sigma_dut_print(global_dut, DUT_MSG_INFO,
959 "Printing Mesh Id:");
960 nan_hex_dump(global_dut,
961 event->discovery_attr[idx].mesh_id,
962 event->discovery_attr[idx].mesh_id_len);
963 sigma_dut_print(global_dut, DUT_MSG_INFO,
964 "Printing Infrastructure Ssid:");
965 nan_hex_dump(global_dut,
966 event->discovery_attr[idx].infrastructure_ssid_val,
967 event->discovery_attr[idx].infrastructure_ssid_len);
968 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200969 } else {
970 sigma_dut_print(global_dut, DUT_MSG_INFO,
971 "PostDiscovery attribute not present");
972 }
973
974 /* Print the fam */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700975 if (event->num_chans) {
976 nan_print_further_availability_chan(global_dut,
977 event->num_chans,
978 &event->famchan[0]);
979 } else {
980 sigma_dut_print(global_dut, DUT_MSG_INFO,
981 "Further Availability Map not present");
982 }
983 if (event->cluster_attribute_len) {
984 sigma_dut_print(global_dut, DUT_MSG_INFO,
985 "Printing Cluster Attribute:");
986 nan_hex_dump(global_dut, event->cluster_attribute,
987 event->cluster_attribute_len);
988 } else {
989 sigma_dut_print(global_dut, DUT_MSG_INFO,
990 "Cluster Attribute not present");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200991 }
992}
993
994
995/* Events Callback */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700996void nan_event_match_expired(NanMatchExpiredInd *event)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200997{
998 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -0700999 "%s: publish_subscribe_id %d match_handle %08x",
1000 __func__, event->publish_subscribe_id,
1001 event->requestor_instance_id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001002}
1003
1004
1005/* Events Callback */
1006void nan_event_subscribe_terminated(NanSubscribeTerminatedInd *event)
1007{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001008 sigma_dut_print(global_dut, DUT_MSG_INFO,
1009 "%s: Subscribe Id %d reason %d",
1010 __func__, event->subscribe_id, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001011}
1012
1013
1014/* Events Callback */
1015void nan_event_followup(NanFollowupInd *event)
1016{
1017 sigma_dut_print(global_dut, DUT_MSG_INFO,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001018 "%s: Publish/Subscribe Id %d match_handle 0x%08x dw_or_faw %d "
1019 MAC_ADDR_STR, __func__, event->publish_subscribe_id,
1020 event->requestor_instance_id, event->dw_or_faw,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001021 MAC_ADDR_ARRAY(event->addr));
1022
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001023 global_match_handle = event->publish_subscribe_id;
1024 global_header_handle = event->requestor_instance_id;
1025 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Printing SSI", __func__);
1026 nan_hex_dump(global_dut, event->service_specific_info,
1027 event->service_specific_info_len);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001028 event_anyresponse = 1;
1029 snprintf(global_event_resp_buf, sizeof(global_event_resp_buf),
1030 "EventName,FollowUp,RemoteInstanceID,%d,LocalInstanceID,%d,mac,"
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001031 MAC_ADDR_STR " ", event->requestor_instance_id >> 24,
1032 event->publish_subscribe_id, MAC_ADDR_ARRAY(event->addr));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001033}
1034
1035
1036/* Events Callback */
1037void nan_event_disceng_event(NanDiscEngEventInd *event)
1038{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001039 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: event_type %d",
1040 __func__, event->event_type);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001041
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001042 if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001043 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: Joined cluster "
1044 MAC_ADDR_STR,
1045 __func__,
1046 MAC_ADDR_ARRAY(event->data.cluster.addr));
Kantesh Mundaragi116be192016-10-19 17:10:52 -07001047 /* To ensure sta_get_events to get the events
1048 * only after joining the NAN cluster. */
1049 pthread_cond_signal(&gCondition);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001050 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001051 if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001052 sigma_dut_print(global_dut, DUT_MSG_INFO,
1053 "%s: Started cluster " MAC_ADDR_STR,
1054 __func__,
1055 MAC_ADDR_ARRAY(event->data.cluster.addr));
1056 }
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001057 if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) {
1058 sigma_dut_print(global_dut, DUT_MSG_INFO,
1059 "%s: Discovery Mac Address "
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001060 MAC_ADDR_STR,
1061 __func__,
1062 MAC_ADDR_ARRAY(event->data.mac_addr.addr));
1063 memcpy(global_nan_mac_addr, event->data.mac_addr.addr,
1064 sizeof(global_nan_mac_addr));
1065 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001066}
1067
1068
1069/* Events Callback */
1070void nan_event_disabled(NanDisabledInd *event)
1071{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001072 sigma_dut_print(global_dut, DUT_MSG_INFO, "%s: reason %d",
1073 __func__, event->reason);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001074 /* pthread_cond_signal(&gCondition); */
1075}
1076
1077
Rakesh Sunki4c086672017-03-30 14:47:55 -07001078/* Events callback */
1079static void ndp_event_data_indication(NanDataPathRequestInd *event)
1080{
1081 sigma_dut_print(global_dut, DUT_MSG_INFO,
1082 "%s: Service Instance Id: %d Peer Discovery MAC ADDR "
1083 MAC_ADDR_STR
1084 " NDP Instance Id: %d App Info len %d App Info %s",
1085 __func__,
1086 event->service_instance_id,
1087 MAC_ADDR_ARRAY(event->peer_disc_mac_addr),
1088 event->ndp_instance_id,
1089 event->app_info.ndp_app_info_len,
1090 event->app_info.ndp_app_info);
1091
1092 global_ndp_instance_id = event->ndp_instance_id;
1093}
1094
1095
1096/* Events callback */
1097static void ndp_event_data_confirm(NanDataPathConfirmInd *event)
1098{
1099 sigma_dut_print(global_dut, DUT_MSG_INFO,
1100 "Received NDP Confirm Indication");
1101
1102 global_ndp_instance_id = event->ndp_instance_id;
1103 if (system("ifconfig nan0 up") != 0) {
1104 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1105 "Failed to set nan interface up");
1106 return;
1107 }
1108 if (system("ip -6 route add fe80::/64 dev nan0 table local") != 0) {
1109 sigma_dut_print(global_dut, DUT_MSG_ERROR,
1110 "Failed to run:ip -6 route replace fe80::/64 dev nan0 table local");
1111 return;
1112 }
1113}
1114
1115
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001116void * my_thread_function(void *ptr)
1117{
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001118 wifi_event_loop(global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001119 pthread_exit(0);
1120 return (void *) NULL;
1121}
1122
1123
1124static NanCallbackHandler callbackHandler = {
1125 .NotifyResponse = nan_notify_response,
1126 .EventPublishReplied = nan_event_publish_replied,
1127 .EventPublishTerminated = nan_event_publish_terminated,
1128 .EventMatch = nan_event_match,
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001129 .EventMatchExpired = nan_event_match_expired,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001130 .EventSubscribeTerminated = nan_event_subscribe_terminated,
1131 .EventFollowup = nan_event_followup,
1132 .EventDiscEngEvent = nan_event_disceng_event,
1133 .EventDisabled = nan_event_disabled,
Rakesh Sunki4c086672017-03-30 14:47:55 -07001134 .EventDataRequest = ndp_event_data_indication,
1135 .EventDataConfirm = ndp_event_data_confirm,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001136};
1137
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001138
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001139void nan_init(struct sigma_dut *dut)
1140{
1141 pthread_t thread1; /* thread variables */
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001142 wifi_error err = wifi_initialize(&global_wifi_handle);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001143
1144 if (err) {
1145 printf("wifi hal initialize failed\n");
1146 return;
1147 }
1148
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001149 global_interface_handle = wifi_get_iface_handle(global_wifi_handle,
1150 (char *) "wlan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001151 /* create threads 1 */
1152 pthread_create(&thread1, NULL, &my_thread_function, NULL);
1153
1154 pthread_mutex_init(&gMutex, NULL);
1155 pthread_cond_init(&gCondition, NULL);
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001156 if (global_interface_handle)
1157 nan_register_handler(global_interface_handle, callbackHandler);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001158}
1159
1160
1161void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1162 struct sigma_cmd *cmd)
1163{
1164 sigma_dut_print(dut, DUT_MSG_INFO, "NAN sta_reset_default");
1165
1166 if (nan_state == 0) {
1167 nan_init(dut);
1168 nan_state = 1;
1169 }
1170 is_fam = 0;
1171 event_anyresponse = 0;
1172 global_dut = dut;
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001173 dut->sta_channel = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001174 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001175
1176 nan_data_interface_delete(0, global_interface_handle, (char *) "nan0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001177 sigma_nan_disable(dut, conn, cmd);
1178}
1179
1180
1181int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1182 struct sigma_cmd *cmd)
1183{
1184 const char *program = get_param(cmd, "Prog");
1185 const char *nan_op = get_param(cmd, "NANOp");
1186 const char *method_type = get_param(cmd, "MethodType");
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001187 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001188 char resp_buf[100];
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001189 wifi_error ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001190
1191 if (program == NULL)
1192 return -1;
1193
1194 if (strcasecmp(program, "NAN") != 0) {
1195 send_resp(dut, conn, SIGMA_ERROR,
1196 "ErrorCode,Unsupported program");
1197 return 0;
1198 }
1199
1200 if (nan_op) {
1201 /*
1202 * NANOp has been specified.
1203 * We will build a nan_enable or nan_disable command.
1204 */
1205 if (strcasecmp(nan_op, "On") == 0) {
1206 if (sigma_nan_enable(dut, conn, cmd) == 0) {
Rakesh Sunki7a40a202017-03-30 14:47:55 -07001207 ret = nan_data_interface_create(
1208 0, global_interface_handle,
1209 (char *) "nan0");
1210 if (ret != WIFI_SUCCESS) {
1211 sigma_dut_print(
1212 global_dut, DUT_MSG_ERROR,
1213 "Unable to create NAN data interface");
1214 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001215 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1216 MAC_ADDR_STR,
1217 MAC_ADDR_ARRAY(global_nan_mac_addr));
1218 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1219 } else {
1220 send_resp(dut, conn, SIGMA_ERROR,
1221 "NAN_ENABLE_FAILED");
1222 return -1;
1223 }
Rakesh Sunkid7344c02017-03-30 14:47:55 -07001224
1225 if (band && strcasecmp(band, "24g") == 0) {
1226 sigma_dut_print(dut, DUT_MSG_INFO,
1227 "%s: Setting band to 2G Only",
1228 __func__);
1229 sigma_ndp_configure_band(
1230 dut, conn, cmd,
1231 NAN_DATA_PATH_SUPPORTED_BAND_2G);
1232 } else if (band && dut->sta_channel > 12) {
1233 sigma_ndp_configure_band(
1234 dut, conn, cmd,
1235 NAN_DATA_PATH_SUPPORT_DUAL_BAND);
1236 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001237 } else if (strcasecmp(nan_op, "Off") == 0) {
1238 sigma_nan_disable(dut, conn, cmd);
1239 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1240 }
1241 }
1242 if (nan_state && nan_op == NULL) {
1243 if (method_type) {
1244 if (strcasecmp(method_type, "Publish") == 0) {
1245 sigma_nan_publish_request(dut, conn, cmd);
1246 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1247 }
1248 if (strcasecmp(method_type, "Subscribe") == 0) {
1249 sigma_nan_subscribe_request(dut, conn, cmd);
1250 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1251 }
1252 if (strcasecmp(method_type, "Followup") == 0) {
1253 sigma_nan_transmit_followup(dut, conn, cmd);
1254 send_resp(dut, conn, SIGMA_COMPLETE, "NULL");
1255 }
1256 } else {
1257 sigma_nan_config_enable(dut, conn, cmd);
1258 snprintf(resp_buf, sizeof(resp_buf), "mac,"
1259 MAC_ADDR_STR,
1260 MAC_ADDR_ARRAY(global_nan_mac_addr));
1261 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1262 }
1263 }
1264
1265 return 0;
1266}
1267
1268
1269int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1270 struct sigma_cmd *cmd)
1271{
1272
1273 const char *program = get_param(cmd, "Program");
1274 const char *parameter = get_param(cmd, "Parameter");
1275 char resp_buf[100];
1276 NanStaParameter rsp;
1277
1278 if (program == NULL) {
1279 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Program Name");
1280 return -1;
1281 }
1282 if (strcasecmp(program, "NAN") != 0) {
1283 send_resp(dut, conn, SIGMA_ERROR,
1284 "ErrorCode,Unsupported program");
1285 return 0;
1286 }
1287
1288 if (parameter == NULL) {
1289 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid Parameter");
1290 return -1;
1291 }
1292 memset(&rsp, 0, sizeof(NanStaParameter));
1293
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07001294 nan_get_sta_parameter(0, global_interface_handle, &rsp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001295 sigma_dut_print(dut, DUT_MSG_INFO,
1296 "%s: NanStaparameter Master_pref:%02x, Random_factor:%02x, hop_count:%02x beacon_transmit_time:%d",
1297 __func__, rsp.master_pref, rsp.random_factor,
1298 rsp.hop_count, rsp.beacon_transmit_time);
1299
1300 if (strcasecmp(parameter, "MasterPref") == 0) {
1301 snprintf(resp_buf, sizeof(resp_buf), "MasterPref,0x%x",
1302 rsp.master_pref);
1303 } else if (strcasecmp(parameter, "MasterRank") == 0) {
1304 snprintf(resp_buf, sizeof(resp_buf), "MasterRank,0x%lx",
1305 rsp.master_rank);
1306 } else if (strcasecmp(parameter, "RandFactor") == 0) {
1307 snprintf(resp_buf, sizeof(resp_buf), "RandFactor,0x%x",
1308 rsp.random_factor);
1309 } else if (strcasecmp(parameter, "HopCount") == 0) {
1310 snprintf(resp_buf, sizeof(resp_buf), "HopCount,0x%x",
1311 rsp.hop_count);
1312 } else if (strcasecmp(parameter, "BeaconTransTime") == 0) {
1313 snprintf(resp_buf, sizeof(resp_buf), "BeaconTransTime 0x%x",
1314 rsp.beacon_transmit_time);
1315 } else if (strcasecmp(parameter, "NANStatus") == 0) {
1316 if (nan_state == 1)
1317 snprintf(resp_buf, sizeof(resp_buf), "On");
1318 else
1319 snprintf(resp_buf, sizeof(resp_buf), "Off");
1320 } else {
1321 send_resp(dut, conn, SIGMA_ERROR, "Invalid Parameter");
1322 return 0;
1323 }
1324
1325 send_resp(dut, conn, SIGMA_COMPLETE, resp_buf);
1326 return 0;
1327}
1328
1329
1330int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1331 struct sigma_cmd *cmd)
1332{
1333 const char *action = get_param(cmd, "Action");
1334
Kantesh Mundaragi132c6d22016-10-28 16:17:50 -07001335 if (!action)
1336 return 0;
1337
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001338 /* Check action for start, stop and get events. */
1339 if (strcasecmp(action, "Start") == 0) {
1340 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1341 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1342 } else if (strcasecmp(action, "Stop") == 0) {
1343 event_anyresponse = 0;
1344 memset(global_event_resp_buf, 0, sizeof(global_event_resp_buf));
1345 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
1346 } else if (strcasecmp(action, "Get") == 0) {
1347 if (event_anyresponse == 1) {
1348 send_resp(dut, conn, SIGMA_COMPLETE,
1349 global_event_resp_buf);
1350 } else {
1351 send_resp(dut, conn, SIGMA_COMPLETE, "EventList,NONE");
1352 }
1353 }
1354 return 0;
1355}
Rakesh Sunki4b75f962017-03-30 14:47:55 -07001356
1357#else /* #if NAN_CERT_VERSION */
1358
1359int nan_cmd_sta_preset_testparameters(struct sigma_dut *dut,
1360 struct sigma_conn *conn,
1361 struct sigma_cmd *cmd)
1362{
1363 return 1;
1364}
1365
1366
1367int nan_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
1368 struct sigma_cmd *cmd)
1369{
1370 return 0;
1371
1372}
1373
1374
1375void nan_cmd_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
1376 struct sigma_cmd *cmd)
1377{
1378 return;
1379}
1380
1381
1382int nan_cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
1383 struct sigma_cmd *cmd)
1384{
1385 return 0;
1386}
1387
1388
1389int nan_cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1390 struct sigma_cmd *cmd)
1391{
1392 return 0;
1393}
1394
1395#endif /* #if NAN_CERT_VERSION */