• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Portions copyright (C) 2022 Broadcom Limited
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <stdint.h>
20 #include <stdlib.h>
21 #ifndef ANDROID
22 #include <stddef.h>
23 #endif
24 
25 #define LOG_TAG  "WifiHAL"
26 
27 #define NAN_MAX_SIDS_IN_BEACONS 127
28 #include <utils/Log.h>
29 #ifndef ANDROID
30 #include <cutils/memory.h>
31 #endif
32 #include <inttypes.h>
33 #include <sys/socket.h>
34 #ifdef ANDROID
35 #include <linux/if.h>
36 #endif
37 #include <ctype.h>
38 #include <stdarg.h>
39 #include <semaphore.h>
40 #include <fcntl.h>
41 #include <string.h>
42 #include <errno.h>
43 #include "netinet/in.h"
44 #include "arpa/inet.h"
45 #ifndef ANDROID
46 #include <sys/ioctl.h>
47 #include <net/if.h>
48 #endif
49 #include <sys/ioctl.h>
50 #include <linux/netlink.h>
51 #include "wifi_hal.h"
52 #include "wifi_nan.h"
53 #include "wifi_twt.h"
54 #include "hal_tool.h"
55 #include "interface_tool.h"
56 
57 #include "common.h"
58 
59 #define EVENT_COUNT 256
60 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
61 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
62 
63 #define NMR2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7]
64 #define NMRSTR "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
65 #define NAN_DISC_MAC_RAND_INTVL 30
66 pthread_mutex_t printMutex;
67 
68 static wifi_hal_fn hal_fn;
69 static char* frequency_to_channel(int center_freq);
70 
71 /* API to spawn a hal instance from halutil CLI to capture events */
72 wifi_error  nan_event_check_request(transaction_id id,
73         wifi_interface_handle handle);
74 
75 /* API to spawn a hal instance from halutil CLI to capture events */
76 wifi_error twt_event_check_request(transaction_id id,
77         wifi_interface_handle handle);
78 static int set_interface_params(char *p_info, char *val_p, int len);
79 static void printApfUsage();
80 static void printTxPowerUsage();
81 
printMsg(const char * fmt,...)82 void printMsg(const char *fmt, ...)
83 {
84     pthread_mutex_lock(&printMutex);
85     va_list l;
86     va_start(l, fmt);
87 
88     vprintf(fmt, l);
89     va_end(l);
90     pthread_mutex_unlock(&printMutex);
91 }
92 
93 template<typename T, unsigned N>
countof(T (& rgt)[N])94 unsigned countof(T (&rgt)[N]) {
95     return N;
96 }
97 
98 #define NBBY    8  /* number of bits/byte */
99 
100 /* Bit map related macros. */
101 #define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
102 #define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
103 #define isset(a,i)  ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
104 #define isclr(a,i)  (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
105 #define CEIL(x, y)  (((x) + ((y) - 1)) / (y))
106 
107 /* TLV defines */
108 #define TLV_TAG_OFF     0   /* tag offset */
109 #define TLV_LEN_OFF     1   /* length offset */
110 #define TLV_HDR_LEN     2   /* header length */
111 #define TLV_BODY_OFF    2   /* body offset */
112 #define TLV_BODY_LEN_MAX 255  /* max body length */
113 
114 
115 /* Information Element IDs */
116 #define WIFI_EID_SSID 0
117 #define WIFI_EID_SUPP_RATES 1
118 #define WIFI_EID_FH_PARAMS 2
119 #define WIFI_EID_DS_PARAMS 3
120 #define WIFI_EID_CF_PARAMS 4
121 #define WIFI_EID_TIM 5
122 #define WIFI_EID_IBSS_PARAMS 6
123 #define WIFI_EID_COUNTRY 7
124 #define WIFI_EID_BSS_LOAD 11
125 #define WIFI_EID_CHALLENGE 16
126 /* EIDs defined by IEEE 802.11h - START */
127 #define WIFI_EID_PWR_CONSTRAINT 32
128 #define WIFI_EID_PWR_CAPABILITY 33
129 #define WIFI_EID_TPC_REQUEST 34
130 #define WIFI_EID_TPC_REPORT 35
131 #define WIFI_EID_SUPPORTED_CHANNELS 36
132 #define WIFI_EID_CHANNEL_SWITCH 37
133 #define WIFI_EID_MEASURE_REQUEST 38
134 #define WIFI_EID_MEASURE_REPORT 39
135 #define WIFI_EID_QUITE 40
136 #define WIFI_EID_IBSS_DFS 41
137 /* EIDs defined by IEEE 802.11h - END */
138 #define WIFI_EID_ERP_INFO 42
139 #define WIFI_EID_HT_CAP 45
140 #define WIFI_EID_QOS 46
141 #define WIFI_EID_RSN 48
142 #define WIFI_EID_EXT_SUPP_RATES 50
143 #define WIFI_EID_NEIGHBOR_REPORT 52
144 #define WIFI_EID_MOBILITY_DOMAIN 54
145 #define WIFI_EID_FAST_BSS_TRANSITION 55
146 #define WIFI_EID_TIMEOUT_INTERVAL 56
147 #define WIFI_EID_RIC_DATA 57
148 #define WIFI_EID_SUPPORTED_OPERATING_CLASSES 59
149 #define WIFI_EID_HT_OPERATION 61
150 #define WIFI_EID_SECONDARY_CHANNEL_OFFSET 62
151 #define WIFI_EID_WAPI 68
152 #define WIFI_EID_TIME_ADVERTISEMENT 69
153 #define WIFI_EID_20_40_BSS_COEXISTENCE 72
154 #define WIFI_EID_20_40_BSS_INTOLERANT 73
155 #define WIFI_EID_OVERLAPPING_BSS_SCAN_PARAMS 74
156 #define WIFI_EID_MMIE 76
157 #define WIFI_EID_SSID_LIST 84
158 #define WIFI_EID_BSS_MAX_IDLE_PERIOD 90
159 #define WIFI_EID_TFS_REQ 91
160 #define WIFI_EID_TFS_RESP 92
161 #define WIFI_EID_WNMSLEEP 93
162 #define WIFI_EID_TIME_ZONE 98
163 #define WIFI_EID_LINK_ID 101
164 #define WIFI_EID_INTERWORKING 107
165 #define WIFI_EID_ADV_PROTO 108
166 #define WIFI_EID_QOS_MAP_SET 110
167 #define WIFI_EID_ROAMING_CONSORTIUM 111
168 #define WIFI_EID_EXT_CAPAB 127
169 #define WIFI_EID_CCKM 156
170 #define WIFI_EID_VHT_CAP 191
171 #define WIFI_EID_VHT_OPERATION 192
172 #define WIFI_EID_VHT_EXTENDED_BSS_LOAD 193
173 #define WIFI_EID_VHT_WIDE_BW_CHSWITCH  194
174 #define WIFI_EID_VHT_TRANSMIT_POWER_ENVELOPE 195
175 #define WIFI_EID_VHT_CHANNEL_SWITCH_WRAPPER 196
176 #define WIFI_EID_VHT_AID 197
177 #define WIFI_EID_VHT_QUIET_CHANNEL 198
178 #define WIFI_EID_VHT_OPERATING_MODE_NOTIFICATION 199
179 #define WIFI_EID_VENDOR_SPECIFIC 221
180 
181 
182 /* Extended capabilities IE bitfields */
183 /* 20/40 BSS Coexistence Management support bit position */
184 #define DOT11_EXT_CAP_OBSS_COEX_MGMT        0
185 /* Extended Channel Switching support bit position */
186 #define DOT11_EXT_CAP_EXT_CHAN_SWITCHING    2
187 /* scheduled PSMP support bit position */
188 #define DOT11_EXT_CAP_SPSMP         6
189 /*  Flexible Multicast Service */
190 #define DOT11_EXT_CAP_FMS           11
191 /* proxy ARP service support bit position */
192 #define DOT11_EXT_CAP_PROXY_ARP     12
193 /* Civic Location */
194 #define DOT11_EXT_CAP_CIVIC_LOC     14
195 /* Geospatial Location */
196 #define DOT11_EXT_CAP_LCI           15
197 /* Traffic Filter Service */
198 #define DOT11_EXT_CAP_TFS           16
199 /* WNM-Sleep Mode */
200 #define DOT11_EXT_CAP_WNM_SLEEP     17
201 /* TIM Broadcast service */
202 #define DOT11_EXT_CAP_TIMBC         18
203 /* BSS Transition Management support bit position */
204 #define DOT11_EXT_CAP_BSSTRANS_MGMT 19
205 /* Direct Multicast Service */
206 #define DOT11_EXT_CAP_DMS           26
207 /* Interworking support bit position */
208 #define DOT11_EXT_CAP_IW            31
209 /* QoS map support bit position */
210 #define DOT11_EXT_CAP_QOS_MAP       32
211 /* service Interval granularity bit position and mask */
212 #define DOT11_EXT_CAP_SI            41
213 #define DOT11_EXT_CAP_SI_MASK       0x0E
214 /* WNM notification */
215 #define DOT11_EXT_CAP_WNM_NOTIF     46
216 /* Operating mode notification - VHT (11ac D3.0 - 8.4.2.29) */
217 #define DOT11_EXT_CAP_OPER_MODE_NOTIF  62
218 /* Fine timing measurement - D3.0 */
219 #define DOT11_EXT_CAP_FTM_RESPONDER    70
220 #define DOT11_EXT_CAP_FTM_INITIATOR    71 /* tentative 11mcd3.0 */
221 
222 #define DOT11_EXT_CH_MASK   0x03 /* extension channel mask */
223 #define DOT11_EXT_CH_UPPER  0x01 /* ext. ch. on upper sb */
224 #define DOT11_EXT_CH_LOWER  0x03 /* ext. ch. on lower sb */
225 #define DOT11_EXT_CH_NONE   0x00 /* no extension ch.  */
226 
227 enum vht_op_chan_width {
228     VHT_OP_CHAN_WIDTH_20_40 = 0,
229     VHT_OP_CHAN_WIDTH_80    = 1,
230     VHT_OP_CHAN_WIDTH_160   = 2,
231     VHT_OP_CHAN_WIDTH_80_80 = 3
232 };
233 /**
234  * Channel Factor for the starting frequence of 2.4 GHz channels.
235  * The value corresponds to 2407 MHz.
236  */
237 #define CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */
238 
239 /**
240  * Channel Factor for the starting frequence of 5 GHz channels.
241  * The value corresponds to 5000 MHz.
242  */
243 #define CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */
244 
245 
246 /* ************* HT definitions. ************* */
247 #define MCSSET_LEN 16       /* 16-bits per 8-bit set to give 128-bits bitmap of MCS Index */
248 #define MAX_MCS_NUM (128)   /* max mcs number = 128 */
249 
250 struct ht_op_ie {
251     u8  ctl_ch;         /* control channel number */
252     u8  chan_info;      /* ext ch,rec. ch. width, RIFS support */
253     u16 opmode;         /* operation mode */
254     u16 misc_bits;      /* misc bits */
255     u8  basic_mcs[MCSSET_LEN];  /* required MCS set */
256 } __attribute__ ((packed));
257 struct vht_op_ie {
258     u8  chan_width;
259     u8  chan1;
260     u8  chan2;
261     u16 supp_mcs; /* same def as above in vht cap */
262 } __attribute__ ((packed));
263 
264 #define EVENT_BUF_SIZE 2048
265 #define MAX_EVENT_MSG_LEN 256
266 #define MAX_CH_BUF_SIZE  256
267 #define MAX_FEATURE_SET  8
268 #define MAX_RADIO_COMBO	5
269 #define MAX_CORE 2
270 #define HOTLIST_LOST_WINDOW  5
271 
272 static wifi_handle halHandle;
273 static wifi_interface_handle *ifaceHandles;
274 static wifi_interface_handle wlan0Handle;
275 static wifi_interface_handle p2p0Handle;
276 static int numIfaceHandles;
277 static int cmdId = 0;
278 static int max_event_wait = 5;
279 static int stest_max_ap = 10;
280 static int stest_base_period = 5000;
281 static int stest_threshold_percent = 80;
282 static int stest_threshold_num_scans = 10;
283 static int swctest_rssi_sample_size =  3;
284 static int swctest_rssi_lost_ap =  3;
285 static int swctest_rssi_min_breaching =  2;
286 static int swctest_rssi_ch_threshold =  1;
287 static int htest_low_threshold =  90;
288 static int htest_high_threshold =  10;
289 static int rssi_monitor = 0;
290 static signed char min_rssi = 0;
291 static signed char max_rssi = 0;
292 static size_t n_requested_pkt_fate = 0;
293 
294 #define FILE_NAME_LEN 128
295 #define FILE_MAX_SIZE (1 * 1024 * 1024)
296 #define MAX_RING_NAME_SIZE 32
297 
298 #define NUM_ALERT_DUMPS 10
299 #define ETHER_ADDR_LEN 6
300 #define MAX_NAN_MSG_BUF_SIZE 256
301 
302 #define NAN_MAX_CLUST_VALUE_RANGE 0xFFFF
303 #define MAX_CH_AVOID 128
304 
305 /*
306  * Host can send Post Connectivity Capability attributes
307  * to be included in Service Discovery frames transmitted.
308  */
309 enum post_connectivity_capability {
310     FEATURE_NOT_SUPPORTED   = 0,
311     FEATURE_SUPPORTED       = 1
312 };
313 
314 
315 /////////////////////////////////////////////////////////////////
316 // Logger related.
317 
318 #define DEFAULT_MEMDUMP_FILE "/data/memdump.bin"
319 #define ALERT_MEMDUMP_PREFIX "/data/alertdump"
320 #define RINGDATA_PREFIX "/data/ring-"
321 #define DEFAULT_TX_PKT_FATE_FILE "/data/txpktfate.txt"
322 #define DEFAULT_RX_PKT_FATE_FILE "/data/rxpktfate.txt"
323 
324 static char mem_dump_file[FILE_NAME_LEN] = DEFAULT_MEMDUMP_FILE;
325 static char tx_pkt_fate_file[FILE_NAME_LEN] = DEFAULT_TX_PKT_FATE_FILE;
326 static char rx_pkt_fate_file[FILE_NAME_LEN] = DEFAULT_RX_PKT_FATE_FILE;
327 
328 struct LoggerParams {
329     u32 verbose_level;
330     u32 flags;
331     u32 max_interval_sec;
332     u32 min_data_size;
333     wifi_ring_buffer_id ring_id;
334     char ring_name[MAX_RING_NAME_SIZE];
335 };
336 struct LoggerParams default_logger_param = {0, 0 , 0 , 0, 0, {0}};
337 
338 char default_ring_name[MAX_RING_NAME_SIZE] = "fw_event";
339 
340 typedef enum {
341     LOG_INVALID = -1,
342     LOG_START,
343     LOG_GET_MEMDUMP,
344     LOG_GET_FW_VER,
345     LOG_GET_DRV_VER,
346     LOG_GET_RING_STATUS,
347     LOG_GET_RINGDATA,
348     LOG_GET_FEATURE,
349     LOG_GET_RING_DATA,
350     LOG_MONITOR_PKTFATE,
351     LOG_GET_TXPKTFATE,
352     LOG_GET_RXPKTFATE,
353     LOG_SET_LOG_HANDLER,
354     LOG_SET_ALERT_HANDLER,
355 } LoggerCmd;
356 
357 LoggerCmd log_cmd = LOG_INVALID;
358 wifi_ring_buffer_id ringId = -1;
359 
360 #define C2S(x)  case x: return #x;
361 
RBentryTypeToString(int cmd)362 static const char *RBentryTypeToString(int cmd) {
363     switch (cmd) {
364         C2S(ENTRY_TYPE_CONNECT_EVENT)
365         C2S(ENTRY_TYPE_PKT)
366         C2S(ENTRY_TYPE_WAKE_LOCK)
367         C2S(ENTRY_TYPE_POWER_EVENT)
368         C2S(ENTRY_TYPE_DATA)
369         default:
370             return "ENTRY_TYPE_UNKNOWN";
371     }
372 }
373 
RBconnectEventToString(int cmd)374 static const char *RBconnectEventToString(int cmd)
375 {
376     switch (cmd) {
377         C2S(WIFI_EVENT_ASSOCIATION_REQUESTED)
378         C2S(WIFI_EVENT_AUTH_COMPLETE)
379         C2S(WIFI_EVENT_ASSOC_COMPLETE)
380         C2S(WIFI_EVENT_FW_AUTH_STARTED)
381         C2S(WIFI_EVENT_FW_ASSOC_STARTED)
382         C2S(WIFI_EVENT_FW_RE_ASSOC_STARTED)
383         C2S(WIFI_EVENT_DRIVER_SCAN_REQUESTED)
384         C2S(WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND)
385         C2S(WIFI_EVENT_DRIVER_SCAN_COMPLETE)
386         C2S(WIFI_EVENT_G_SCAN_STARTED)
387         C2S(WIFI_EVENT_G_SCAN_COMPLETE)
388         C2S(WIFI_EVENT_DISASSOCIATION_REQUESTED)
389         C2S(WIFI_EVENT_RE_ASSOCIATION_REQUESTED)
390         C2S(WIFI_EVENT_ROAM_REQUESTED)
391         C2S(WIFI_EVENT_BEACON_RECEIVED)
392         C2S(WIFI_EVENT_ROAM_SCAN_STARTED)
393         C2S(WIFI_EVENT_ROAM_SCAN_COMPLETE)
394         C2S(WIFI_EVENT_ROAM_SEARCH_STARTED)
395         C2S(WIFI_EVENT_ROAM_SEARCH_STOPPED)
396         C2S(WIFI_EVENT_CHANNEL_SWITCH_ANOUNCEMENT)
397         C2S(WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START)
398         C2S(WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP)
399         C2S(WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED)
400         C2S(WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED)
401         C2S(WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED)
402         C2S(WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE)
403         C2S(WIFI_EVENT_BT_COEX_BT_SCO_START)
404         C2S(WIFI_EVENT_BT_COEX_BT_SCO_STOP)
405         C2S(WIFI_EVENT_BT_COEX_BT_SCAN_START)
406         C2S(WIFI_EVENT_BT_COEX_BT_SCAN_STOP)
407         C2S(WIFI_EVENT_BT_COEX_BT_HID_START)
408         C2S(WIFI_EVENT_BT_COEX_BT_HID_STOP)
409         C2S(WIFI_EVENT_ROAM_AUTH_STARTED)
410         C2S(WIFI_EVENT_ROAM_AUTH_COMPLETE)
411         C2S(WIFI_EVENT_ROAM_ASSOC_STARTED)
412         C2S(WIFI_EVENT_ROAM_ASSOC_COMPLETE)
413         C2S(WIFI_EVENT_DRIVER_PNO_ADD)
414         C2S(WIFI_EVENT_DRIVER_PNO_REMOVE)
415         C2S(WIFI_EVENT_DRIVER_PNO_NETWORK_FOUND)
416         C2S(WIFI_EVENT_DRIVER_PNO_SCAN_REQUESTED)
417         C2S(WIFI_EVENT_DRIVER_PNO_SCAN_RESULT_FOUND)
418         C2S(WIFI_EVENT_DRIVER_PNO_SCAN_COMPLETE)
419         default:
420             return "WIFI_EVENT_UNKNOWN";
421     }
422 }
423 
RBTlvTagToString(int cmd)424 static const char *RBTlvTagToString(int cmd) {
425     switch (cmd) {
426         C2S(WIFI_TAG_VENDOR_SPECIFIC)
427         C2S(WIFI_TAG_BSSID)
428         C2S(WIFI_TAG_ADDR)
429         C2S(WIFI_TAG_SSID)
430         C2S(WIFI_TAG_STATUS)
431         C2S(WIFI_TAG_CHANNEL_SPEC)
432         C2S(WIFI_TAG_WAKE_LOCK_EVENT)
433         C2S(WIFI_TAG_ADDR1)
434         C2S(WIFI_TAG_ADDR2)
435         C2S(WIFI_TAG_ADDR3)
436         C2S(WIFI_TAG_ADDR4)
437         C2S(WIFI_TAG_IE)
438         C2S(WIFI_TAG_INTERFACE)
439         C2S(WIFI_TAG_REASON_CODE)
440         C2S(WIFI_TAG_RATE_MBPS)
441         C2S(WIFI_TAG_CHANNEL)
442         C2S(WIFI_TAG_RSSI)
443         default:
444             return "WIFI_TAG_UNKNOWN";
445     }
446 }
447 
RBchanWidthToString(int cmd)448 static const char *RBchanWidthToString(int cmd) {
449     switch (cmd) {
450         C2S(WIFI_CHAN_WIDTH_20)
451         C2S(WIFI_CHAN_WIDTH_40)
452         C2S(WIFI_CHAN_WIDTH_80)
453         C2S(WIFI_CHAN_WIDTH_160)
454         C2S(WIFI_CHAN_WIDTH_80P80)
455         C2S(WIFI_CHAN_WIDTH_5)
456         C2S(WIFI_CHAN_WIDTH_10)
457         C2S(WIFI_CHAN_WIDTH_INVALID)
458         default:
459             return "WIFI_CHAN_WIDTH_INVALID";
460     }
461 }
462 
BandToString(wlan_mac_band cmd)463 static const char *BandToString(wlan_mac_band cmd) {
464     switch (cmd) {
465         C2S(WLAN_MAC_2_4_BAND)
466         C2S(WLAN_MAC_5_0_BAND)
467         C2S(WLAN_MAC_6_0_BAND)
468         C2S(WLAN_MAC_60_0_BAND)
469         default:
470         return "INVALID";
471     }
472 }
473 
AntennCfgToString(wifi_antenna_configuration cmd)474 static const char *AntennCfgToString(wifi_antenna_configuration cmd) {
475     switch (cmd) {
476         C2S(WIFI_ANTENNA_1X1)
477         C2S(WIFI_ANTENNA_2X2)
478         C2S(WIFI_ANTENNA_3X3)
479         C2S(WIFI_ANTENNA_4X4)
480         default:
481         return "WIFI_ANTENNA_INVALID";
482     }
483 }
484 
485 /////////////////////////////////////////////////////////////////
486 // RTT related to configuration
487 #define MAX_SSID_LEN (32 + 1)
488 /* 18-bytes of Ethernet address buffer length */
489 #define ETHER_ADDR_STR_LEN      18
490 #define ETHER_ADDR_LEN          6
491 
492 #define DEFAULT_RTT_FILE "/data/rtt-ap.list"
493 static int rtt_from_file = 0;
494 static int rtt_to_file = 0;
495 static wifi_band band = WIFI_BAND_UNSPECIFIED;
496 static int max_ap = 256; // the maximum count of  ap for RTT test
497 static char rtt_aplist[FILE_NAME_LEN] = DEFAULT_RTT_FILE;
498 static mac_addr responder_addr;
499 static wifi_channel responder_channel;
500 static int channel_width = 0;
501 static bool rtt_sta = false;
502 static bool rtt_nan = false;
503 static bool is_6g = false;
504 struct rtt_params {
505     u32 burst_period;
506     u32 num_burst;
507     u32 num_frames_per_burst;
508     u32 num_retries_per_ftm;
509     u32 num_retries_per_ftmr;
510     u32 burst_duration;
511     u8 LCI_request;
512     u8 LCR_request;
513     u8 preamble;
514     u8 bw;
515     wifi_rtt_type type;
516 };
517 struct rtt_params default_rtt_param = {0, 0, 0, 0, 0, 15, 0, 0, 0, 0, RTT_TYPE_2_SIDED};
518 
519 mac_addr hotlist_bssids[16];
520 mac_addr blacklist_bssids[16];
521 char whitelist_ssids[MAX_WHITELIST_SSID][MAX_SSID_LEN] = {{0}};
522 unsigned char mac_oui[3];
523 wifi_epno_params epno_cfg;
524 int channel_list[16];
525 int num_hotlist_bssids = 0;
526 int num_channels = 0;
527 mac_addr pref_bssids[16];
528 int rssi_modifier[16];
529 int num_pref_bssids = -1;
530 int num_blacklist_bssids = -1;
531 int num_whitelist_ssids = -1;
532 bool set_roaming_configuration = false;
533 
534 #define EPNO_HIDDEN               (1 << 0)
535 #define EPNO_A_BAND_TRIG          (1 << 1)
536 #define EPNO_BG_BAND_TRIG         (1 << 2)
537 #define EPNO_ABG_BAND_TRIG        (EPNO_A_BAND_TRIG | EPNO_BG_BAND_TRIG)
538 #define EPNO_FLAG_STRICT_MATCH    (1 << 3)
539 #define EPNO_FLAG_SAME_NETWORK    (1 << 4)
540 
541 void parseMacAddress(const char *str, mac_addr addr);
542 
linux_set_iface_flags(int sock,const char * ifname,int dev_up)543 int linux_set_iface_flags(int sock, const char *ifname, int dev_up)
544 {
545     struct ifreq ifr;
546     int ret;
547 
548     ALOGD("setting interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
549 
550     if (sock < 0) {
551         printMsg("Bad socket: %d\n", sock);
552         return -1;
553     }
554 
555     memset(&ifr, 0, sizeof(ifr));
556 #ifdef ANDROID
557     strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
558 #else
559     strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
560 #endif
561     ALOGD("reading old value\n");
562 
563     if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
564         ret = errno ? -errno : -999;
565         printMsg("Could not read interface %s flags: %d\n", ifname, errno);
566         return ret;
567     } else {
568         ALOGD("writing new value\n");
569     }
570 
571     if (dev_up) {
572         if (ifr.ifr_flags & IFF_UP) {
573             ALOGD("interface %s is already up\n", ifname);
574             return 0;
575         }
576         ifr.ifr_flags |= IFF_UP;
577     } else {
578         if (!(ifr.ifr_flags & IFF_UP)) {
579             printMsg("interface %s is already down\n", ifname);
580             return 0;
581         }
582         ifr.ifr_flags &= ~IFF_UP;
583     }
584 
585     if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
586         ret = errno ? -errno : -999;
587         printMsg("Could not set interface %s flags \n", ifname);
588         return ret;
589     } else {
590         ALOGD("set interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
591     }
592     ALOGD("Done\n");
593     return 0;
594 }
595 
596 
init()597 static int init() {
598     android::wifi_system::HalTool hal_tool;
599     if (!hal_tool.InitFunctionTable(&hal_fn)) {
600         printMsg("Could not initialize the function table!\n");
601         return -1;
602     }
603 
604     android::wifi_system::InterfaceTool if_tool;
605     if (!if_tool.SetWifiUpState(true)) {
606         printMsg("Failed to set the interface state to up.\n");
607         return -1;
608     }
609 
610     wifi_error res = hal_fn.wifi_initialize(&halHandle);
611     if (res < 0) {
612         return res;
613     }
614 
615     res = hal_fn.wifi_get_ifaces(halHandle, &numIfaceHandles, &ifaceHandles);
616     if (res < 0) {
617         return res;
618     }
619 
620     char buf[EVENT_BUF_SIZE];
621     for (int i = 0; i < numIfaceHandles; i++) {
622         if (hal_fn.wifi_get_iface_name(ifaceHandles[i], buf, sizeof(buf)) == WIFI_SUCCESS) {
623             if (strcmp(buf, "wlan0") == 0) {
624                 printMsg("found interface %s\n", buf);
625                 wlan0Handle = ifaceHandles[i];
626             } else if (strcmp(buf, "p2p0") == 0) {
627                 printMsg("found interface %s\n", buf);
628                 p2p0Handle = ifaceHandles[i];
629             }
630         }
631     }
632 
633     return res;
634 }
635 
cleaned_up_handler(wifi_handle handle)636 static void cleaned_up_handler(wifi_handle handle) {
637     printMsg("HAL cleaned up handler\n");
638     halHandle = NULL;
639     ifaceHandles = NULL;
640 }
641 
cleanup()642 static void cleanup() {
643     printMsg("cleaning up HAL\n");
644     hal_fn.wifi_cleanup(halHandle, cleaned_up_handler);
645 }
646 
647 sem_t event_thread_mutex;
648 
eventThreadFunc(void * context)649 static void *eventThreadFunc(void *context) {
650 
651     printMsg("starting wifi event loop\n");
652     sem_post( &event_thread_mutex );
653     hal_fn.wifi_event_loop(halHandle);
654     printMsg("out of wifi event loop\n");
655 
656     return NULL;
657 }
658 
659 
getNewCmdId()660 static int getNewCmdId() {
661     return cmdId++;
662 }
663 
664 /* pretty hex print a contiguous buffer to file */
665 void
fprhex(FILE * f_wp,char * buf,uint nbytes,bool prefix)666 fprhex(FILE *f_wp, char *buf, uint nbytes, bool prefix)
667 {
668     char line[128], *p;
669     int rem_len = sizeof(line);
670     int nchar = 0;
671     uint i;
672 
673     p = line;
674     for (i = 0; i < nbytes; i++) {
675         if ((i % 16 == 0) && prefix) {
676             nchar = snprintf(p, rem_len, "  %04x: ", i); /* line prefix */
677             p += nchar;
678             rem_len -= nchar;
679         }
680 
681         if (rem_len > 0) {
682             nchar = snprintf(p, rem_len, "%02x ", (unsigned char)buf[i]);
683             p += nchar;
684             rem_len -= nchar;
685         }
686 
687         if (i % 16 == 15) {
688             fprintf(f_wp, "%s\n", line); /* flush line */
689             p = line;
690             rem_len = sizeof(line);
691         }
692     }
693 
694     /* flush last partial line */
695     if (p != line) {
696         fprintf(f_wp, "%s\n", line);
697     }
698 }
699 
700 
701 /* -------------------------------------------  */
702 /* helpers                                      */
703 /* -------------------------------------------  */
704 
printScanHeader()705 void printScanHeader() {
706     printMsg("SSID\t\t\t\t\tBSSID\t\t  RSSI\tchannel\ttimestamp\tRTT\tRTT SD\n");
707     printMsg("----\t\t\t\t\t-----\t\t  ----\t-------\t---------\t---\t------\n");
708 }
709 
printScanResult(wifi_scan_result result)710 void printScanResult(wifi_scan_result result) {
711 
712     printMsg("%-32s\t", result.ssid);
713 
714     printMsg("%02x:%02x:%02x:%02x:%02x:%02x ", result.bssid[0], result.bssid[1],
715             result.bssid[2], result.bssid[3], result.bssid[4], result.bssid[5]);
716 
717     printMsg("%d\t", result.rssi);
718     printMsg("%d\t", result.channel);
719     printMsg("%lld\t", result.ts);
720     printMsg("%lld\t", result.rtt);
721     printMsg("%lld\n", result.rtt_sd);
722 }
723 
printSignificantChangeResult(wifi_significant_change_result * res)724 void printSignificantChangeResult(wifi_significant_change_result *res) {
725 
726     wifi_significant_change_result &result = *res;
727     printMsg("%02x:%02x:%02x:%02x:%02x:%02x ", result.bssid[0], result.bssid[1],
728             result.bssid[2], result.bssid[3], result.bssid[4], result.bssid[5]);
729 
730     printMsg("%d\t", result.channel);
731 
732     for (int i = 0; i < result.num_rssi; i++) {
733         printMsg("%d,", result.rssi[i]);
734     }
735     printMsg("\n");
736 }
737 
printScanCapabilities(wifi_gscan_capabilities capabilities)738 void printScanCapabilities(wifi_gscan_capabilities capabilities)
739 {
740     printMsg("Scan Capabililites\n");
741     printMsg("  max_scan_cache_size = %d\n", capabilities.max_scan_cache_size);
742     printMsg("  max_scan_buckets = %d\n", capabilities.max_scan_buckets);
743     printMsg("  max_ap_cache_per_scan = %d\n", capabilities.max_ap_cache_per_scan);
744     printMsg("  max_rssi_sample_size = %d\n", capabilities.max_rssi_sample_size);
745     printMsg("  max_scan_reporting_threshold = %d\n", capabilities.max_scan_reporting_threshold);
746     printMsg("  max_hotlist_bssids = %d\n", capabilities.max_hotlist_bssids);
747     printMsg("  max_significant_wifi_change_aps = %d\n",
748             capabilities.max_significant_wifi_change_aps);
749     printMsg("  max_number_epno_networks = %d\n", capabilities.max_number_epno_networks);
750 }
751 
752 
753 /* -------------------------------------------  */
754 /* commands and events                          */
755 /* -------------------------------------------  */
756 
757 typedef enum {
758     EVENT_TYPE_SCAN_FAILED                        = 1000,
759     EVENT_TYPE_HOTLIST_AP_FOUND                   = 1001,
760     EVENT_TYPE_SIGNIFICANT_WIFI_CHANGE            = 1002,
761     EVENT_TYPE_RTT_RESULTS                        = 1003,
762     EVENT_TYPE_SCAN_COMPLETE                      = 1004,
763     EVENT_TYPE_HOTLIST_AP_LOST                    = 1005,
764     EVENT_TYPE_EPNO_SSID                          = 1006,
765     EVENT_TYPE_LOGGER_RINGBUFFER_DATA             = 1007,
766     EVENT_TYPE_LOGGER_MEMDUMP_DATA                = 1008,
767     EVENT_TYPE_LOGGER_ALERT_DATA                  = 1009,
768     EVENT_TYPE_RSSI_MONITOR                       = 1010,
769     EVENT_TYPE_SCAN_RESULTS_THRESHOLD             = 1011,
770     EVENT_TYPE_NAN_PUBLISH_REPLIED                = 1012,
771     EVENT_TYPE_SUBSCRIBE_MATCHED                  = 1013,
772     EVENT_TYPE_NAN_FOLLOWUP_RECIEVE               = 1014,
773     EVENT_TYPE_NAN_PUBLISH_TERMINATED             = 1015,
774     EVENT_TYPE_NAN_DISABLED                       = 1016,
775     EVENT_TYPE_NAN_SUBSCRIBE_TERMINATED           = 1017,
776     EVENT_TYPE_NAN_ENABLED                        = 1018,
777     EVENT_TYPE_NAN_DATA_REQUEST_INDICATION        = 1019,
778     EVENT_TYPE_NAN_DATA_CONFIRMATION              = 1020,
779     EVENT_TYPE_NAN_DATA_END_INDICAION             = 1021,
780     EVENT_TYPE_NAN_TRANSMIT_FOLLOWUP_INDICATION   = 1022,
781     EVENT_TYPE_RTT_RESULTS_DETAIL                 = 1023,
782     EVENT_TYPE_CHRE_NAN_RTT_STATE_UPDATED         = 1024,
783 
784 } EventType;
785 
786 typedef struct {
787     int type;
788     char buf[MAX_EVENT_MSG_LEN];
789 } EventInfo;
790 
791 const int MAX_EVENTS_IN_CACHE = 256;
792 EventInfo eventCache[256];
793 int eventsInCache = 0;
794 pthread_cond_t eventCacheCondition;
795 pthread_mutex_t eventCacheMutex;
796 
putEventInCache(int type,const char * msg)797 void putEventInCache(int type, const char *msg) {
798     pthread_mutex_lock(&eventCacheMutex);
799     if (eventsInCache + 1 < MAX_EVENTS_IN_CACHE) {
800         eventCache[eventsInCache].type = type;
801         strncpy(eventCache[eventsInCache].buf, msg, (MAX_EVENT_MSG_LEN - 1));
802         eventCache[eventsInCache].buf[MAX_EVENT_MSG_LEN - 1] = '\0';
803         eventsInCache++;
804         pthread_cond_signal(&eventCacheCondition);
805     } else {
806         printMsg("Too many events in the cache\n");
807     }
808     pthread_mutex_unlock(&eventCacheMutex);
809 }
810 
getEventFromCache(EventInfo & info)811 void getEventFromCache(EventInfo& info) {
812     pthread_mutex_lock(&eventCacheMutex);
813     while (true) {
814         if (eventsInCache > 0) {
815             info.type = eventCache[0].type;
816             strncpy(info.buf, eventCache[0].buf, (MAX_EVENT_MSG_LEN - 1));
817             eventCache[0].buf[MAX_EVENT_MSG_LEN - 1] = '\0';
818             eventsInCache--;
819             memmove(&eventCache[0], &eventCache[1], sizeof(EventInfo) * eventsInCache);
820             pthread_mutex_unlock(&eventCacheMutex);
821             return;
822         } else {
823             pthread_cond_wait(&eventCacheCondition, &eventCacheMutex);
824         }
825     }
826 }
827 
on_scan_event(wifi_request_id id,wifi_scan_event event)828 static void on_scan_event(wifi_request_id id, wifi_scan_event event) {
829     EventType internal_event;
830     printMsg("Received scan event\n");
831     if (event == WIFI_SCAN_THRESHOLD_PERCENT || event == WIFI_SCAN_THRESHOLD_NUM_SCANS) {
832         printMsg("Received buffer events - %d \n", event);
833         internal_event = EVENT_TYPE_SCAN_RESULTS_THRESHOLD;
834     } else if(event == WIFI_SCAN_RESULTS_AVAILABLE) {
835         printMsg("Received scan complete event  - WIFI_SCAN_RESULTS_AVAILABLE!!\n");
836         internal_event = EVENT_TYPE_SCAN_COMPLETE;
837     } else if (event == WIFI_SCAN_FAILED) {
838         printMsg("Received scan event - WIFI_SCAN_FAILED \n");
839         internal_event = EVENT_TYPE_SCAN_FAILED;
840     } else {
841         /* set to default value */
842         internal_event = EVENT_TYPE_SCAN_FAILED;
843     }
844     putEventInCache(internal_event, "New scan event");
845 }
846 
847 static int scanCmdId;
848 static int rssiMonId;
849 static int hotlistCmdId;
850 static int rttCmdId;
851 static int epnoCmdId;
852 static int loggerCmdId;
853 static u16 nanCmdId;
854 static u16 twtCmdId;
855 static wifi_error twt_init_handlers(void);
856 
startScan(int max_ap_per_scan,int base_period,int threshold_percent,int threshold_num_scans)857 static bool startScan(int max_ap_per_scan, int base_period, int threshold_percent,
858         int threshold_num_scans) {
859 
860     /* Get capabilties */
861     wifi_gscan_capabilities capabilities;
862     int result = hal_fn.wifi_get_gscan_capabilities(wlan0Handle, &capabilities);
863     if (result < 0) {
864         printMsg("failed to get scan capabilities - %d\n", result);
865         printMsg("trying scan anyway ..\n");
866     } else {
867         printScanCapabilities(capabilities);
868     }
869 
870     wifi_scan_cmd_params params;
871     memset(&params, 0, sizeof(params));
872 
873     if(num_channels > 0){
874         params.max_ap_per_scan = max_ap_per_scan;
875         params.base_period = base_period;                      // 5 second by default
876         params.report_threshold_percent = threshold_percent;
877         params.report_threshold_num_scans = threshold_num_scans;
878         params.num_buckets = 1;
879 
880         params.buckets[0].bucket = 0;
881         params.buckets[0].band = WIFI_BAND_UNSPECIFIED;
882         params.buckets[0].period = base_period;
883         params.buckets[0].num_channels = num_channels;
884 
885         for(int i = 0; i < num_channels; i++){
886             params.buckets[0].channels[i].channel = channel_list[i];
887         }
888 
889     } else {
890 
891         /* create a schedule to scan channels 1, 6, 11 every 5 second and
892          * scan 36, 40, 44, 149, 153, 157, 161 165 every 10 second */
893         params.max_ap_per_scan = max_ap_per_scan;
894         params.base_period = base_period;                      // 5 second
895         params.report_threshold_percent = threshold_percent;
896         params.report_threshold_num_scans = threshold_num_scans;
897         params.num_buckets = 4;
898 
899         params.buckets[0].bucket = 0;
900         params.buckets[0].band = WIFI_BAND_BG;
901         params.buckets[0].period = 5000;                // 5 second
902         params.buckets[0].report_events = 0;
903         params.buckets[0].num_channels = 3;     // driver should ignore list since band is specified
904 
905         params.buckets[0].channels[0].channel = 2412;
906         params.buckets[0].channels[1].channel = 2437;
907         params.buckets[0].channels[2].channel = 2462;
908 
909         params.buckets[1].bucket = 1;
910         params.buckets[1].band = WIFI_BAND_UNSPECIFIED;
911         params.buckets[1].period = 10000;               // 10 second
912         params.buckets[1].report_events = 0;
913         params.buckets[1].num_channels = 6;
914 
915 
916         params.buckets[1].channels[0].channel = 5180;
917         params.buckets[1].channels[1].channel = 5200;
918         params.buckets[1].channels[2].channel = 5220;
919         params.buckets[1].channels[3].channel = 5745;
920         params.buckets[1].channels[4].channel = 5765;
921         params.buckets[1].channels[5].channel = 5785;
922 
923         params.buckets[2].bucket = 2;
924         params.buckets[2].band = WIFI_BAND_UNSPECIFIED;
925         params.buckets[2].period = 15000;                // 15 second
926         params.buckets[2].report_events = 0;
927         params.buckets[2].num_channels = 3;
928 
929         params.buckets[2].channels[0].channel = 2462;
930         params.buckets[2].channels[1].channel = 5805;
931         params.buckets[2].channels[2].channel = 5825;
932 
933         params.buckets[3].bucket = 3;
934         params.buckets[3].band = WIFI_BAND_A;
935         params.buckets[3].period = 35000;       // 35 second
936         params.buckets[3].report_events = 1;
937         params.buckets[3].num_channels = 3;     // driver should ignore list since band is specified
938 
939         params.buckets[3].channels[0].channel = 2462;
940         params.buckets[3].channels[1].channel = 5805;
941         params.buckets[3].channels[2].channel = 5825;
942     }
943 
944     wifi_scan_result_handler handler;
945     memset(&handler, 0, sizeof(handler));
946 
947     handler.on_scan_event = on_scan_event;
948 
949     scanCmdId = getNewCmdId();
950     printMsg("Starting scan --->\n");
951     printMsg("Number of buckets = %d\n", params.num_buckets);
952     return hal_fn.wifi_start_gscan(scanCmdId, wlan0Handle, params, handler) == WIFI_SUCCESS;
953 }
954 
stopScan()955 static void stopScan() {
956     wifi_request_id id = scanCmdId;
957     if (id == 0)
958         id = -1;
959 
960     hal_fn.wifi_stop_gscan(id, wlan0Handle);
961     scanCmdId = 0;
962 }
963 
964 wifi_scan_result **saved_scan_results;
965 unsigned max_saved_scan_results;
966 unsigned num_saved_scan_results;
967 
on_single_shot_scan_event(wifi_request_id id,wifi_scan_event event)968 static void on_single_shot_scan_event(wifi_request_id id, wifi_scan_event event) {
969     if(event == WIFI_SCAN_RESULTS_AVAILABLE || event == WIFI_SCAN_THRESHOLD_NUM_SCANS ||
970             event == WIFI_SCAN_THRESHOLD_PERCENT) {
971         printMsg("Received scan complete event: %d\n", event);
972         putEventInCache(EVENT_TYPE_SCAN_COMPLETE, "One scan completed");
973     }
974     else if (event == WIFI_SCAN_FAILED) {
975         printMsg("Received scan event - WIFI_SCAN_FAILED \n");
976         putEventInCache(EVENT_TYPE_SCAN_FAILED, "Scan failed");
977     }
978     else {
979         printMsg("Received unknown scan event: %d \n", event);
980     }
981 }
982 
on_full_scan_result(wifi_request_id id,wifi_scan_result * r,unsigned buckets_scanned)983 static void on_full_scan_result(wifi_request_id id, wifi_scan_result *r, unsigned buckets_scanned) {
984     if (num_saved_scan_results < max_saved_scan_results) {
985         int alloc_len = offsetof(wifi_scan_result, ie_data) + r->ie_length;
986         wifi_scan_result **result = &(saved_scan_results[num_saved_scan_results]);
987         *result = (wifi_scan_result *)malloc(alloc_len);
988         memcpy(*result, r, alloc_len);
989         printMsg("buckets_scanned - %x\n", buckets_scanned);
990         num_saved_scan_results++;
991     }
992 }
993 
scanOnce(wifi_band band,wifi_scan_result ** results,int num_results)994 static int scanOnce(wifi_band band, wifi_scan_result **results, int num_results) {
995 
996     saved_scan_results = results;
997     max_saved_scan_results = num_results;
998     num_saved_scan_results = 0;
999 
1000     wifi_scan_cmd_params params;
1001     memset(&params, 0, sizeof(params));
1002 
1003     params.max_ap_per_scan = 10;
1004     params.base_period = 5000;                        // 5 second by default
1005     params.report_threshold_percent = 90;
1006     params.report_threshold_num_scans = 1;
1007     params.num_buckets = 1;
1008 
1009     params.buckets[0].bucket = 0;
1010     params.buckets[0].band = band;
1011     params.buckets[0].period = 5000;                  // 5 second
1012     params.buckets[0].report_events = 2;              // REPORT_EVENTS_AFTER_EACH_SCAN
1013     params.buckets[0].num_channels = 0;
1014 
1015     wifi_scan_result_handler handler;
1016     memset(&handler, 0, sizeof(handler));
1017     handler.on_scan_event = on_single_shot_scan_event;
1018     handler.on_full_scan_result = on_full_scan_result;
1019 
1020     int scanCmdId = getNewCmdId();
1021     printMsg("Starting scan --->\n");
1022     if (hal_fn.wifi_start_gscan(scanCmdId, wlan0Handle, params, handler) == WIFI_SUCCESS) {
1023         while (true) {
1024             EventInfo info;
1025             memset(&info, 0, sizeof(info));
1026             getEventFromCache(info);
1027             if (info.type == EVENT_TYPE_SCAN_RESULTS_THRESHOLD
1028                     || info.type == EVENT_TYPE_SCAN_COMPLETE) {
1029                 int retrieved_num_results = num_saved_scan_results;
1030                 if (retrieved_num_results == 0) {
1031                     printMsg("fetched 0 scan results, waiting for more..\n");
1032                     continue;
1033                 } else {
1034                     printMsg("fetched %d scan results\n", retrieved_num_results);
1035 
1036                     printMsg("Scan once completed, stopping scan\n");
1037                     hal_fn.wifi_stop_gscan(scanCmdId, wlan0Handle);
1038                     saved_scan_results = NULL;
1039                     max_saved_scan_results = 0;
1040                     num_saved_scan_results = 0;
1041                     return retrieved_num_results;
1042                 }
1043             }
1044         }
1045     } else {
1046         return 0;
1047     }
1048 }
1049 
retrieveScanResults()1050 static int retrieveScanResults() {
1051 
1052     int num_results = 64;
1053     wifi_cached_scan_results *results;
1054     results = (wifi_cached_scan_results *)malloc(num_results * sizeof(wifi_cached_scan_results));
1055     if (!results) {
1056         printMsg("%s:Malloc failed\n",__FUNCTION__);
1057         return WIFI_ERROR_OUT_OF_MEMORY;
1058     }
1059     memset(results, 0, sizeof(wifi_cached_scan_results) * num_results);
1060     printMsg("Retrieve Scan results available -->\n");
1061     int result = hal_fn.wifi_get_cached_gscan_results(wlan0Handle, 1, num_results, results, &num_results);
1062     if (result < 0) {
1063         printMsg("failed to fetch scan results : %d\n", result);
1064         goto exit;
1065     } else {
1066         printMsg("fetched %d scan results\n", num_results);
1067     }
1068 
1069     printScanHeader();
1070     for (int i = 0; i < num_results; i++) {
1071         printMsg("ScanId = %d, Scanned buckets 0x%x, Flags = %x, num results = %d\n",
1072             results[i].scan_id, results[i].buckets_scanned, results[i].flags,
1073             results[i].num_results);
1074         for (int j = 0; j < results[i].num_results; j++) {
1075             printScanResult(results[i].results[j]);
1076         }
1077         printMsg("\n");
1078     }
1079 
1080 exit:
1081     if (results) {
1082         free(results);
1083     }
1084     return WIFI_SUCCESS;
1085 }
1086 
1087 
compareScanResultsByRssi(const void * p1,const void * p2)1088 static int compareScanResultsByRssi(const void *p1, const void *p2) {
1089     const wifi_scan_result *result1 = *(const wifi_scan_result **)(p1);
1090     const wifi_scan_result *result2 = *(const wifi_scan_result **)(p2);
1091 
1092     /* RSSI is -ve, so lower one wins */
1093     if (result1->rssi < result2->rssi) {
1094         return 1;
1095     } else if (result1->rssi == result2->rssi) {
1096         return 0;
1097     } else {
1098         return -1;
1099     }
1100 }
1101 
sortScanResultsByRssi(wifi_scan_result ** results,int num_results)1102 static void sortScanResultsByRssi(wifi_scan_result **results, int num_results) {
1103     qsort(results, num_results, sizeof(wifi_scan_result*), &compareScanResultsByRssi);
1104 }
1105 
removeDuplicateScanResults(wifi_scan_result ** results,int num)1106 static int removeDuplicateScanResults(wifi_scan_result **results, int num) {
1107     /* remove duplicates by BSSID */
1108     int num_results = num;
1109     wifi_scan_result *tmp;
1110     for (int i = 0; i < num_results; i++) {
1111         for (int j = i + 1; j < num_results; ) {
1112             if (memcmp((*results[i]).bssid, (*results[j]).bssid, sizeof(mac_addr)) == 0) {
1113                 int num_to_move = num_results - j - 1;
1114                 tmp = results[j];
1115                 memmove(&results[j], &results[j+1], num_to_move * sizeof(wifi_scan_result *));
1116                 free(tmp);
1117                 num_results--;
1118             } else {
1119                 j++;
1120             }
1121         }
1122     }
1123     return num_results;
1124 }
1125 
onRTTResults(wifi_request_id id,unsigned num_results,wifi_rtt_result * result[])1126 static void onRTTResults (wifi_request_id id, unsigned num_results, wifi_rtt_result *result[]) {
1127 
1128     printMsg("RTT results\n");
1129     wifi_rtt_result *rtt_result;
1130     mac_addr addr = {0};
1131     for (unsigned i = 0; i < num_results; i++) {
1132         rtt_result = result[i];
1133         if (memcmp(addr, rtt_result->addr, sizeof(mac_addr))) {
1134             printMsg("Target mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
1135                     rtt_result->addr[0],
1136                     rtt_result->addr[1],
1137                     rtt_result->addr[2],
1138                     rtt_result->addr[3],
1139                     rtt_result->addr[4],
1140                     rtt_result->addr[5]);
1141             memcpy(addr, rtt_result->addr, sizeof(mac_addr));
1142         }
1143         printMsg("\tburst_num : %d, measurement_number : %d, success_number : %d\n"
1144                 "\tnumber_per_burst_peer : %d, status : %d, retry_after_duration : %d s\n"
1145                 "\trssi : %d dbm, rx_rate : %d Kbps, rtt : %llu ns, rtt_sd : %llu\n"
1146                 "\tdistance : %d cm, burst_duration : %d ms, negotiated_burst_num : %d\n",
1147                 rtt_result->burst_num, rtt_result->measurement_number,
1148                 rtt_result->success_number, rtt_result->number_per_burst_peer,
1149                 rtt_result->status, rtt_result->retry_after_duration,
1150                 rtt_result->rssi, rtt_result->rx_rate.bitrate * 100,
1151                 rtt_result->rtt/1000, rtt_result->rtt_sd, rtt_result->distance_mm / 10,
1152                 rtt_result->burst_duration, rtt_result->negotiated_burst_num);
1153     }
1154 
1155     putEventInCache(EVENT_TYPE_RTT_RESULTS, "RTT results");
1156 }
1157 
onHotlistAPFound(wifi_request_id id,unsigned num_results,wifi_scan_result * results)1158 static void onHotlistAPFound(wifi_request_id id, unsigned num_results, wifi_scan_result *results) {
1159 
1160     printMsg("Found hotlist APs\n");
1161     for (unsigned i = 0; i < num_results; i++) {
1162         printScanResult(results[i]);
1163     }
1164     putEventInCache(EVENT_TYPE_HOTLIST_AP_FOUND, "Found a hotlist AP");
1165 }
1166 
onHotlistAPLost(wifi_request_id id,unsigned num_results,wifi_scan_result * results)1167 static void onHotlistAPLost(wifi_request_id id, unsigned num_results, wifi_scan_result *results) {
1168 
1169     printMsg("Lost hotlist APs\n");
1170     for (unsigned i = 0; i < num_results; i++) {
1171         printScanResult(results[i]);
1172     }
1173     putEventInCache(EVENT_TYPE_HOTLIST_AP_LOST, "Lost event Hotlist APs");
1174 }
1175 
onePnoSsidFound(wifi_request_id id,unsigned num_results,wifi_scan_result * results)1176 static void onePnoSsidFound(wifi_request_id id, unsigned num_results, wifi_scan_result *results) {
1177 
1178     printMsg("Found ePNO SSID\n");
1179     for (unsigned i = 0; i < num_results; i++) {
1180         printMsg("SSID %s, %02x:%02x:%02x:%02x:%02x:%02x, channel %d, rssi %d\n",
1181             results[i].ssid, results[i].bssid[0], results[i].bssid[1],
1182             results[i].bssid[2], results[i].bssid[3], results[i].bssid[4],
1183             results[i].bssid[5], results[i].channel, (signed char)results[i].rssi);
1184     }
1185     putEventInCache(EVENT_TYPE_EPNO_SSID, "Found ePNO SSID");
1186 }
1187 
onRssiThresholdbreached(wifi_request_id id,u8 * cur_bssid,s8 cur_rssi)1188 static void onRssiThresholdbreached(wifi_request_id id, u8 *cur_bssid, s8 cur_rssi) {
1189 
1190     printMsg("RSSI threshold breached, cur RSSI - %d!!\n", cur_rssi);
1191     printMsg("BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
1192                 cur_bssid[0], cur_bssid[1], cur_bssid[2],
1193                 cur_bssid[3], cur_bssid[4], cur_bssid[5]);
1194     putEventInCache(EVENT_TYPE_RSSI_MONITOR, "RSSI monitor Event");
1195 }
1196 
1197 
bss_get_ie(u8 id,const char * ie,const s32 ie_len)1198 static const u8 *bss_get_ie(u8 id, const char* ie, const s32 ie_len)
1199 {
1200     const u8 *end, *pos;
1201 
1202     pos = (const u8 *)ie;
1203     end = pos + ie_len;
1204 
1205     while (pos + 1 < end) {
1206         if (pos + 2 + pos[1] > end)
1207             break;
1208         if (pos[0] == id)
1209             return pos;
1210         pos += 2 + pos[1];
1211     }
1212 
1213     return NULL;
1214 }
is11mcAP(const char * ie,const s32 ie_len)1215 static bool is11mcAP(const char* ie, const s32 ie_len)
1216 {
1217     const u8 *ext_cap_ie, *ptr_ie;
1218     u8 ext_cap_length = 0;
1219     ptr_ie = bss_get_ie(WIFI_EID_EXT_CAPAB, ie, ie_len);
1220     if (ptr_ie) {
1221         ext_cap_length = *(ptr_ie + TLV_LEN_OFF);
1222         ext_cap_ie = ptr_ie + TLV_BODY_OFF;
1223         if ((ext_cap_length >= CEIL(DOT11_EXT_CAP_FTM_RESPONDER, NBBY)) &&
1224                 (isset(ext_cap_ie, DOT11_EXT_CAP_FTM_RESPONDER) ||
1225                  isset(ext_cap_ie, DOT11_EXT_CAP_FTM_INITIATOR))) {
1226             return true;
1227         }
1228     }
1229     return false;
1230 }
1231 
1232 #define CHAN_FACTOR_6_G 11900u   /* 6   GHz band, 5950 MHz */
channel2mhz_6g(uint ch)1233 int channel2mhz_6g(uint ch)
1234 {
1235      int freq;
1236      freq = (ch * 5) + (CHAN_FACTOR_6_G / 2);
1237      return freq;
1238 }
1239 
channel2mhz(uint ch)1240 int channel2mhz(uint ch)
1241 {
1242     int freq;
1243     int start_factor = (ch > 14)? CHAN_FACTOR_5_G : CHAN_FACTOR_2_4_G;
1244     if ((start_factor == CHAN_FACTOR_2_4_G && (ch < 1 || ch > 14)) ||
1245             (ch > 200))
1246         freq = -1;
1247     else if ((start_factor == CHAN_FACTOR_2_4_G) && (ch == 14))
1248         freq = 2484;
1249     else
1250         freq = ch * 5 + start_factor / 2;
1251 
1252     return freq;
1253 }
1254 
read_ht_oper_ie(const char * ie,const s32 ie_len)1255 struct ht_op_ie *read_ht_oper_ie(const char* ie, const s32 ie_len)
1256 {
1257     const u8 *ptr_ie;
1258     ptr_ie = bss_get_ie(WIFI_EID_HT_OPERATION, ie, ie_len);
1259     if (ptr_ie) {
1260         return (struct ht_op_ie *)(ptr_ie + TLV_BODY_OFF);
1261     }
1262     return NULL;
1263 }
1264 
read_vht_oper_ie(const char * ie,const s32 ie_len)1265 struct vht_op_ie *read_vht_oper_ie(const char* ie, const s32 ie_len)
1266 {
1267     const u8 *ptr_ie;
1268     ptr_ie = bss_get_ie(WIFI_EID_VHT_OPERATION, ie, ie_len);
1269     if (ptr_ie) {
1270         return (struct vht_op_ie *)(ptr_ie + TLV_BODY_OFF);
1271     }
1272     return NULL;
1273 }
1274 
convert_channel(int ch,int chan_width,bool is_6g)1275 wifi_channel_info convert_channel(int ch, int chan_width, bool is_6g)
1276 {
1277     wifi_channel_info chan_info;
1278     memset(&chan_info, 0, sizeof(wifi_channel_info));
1279 
1280     chan_info.width = (wifi_channel_width)chan_width;
1281     if (is_6g) {
1282         chan_info.center_freq = channel2mhz_6g(ch);
1283         return chan_info;
1284     } else {
1285         chan_info.center_freq = channel2mhz(ch);
1286     }
1287     if (chan_width == WIFI_CHAN_WIDTH_160) {
1288         if ((ch >= 36) && (ch <= 64))
1289             chan_info.center_freq0 = 5250;
1290         if ((ch >= 100) && (ch <= 128))
1291             chan_info.center_freq0 = 5570;
1292         if ((ch >= 149) && (ch <= 177))
1293             chan_info.center_freq0 = 5815;
1294     } else if (chan_width == WIFI_CHAN_WIDTH_80) {
1295         /*primary is the lowest channel*/
1296         if ((ch >= 36) && (ch <= 48))
1297             chan_info.center_freq0 = 5210;
1298         else if ((ch >= 52) && (ch <= 64))
1299             chan_info.center_freq0 = 5290;
1300         else if ((ch >= 100) && (ch <= 112))
1301             chan_info.center_freq0 = 5530;
1302         else if ((ch >= 116) && (ch <= 128))
1303             chan_info.center_freq0 = 5610;
1304         else if ((ch >= 132) && (ch <= 144))
1305             chan_info.center_freq0 = 5690;
1306         else if ((ch >= 149) && (ch <= 161))
1307             chan_info.center_freq0 = 5775;
1308     } else {
1309         if (chan_width == WIFI_CHAN_WIDTH_40) {
1310             if ((ch >= 36) && (ch <= 40))
1311                 chan_info.center_freq0 = 5190;
1312             else if ((ch >= 44) && (ch <= 48))
1313                 chan_info.center_freq0 = 5230;
1314             else if ((ch >= 52) && (ch <= 56))
1315                 chan_info.center_freq0 = 5270;
1316             else if ((ch >= 60) && (ch <= 64))
1317                 chan_info.center_freq0 = 5310;
1318             else if ((ch >= 100) && (ch <= 104))
1319                 chan_info.center_freq0 = 5510;
1320             else if ((ch >= 108) && (ch <= 112))
1321                 chan_info.center_freq0 = 5550;
1322             else if ((ch >= 116) && (ch <= 120))
1323                 chan_info.center_freq0 = 5590;
1324             else if ((ch >= 124) && (ch <= 128))
1325                 chan_info.center_freq0 = 5630;
1326             else if ((ch >= 132) && (ch <= 136))
1327                 chan_info.center_freq0 = 5670;
1328             else if ((ch >= 140) && (ch <= 144))
1329                 chan_info.center_freq0 = 5710;
1330             else if ((ch >= 149) && (ch <= 153))
1331                 chan_info.center_freq0 = 5755;
1332             else if ((ch >= 157) && (ch <= 161))
1333                 chan_info.center_freq0 = 5795;
1334         }
1335     }
1336     return chan_info;
1337 }
1338 
get_channel_of_ie(const char * ie,const s32 ie_len)1339 wifi_channel_info get_channel_of_ie(const char* ie, const s32 ie_len)
1340 {
1341     struct vht_op_ie *vht_op;
1342     struct ht_op_ie *ht_op;
1343     const u8 *ptr_ie;
1344     wifi_channel_info chan_info;
1345     memset(&chan_info, 0, sizeof(wifi_channel_info));
1346     vht_op = read_vht_oper_ie(ie, ie_len);
1347     if ((vht_op = read_vht_oper_ie(ie, ie_len)) &&
1348             (ht_op = read_ht_oper_ie(ie, ie_len))) {
1349         /* VHT mode */
1350         if (vht_op->chan_width == VHT_OP_CHAN_WIDTH_80) {
1351             chan_info.width = WIFI_CHAN_WIDTH_80;
1352             /* primary channel */
1353             chan_info.center_freq = channel2mhz(ht_op->ctl_ch);
1354             /* center frequency */
1355             chan_info.center_freq0 = channel2mhz(vht_op->chan1);
1356             return chan_info;
1357         }
1358     }
1359     if (ht_op = read_ht_oper_ie(ie, ie_len)){
1360         /* HT mode */
1361         /* control channel */
1362         chan_info.center_freq = channel2mhz(ht_op->ctl_ch);
1363         chan_info.width = WIFI_CHAN_WIDTH_20;
1364         switch (ht_op->chan_info & DOT11_EXT_CH_MASK) {
1365             chan_info.center_freq = channel2mhz(ht_op->ctl_ch);
1366             case DOT11_EXT_CH_UPPER:
1367                 chan_info.width = WIFI_CHAN_WIDTH_40;
1368                 break;
1369             case DOT11_EXT_CH_LOWER:
1370                 chan_info.width = WIFI_CHAN_WIDTH_40;
1371                 break;
1372             case DOT11_EXT_CH_NONE:
1373                 break;
1374         }
1375     } else {
1376         chan_info.width = WIFI_CHAN_WIDTH_20;
1377         ptr_ie = bss_get_ie(WIFI_EID_DS_PARAMS, ie, ie_len);
1378         if (ptr_ie) {
1379             chan_info.center_freq = channel2mhz(ptr_ie[TLV_BODY_OFF]);
1380         }
1381     }
1382     return chan_info;
1383 }
1384 
testRTT()1385 static void testRTT()
1386 {
1387     wifi_scan_result *results[max_ap];
1388     wifi_scan_result *scan_param;
1389     u32 num_ap = 0;
1390     /*For STA-STA RTT */
1391     u32 num_sta = 0;
1392     int result = 0;
1393     /* Run by a provided rtt-ap-list file */
1394     FILE* w_fp = NULL;
1395     wifi_rtt_config params[max_ap];
1396     if (!rtt_from_file && !rtt_sta && !rtt_nan) {
1397         /* band filter for a specific band */
1398         if (band == WIFI_BAND_UNSPECIFIED)
1399             band = WIFI_BAND_ABG;
1400         int num_results = scanOnce(band, results, max_ap);
1401         if (num_results == 0) {
1402             printMsg("RTT aborted because of no scan results\n");
1403             return;
1404         } else {
1405             printMsg("Retrieved %d scan results\n", num_results);
1406         }
1407 
1408         num_results = removeDuplicateScanResults(results, num_results);
1409 
1410         sortScanResultsByRssi(results, num_results);
1411         printMsg("Sorted scan results -\n");
1412         for (int i = 0; i < num_results; i++) {
1413             printScanResult(*results[i]);
1414         }
1415         if (rtt_to_file) {
1416             /* Write a RTT AP list to a file */
1417             w_fp = fopen(rtt_aplist, "w");
1418             if (w_fp == NULL) {
1419                 printMsg("failed to open the file : %s\n", rtt_aplist);
1420                 return;
1421             }
1422             fprintf(w_fp, "|SSID|BSSID|Primary Freq|Center Freq|Channel BW(0=20MHZ,1=40MZ,2=80MHZ)"
1423                     "|rtt_type(1=1WAY,2=2WAY,3=auto)|Peer Type(STA=0, AP=1)|burst period|"
1424                     "Num of Burst|FTM retry count|FTMR retry count|LCI|LCR|Burst Duration|Preamble|BW\n");
1425         }
1426         for (int i = 0; i < min(num_results, max_ap); i++) {
1427             scan_param = results[i];
1428             if(is11mcAP(&scan_param->ie_data[0], scan_param->ie_length)) {
1429                 memcpy(params[num_ap].addr, scan_param->bssid, sizeof(mac_addr));
1430                 mac_addr &addr = params[num_ap].addr;
1431                 printMsg("Adding %s(%02x:%02x:%02x:%02x:%02x:%02x) on Freq (%d) for 11mc RTT\n",
1432                         scan_param->ssid, addr[0], addr[1],
1433                         addr[2], addr[3], addr[4], addr[5],
1434                         scan_param->channel);
1435                 params[num_ap].type = default_rtt_param.type;
1436                 params[num_ap].channel = get_channel_of_ie(&scan_param->ie_data[0],
1437                         scan_param->ie_length);
1438                 params[num_ap].peer = RTT_PEER_AP;
1439                 params[num_ap].num_burst = default_rtt_param.num_burst;
1440                 params[num_ap].num_frames_per_burst = default_rtt_param.num_frames_per_burst;
1441                 params[num_ap].num_retries_per_rtt_frame =
1442                     default_rtt_param.num_retries_per_ftm;
1443                 params[num_ap].num_retries_per_ftmr = default_rtt_param.num_retries_per_ftmr;
1444                 params[num_ap].burst_period = default_rtt_param.burst_period;
1445                 params[num_ap].burst_duration = default_rtt_param.burst_duration;
1446                 params[num_ap].LCI_request = default_rtt_param.LCI_request;
1447                 params[num_ap].LCR_request = default_rtt_param.LCR_request;
1448                 params[num_ap].preamble = (wifi_rtt_preamble)default_rtt_param.preamble;
1449                 params[num_ap].bw = (wifi_rtt_bw)default_rtt_param.bw;
1450                 if (rtt_to_file) {
1451                     fprintf(w_fp, "%s %02x:%02x:%02x:%02x:%02x:%02x %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", scan_param->ssid,
1452                             params[num_ap].addr[0], params[num_ap].addr[1], params[num_ap].addr[2], params[num_ap].addr[3],
1453                             params[num_ap].addr[4], params[num_ap].addr[5],params[num_ap].channel.center_freq,
1454                             params[num_ap].channel.center_freq0, params[num_ap].channel.width, params[num_ap].type,params[num_ap].peer,
1455                             params[num_ap].burst_period, params[num_ap].num_burst, params[num_ap].num_frames_per_burst,
1456                             params[num_ap].num_retries_per_rtt_frame, params[num_ap].num_retries_per_ftmr,
1457                             params[num_ap].LCI_request, params[num_ap].LCR_request, params[num_ap].burst_duration,
1458                             params[num_ap].preamble, params[num_ap].bw);
1459                 }
1460                 num_ap++;
1461             } else {
1462                 /* legacy AP */
1463             }
1464         }
1465         /* free the results data */
1466         for (int i = 0; i < num_results; i++) {
1467             free(results[i]);
1468             results[i] = NULL;
1469         }
1470         if (w_fp)
1471             fclose(w_fp);
1472     } else if (rtt_sta || rtt_nan) {
1473         printf(" Run initiator rtt sta/nan, rtt_sta = %d, rtt_nan = %d \n",
1474             rtt_sta, rtt_nan);
1475         /* As we have only one target */
1476         memcpy(params[num_sta].addr, responder_addr, sizeof(mac_addr));
1477         params[num_sta].channel = convert_channel(responder_channel, channel_width, is_6g);
1478         printMsg("Adding(" MACSTR ") on Freq (%d),(%d) for 11mc RTT\n",
1479                  MAC2STR(responder_addr),
1480                  params[num_sta].channel.center_freq,
1481                  params[num_sta].channel.center_freq0);
1482         /*As we are doing STA-STA RTT */
1483         params[num_sta].type = default_rtt_param.type;
1484         if (rtt_nan) {
1485             params[num_sta].peer = RTT_PEER_NAN;
1486         } else if (rtt_sta) {
1487             params[num_sta].peer = RTT_PEER_STA;
1488         }
1489         params[num_sta].num_burst = default_rtt_param.num_burst;
1490         params[num_sta].num_frames_per_burst = default_rtt_param.num_frames_per_burst;
1491         params[num_sta].num_retries_per_rtt_frame =
1492             default_rtt_param.num_retries_per_ftm;
1493         params[num_sta].num_retries_per_ftmr = default_rtt_param.num_retries_per_ftmr;
1494         params[num_sta].burst_period = default_rtt_param.burst_period;
1495         params[num_sta].burst_duration = default_rtt_param.burst_duration;
1496         params[num_sta].LCI_request = default_rtt_param.LCI_request;
1497         params[num_sta].LCR_request = default_rtt_param.LCR_request;
1498         params[num_sta].preamble = (wifi_rtt_preamble)default_rtt_param.preamble;
1499         params[num_sta].bw = (wifi_rtt_bw)default_rtt_param.bw;
1500         num_sta++;
1501 
1502     } else {
1503 
1504         /* Run by a provided rtt-ap-list file */
1505         FILE* fp;
1506         char bssid[ETHER_ADDR_STR_LEN];
1507         char ssid[MAX_SSID_LEN];
1508         char first_char;
1509         memset(bssid, 0, sizeof(bssid));
1510         memset(ssid, 0, sizeof(ssid));
1511         /* Read a RTT AP list from a file */
1512         fp = fopen(rtt_aplist, "r");
1513         if (fp == NULL) {
1514             printMsg("\nRTT AP list file does not exist on %s.\n"
1515                     "Please specify correct full path or use default one, %s, \n"
1516                     "  by following order in file, such as:\n"
1517                     "|SSID|BSSID|chan_num|Channel BW(0=20MHZ,1=40MZ,2=80MHZ)|"
1518                     "RTT_Type(1=1WAY,2=2WAY,3=auto)|Peer Type(STA=0, AP=1)|Burst Period|"
1519                     "No of Burst|No of FTM Burst|FTM Retry Count|FTMR Retry Count|LCI|LCR|"
1520                     "Burst Duration|Preamble|Bandwith\n",
1521                     rtt_aplist, DEFAULT_RTT_FILE);
1522             return;
1523         }
1524         printMsg("    %-16s%-20s%-8s%-12s%-10s%-10s%-16s%-10s%-14s%-11s%-12s%-5s%-5s%-15s%-10s\n",
1525                 "SSID", "BSSID", "chan", "Bandwidth", "RTT_Type", "RTT_Peer",
1526                 "Burst_Period", "No_Burst", "No_FTM_Burst", "FTM_Retry",
1527                 "FTMR_Retry", "LCI", "LCR", "Burst_duration", "Preamble", "Bandwidth");
1528         int i = 0;
1529         while (!feof(fp)) {
1530             if ((fscanf(fp, "%c", &first_char) == 1) && (first_char != '|')) {
1531                 fseek(fp, -1, SEEK_CUR);
1532                 result = fscanf(fp, "%s %s %u %u %u %u %u %u %u %u %u %hhu %hhu %u %hhu %hhu\n",
1533                         ssid, bssid, (unsigned int*)&responder_channel,
1534                         (unsigned int*)&channel_width,
1535                         (unsigned int*)&params[i].type, (unsigned int*)&params[i].peer,
1536                         &params[i].burst_period, &params[i].num_burst,
1537                         &params[i].num_frames_per_burst,
1538                         &params[i].num_retries_per_rtt_frame,
1539                         &params[i].num_retries_per_ftmr,
1540                         (unsigned char*)&params[i].LCI_request,
1541                         (unsigned char*)&params[i].LCR_request,
1542                         (unsigned int*)&params[i].burst_duration,
1543                         (unsigned char*)&params[i].preamble,
1544                         (unsigned char*)&params[i].bw);
1545 
1546                 if (result != 16) {
1547                     printMsg("fscanf failed %d\n", result);
1548                     break;
1549                 }
1550                 params[i].channel = convert_channel(responder_channel, channel_width, is_6g);
1551                 parseMacAddress(bssid, params[i].addr);
1552 
1553                 printMsg("[%d] %-16s%-20s%-8u%-14u%-12d%-10d%-10u%-16u%-10u%-14u%-11u%-12u%-5hhu%-5hhu%-15u%-10hhu-10hhu\n",
1554                         i+1, ssid, bssid, params[i].channel.center_freq,
1555                         params[i].channel.center_freq0, params[i].channel.width,
1556                         params[i].type, params[i].peer, params[i].burst_period,
1557                         params[i].num_burst, params[i].num_frames_per_burst,
1558                         params[i].num_retries_per_rtt_frame,
1559                         params[i].num_retries_per_ftmr, params[i].LCI_request,
1560                         params[i].LCR_request, params[i].burst_duration, params[i].preamble, params[i].bw);
1561 
1562                 i++;
1563             } else {
1564                 /* Ignore the rest of the line. */
1565                 result = fscanf(fp, "%*[^\n]");
1566                 if (result != 1) {
1567                     printMsg("fscanf failed %d\n", result);
1568                     break;
1569                 }
1570 
1571                 result = fscanf(fp, "\n");
1572                 if (result != 1) {
1573                     printMsg("fscanf failed %d\n", result);
1574                     break;
1575                 }
1576             }
1577         }
1578         num_ap = i;
1579         fclose(fp);
1580         fp = NULL;
1581     }
1582 
1583     wifi_rtt_event_handler handler;
1584     handler.on_rtt_results = &onRTTResults;
1585     if (!rtt_to_file || rtt_sta || rtt_nan)  {
1586         if (num_ap || num_sta) {
1587             if (num_ap) {
1588                 printMsg("Configuring RTT for %d APs\n", num_ap);
1589                 result = hal_fn.wifi_rtt_range_request(rttCmdId, wlan0Handle, num_ap, params, handler);
1590             } else if (num_sta) {
1591                 printMsg("Configuring RTT for %d sta \n", num_sta);
1592                 result = hal_fn.wifi_rtt_range_request(rttCmdId, wlan0Handle, num_sta, params, handler);
1593             }
1594 
1595             if (result == WIFI_SUCCESS) {
1596                 printMsg("\nWaiting for RTT results\n");
1597                 while (true) {
1598                     EventInfo info;
1599                     memset(&info, 0, sizeof(info));
1600                     getEventFromCache(info);
1601                     if (info.type == EVENT_TYPE_RTT_RESULTS ||
1602                         info.type == EVENT_TYPE_RTT_RESULTS_DETAIL) {
1603                         break;
1604                     }
1605                 }
1606             } else {
1607                 printMsg("Could not set setRTTAPs : %d\n", result);
1608             }
1609         } else {
1610             printMsg("no candidate for RTT\n");
1611         }
1612     } else {
1613         printMsg("written AP info into file %s successfully\n", rtt_aplist);
1614     }
1615 }
1616 
cancelRTT()1617 static int cancelRTT()
1618 {
1619     int ret;
1620     ret = hal_fn.wifi_rtt_range_cancel(rttCmdId, wlan0Handle, 0, NULL);
1621     if (ret == WIFI_SUCCESS) {
1622         printMsg("Successfully cancelled the RTT\n");
1623     }
1624     return ret;
1625 }
1626 
getRTTCapability()1627 static void getRTTCapability()
1628 {
1629     int ret;
1630     wifi_rtt_capabilities rtt_capability;
1631     ret = hal_fn.wifi_get_rtt_capabilities(wlan0Handle, &rtt_capability);
1632     if (ret == WIFI_SUCCESS) {
1633         printMsg("Supported Capabilites of RTT :\n");
1634         if (rtt_capability.rtt_one_sided_supported)
1635             printMsg("One side RTT is supported\n");
1636         if (rtt_capability.rtt_ftm_supported)
1637             printMsg("FTM(11mc) RTT is supported\n");
1638         if (rtt_capability.lci_support)
1639             printMsg("LCI is supported\n");
1640         if (rtt_capability.lcr_support)
1641             printMsg("LCR is supported\n");
1642         if (rtt_capability.bw_support) {
1643             printMsg("BW(%s %s %s %s) are supported\n",
1644                     (rtt_capability.bw_support & BW_20_SUPPORT) ? "20MHZ" : "",
1645                     (rtt_capability.bw_support & BW_40_SUPPORT) ? "40MHZ" : "",
1646                     (rtt_capability.bw_support & BW_80_SUPPORT) ? "80MHZ" : "",
1647                     (rtt_capability.bw_support & BW_160_SUPPORT) ? "160MHZ" : "");
1648         }
1649         if (rtt_capability.preamble_support) {
1650             printMsg("Preamble(%s %s %s) are supported\n",
1651                     (rtt_capability.preamble_support & PREAMBLE_LEGACY) ? "Legacy" : "",
1652                     (rtt_capability.preamble_support & PREAMBLE_HT) ? "HT" : "",
1653                     (rtt_capability.preamble_support & PREAMBLE_VHT) ? "VHT" : "");
1654 
1655         }
1656     } else {
1657         printMsg("Could not get the rtt capabilities : %d\n", ret);
1658     }
1659 
1660 }
1661 
1662 /* TWT related apis */
setupTwtRequest(char * argv[])1663 static void setupTwtRequest(char *argv[]) {
1664     TwtSetupRequest msg;
1665     wifi_error ret = WIFI_SUCCESS;
1666     char *endptr, *param, *val_p;
1667 
1668     /* Set Default twt setup request params */
1669     memset(&msg, 0, sizeof(msg));
1670 
1671     /* Parse args for twt params */
1672     /* skip utility */
1673     argv++;
1674     /* skip command */
1675     argv++;
1676     /* skip command */
1677     argv++;
1678 
1679     while ((param = *argv++) != NULL) {
1680         val_p = *argv++;
1681         if (!val_p || *val_p == '-') {
1682             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
1683             ret = WIFI_ERROR_NOT_SUPPORTED;
1684             goto exit;
1685         }
1686         if (strcmp(param, "-config_id") == 0) {
1687             msg.config_id = atoi(val_p);
1688         } else if (strcmp(param, "-neg_type") == 0) {
1689             msg.negotiation_type = atoi(val_p);
1690         } else if (strcmp(param, "-trigger_type") == 0) {
1691             msg.trigger_type = atoi(val_p);
1692         } else if (strcmp(param, "-wake_dur_us") == 0) {
1693             msg.wake_dur_us = strtoul(val_p, &endptr, 0);
1694         } else if (strcmp(param, "-wake_int_us") == 0) {
1695             msg.wake_int_us = strtoul(val_p, &endptr, 0);
1696         } else if (strcmp(param, "-wake_int_min_us") == 0) {
1697             msg.wake_int_min_us = strtoul(val_p, &endptr, 0);
1698         } else if (strcmp(param, "-wake_int_max_us") == 0) {
1699             msg.wake_int_max_us = strtoul(val_p, &endptr, 0);
1700         } else if (strcmp(param, "-wake_dur_min_us") == 0) {
1701             msg.wake_dur_min_us = strtoul(val_p, &endptr, 0);
1702         } else if (strcmp(param, "-wake_dur_max_us") == 0) {
1703             msg.wake_dur_max_us = strtoul(val_p, &endptr, 0);
1704         } else if (strcmp(param, "-avg_pkt_size") == 0) {
1705             msg.avg_pkt_size = strtoul(val_p, &endptr, 0);
1706         } else if (strcmp(param, "-avg_pkt_num") == 0) {
1707             msg.avg_pkt_num = strtoul(val_p, &endptr, 0);
1708         } else if (strcmp(param, "-wake_time_off_us") == 0) {
1709             msg.wake_time_off_us = strtoul(val_p, &endptr, 0);
1710         } else {
1711             printMsg("%s:Unsupported Parameter for twt setup request\n", __FUNCTION__);
1712             ret = WIFI_ERROR_INVALID_ARGS;
1713             goto exit;
1714         }
1715     }
1716 
1717     ret = twt_init_handlers();
1718     if (ret != WIFI_SUCCESS) {
1719         printMsg("Failed to initialize twt handlers %d\n", ret);
1720         goto exit;
1721     }
1722     ret = twt_setup_request(wlan0Handle, &msg);
1723 exit:
1724     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
1725     return;
1726 }
1727 
TeardownTwt(char * argv[])1728 static void TeardownTwt(char *argv[]) {
1729     TwtTeardownRequest msg;
1730     wifi_error ret = WIFI_SUCCESS;
1731     char *param, *val_p;
1732 
1733     /* Set Default twt teardown params */
1734     memset(&msg, 0, sizeof(msg));
1735 
1736     /* Parse args for twt params */
1737     /* skip utility */
1738     argv++;
1739     /* skip command */
1740     argv++;
1741     /* skip command */
1742     argv++;
1743 
1744     while ((param = *argv++) != NULL) {
1745         val_p = *argv++;
1746         if (!val_p || *val_p == '-') {
1747             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
1748             ret = WIFI_ERROR_NOT_SUPPORTED;
1749             goto exit;
1750         }
1751         if (strcmp(param, "-config_id") == 0) {
1752             msg.config_id = atoi(val_p);
1753         } else if (strcmp(param, "-all_twt") == 0) {
1754             msg.all_twt = atoi(val_p);
1755         } else if (strcmp(param, "-neg_type") == 0) {
1756             msg.negotiation_type = atoi(val_p);
1757         } else {
1758             printMsg("%s:Unsupported Parameter for twt teardown request\n", __FUNCTION__);
1759             ret = WIFI_ERROR_INVALID_ARGS;
1760             goto exit;
1761         }
1762     }
1763 
1764     ret = twt_init_handlers();
1765     if (ret != WIFI_SUCCESS) {
1766         printMsg("Failed to initialize twt handlers %d\n", ret);
1767         goto exit;
1768     }
1769     ret = twt_teardown_request(wlan0Handle, &msg);
1770 exit:
1771     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
1772     return;
1773 }
1774 
InfoFrameTwt(char * argv[])1775 static void InfoFrameTwt(char *argv[]) {
1776     TwtInfoFrameRequest msg;
1777     wifi_error ret = WIFI_SUCCESS;
1778     char *param, *val_p;
1779 
1780     /* Set Default twt info frame params */
1781     memset(&msg, 0, sizeof(msg));
1782 
1783     /* Parse args for twt params */
1784     /* skip utility */
1785     argv++;
1786     /* skip command */
1787     argv++;
1788     /* skip command */
1789     argv++;
1790 
1791     while ((param = *argv++) != NULL) {
1792         val_p = *argv++;
1793         if (!val_p || *val_p == '-') {
1794             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
1795             ret = WIFI_ERROR_NOT_SUPPORTED;
1796             goto exit;
1797         }
1798         if (strcmp(param, "-config_id") == 0) {
1799             msg.config_id = atoi(val_p);
1800         } else if (strcmp(param, "-all_twt") == 0) {
1801             msg.all_twt = atoi(val_p);
1802         } else if (strcmp(param, "-resume_time_us") == 0) {
1803             msg.resume_time_us = atoi(val_p);
1804         } else {
1805             printMsg("%s:Unsupported Parameter for twt info request\n", __FUNCTION__);
1806             ret = WIFI_ERROR_INVALID_ARGS;
1807             goto exit;
1808         }
1809     }
1810 
1811     ret = twt_init_handlers();
1812     if (ret != WIFI_SUCCESS) {
1813         printMsg("Failed to initialize twt handlers %d\n", ret);
1814         goto exit;
1815     }
1816     ret = twt_info_frame_request(wlan0Handle, &msg);
1817 exit:
1818     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
1819     return;
1820 }
1821 
GetTwtStats(char * argv[])1822 static void GetTwtStats(char *argv[]) {
1823     wifi_error ret = WIFI_SUCCESS;
1824     char *param, *val_p;
1825     u8 config_id = 1;
1826     TwtStats twt_stats;
1827 
1828     /* Parse args for twt params */
1829     /* skip utility */
1830     argv++;
1831     /* skip command */
1832     argv++;
1833     /* skip command */
1834     argv++;
1835 
1836     while ((param = *argv++) != NULL) {
1837         val_p = *argv++;
1838         if (!val_p || *val_p == '-') {
1839             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
1840             ret = WIFI_ERROR_NOT_SUPPORTED;
1841             goto exit;
1842         }
1843         if (strcmp(param, "-config_id") == 0) {
1844             config_id = atoi(val_p);
1845         } else {
1846             printMsg("%s:Unsupported Parameter for get stats request\n", __FUNCTION__);
1847             ret = WIFI_ERROR_INVALID_ARGS;
1848             goto exit;
1849         }
1850     }
1851 
1852     memset(&twt_stats, 0, sizeof(twt_stats));
1853     ret = twt_get_stats(wlan0Handle, config_id, &twt_stats);
1854     if (ret == WIFI_SUCCESS) {
1855         printMsg("TWT stats :\n");
1856         if (twt_stats.config_id)
1857             printMsg("config id = %d\n", twt_stats.config_id);
1858         if (twt_stats.avg_pkt_num_tx)
1859             printMsg("avg_pkt_num_tx = %d\n", twt_stats.avg_pkt_num_tx);
1860         if (twt_stats.avg_pkt_num_rx)
1861             printMsg("avg_pkt_num_rx = %d\n", twt_stats.avg_pkt_num_rx);
1862         if (twt_stats.avg_tx_pkt_size)
1863             printMsg("avg_tx_pkt_size = %d\n", twt_stats.avg_tx_pkt_size);
1864         if (twt_stats.avg_rx_pkt_size)
1865             printMsg("avg_rx_pkt_size = %d\n", twt_stats.avg_rx_pkt_size);
1866         if (twt_stats.avg_eosp_dur_us)
1867             printMsg("avg_eosp_dur_us = %d\n", twt_stats.avg_eosp_dur_us);
1868         if (twt_stats.eosp_count)
1869             printMsg("eosp_count = %d\n", twt_stats.eosp_count);
1870 
1871         return;
1872     }
1873 exit:
1874     printMsg("Could not get the twt stats : err %d\n", ret);
1875     return;
1876 }
1877 
ClearTwtStats(char * argv[])1878 void ClearTwtStats(char *argv[]) {
1879     wifi_error ret = WIFI_SUCCESS;
1880     char *param, *val_p;
1881     u8 config_id = 1;
1882 
1883     /* Parse args for twt params */
1884     /* skip utility */
1885     argv++;
1886     /* skip command */
1887     argv++;
1888     /* skip command */
1889     argv++;
1890 
1891     while ((param = *argv++) != NULL) {
1892         val_p = *argv++;
1893         if (!val_p || *val_p == '-') {
1894             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
1895             ret = WIFI_ERROR_NOT_SUPPORTED;
1896             goto exit;
1897         }
1898         if (strcmp(param, "-config_id") == 0) {
1899             config_id = atoi(val_p);
1900         } else {
1901             printMsg("%s:Unsupported Parameter for twt info request\n", __FUNCTION__);
1902             ret = WIFI_ERROR_INVALID_ARGS;
1903             goto exit;
1904         }
1905     }
1906 
1907     ret = twt_init_handlers();
1908     if (ret != WIFI_SUCCESS) {
1909         printMsg("Failed to initialize twt handlers %d\n", ret);
1910         goto exit;
1911     }
1912     ret = twt_clear_stats(wlan0Handle, config_id);
1913 exit:
1914     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
1915     return;
1916 }
1917 
getTWTCapability()1918 static void getTWTCapability() {
1919     int ret;
1920     TwtCapabilitySet twt_capability;
1921 
1922     ret = twt_get_capability(wlan0Handle, &twt_capability);
1923     if (ret == WIFI_SUCCESS) {
1924         printMsg("Supported Capabilites of TWT :\n");
1925         if (twt_capability.device_capability.requester_supported)
1926             printMsg("Device Requester supported\n");
1927         if (twt_capability.device_capability.responder_supported)
1928             printMsg("Device Responder supported\n");
1929         if (twt_capability.device_capability.broadcast_twt_supported)
1930             printMsg("Device Broadcast twt supported\n");
1931         if (twt_capability.device_capability.flexibile_twt_supported)
1932             printMsg("Device Flexibile twt supported\n");
1933         if (twt_capability.peer_capability.requester_supported)
1934             printMsg("Peer Requester supported\n");
1935         if (twt_capability.peer_capability.responder_supported)
1936             printMsg("Peer Responder supported\n");
1937         if (twt_capability.peer_capability.broadcast_twt_supported)
1938             printMsg("Peer Broadcast twt supported\n");
1939         if (twt_capability.peer_capability.flexibile_twt_supported)
1940             printMsg("Peer Flexibile twt supported\n");
1941     } else {
1942         printMsg("Could not get the twt capabilities : %d\n", ret);
1943     }
1944     return;
1945 }
1946 
showResponderCapability(wifi_rtt_responder responder_info)1947 static void showResponderCapability(wifi_rtt_responder responder_info)
1948 {
1949     wifi_channel_info channel_info;
1950     channel_info = responder_info.channel;
1951     printMsg("Centre freq = %d \n",channel_info.center_freq);
1952     if (channel_info.width == WIFI_CHAN_WIDTH_20) {
1953         printMsg("channel width = 20 \n");
1954     } else if (channel_info.width == WIFI_CHAN_WIDTH_40) {
1955         printMsg("channel width = 40 \n");
1956     } else if (channel_info.width == WIFI_CHAN_WIDTH_80) {
1957         printMsg("channel width = 80 \n");
1958     }
1959     if (channel_info.width == WIFI_CHAN_WIDTH_40 || channel_info.width == WIFI_CHAN_WIDTH_80) {
1960         printMsg("CentreFreq0 = %d \n",channel_info.center_freq0);
1961     }
1962     if (responder_info.preamble & WIFI_RTT_PREAMBLE_HT) {
1963         printMsg("Responder preamble = %d \n",responder_info.preamble);
1964     }
1965     if (responder_info.preamble & WIFI_RTT_PREAMBLE_VHT) {
1966         printMsg("Responder preamble = %d \n",responder_info.preamble);
1967     }
1968     if (responder_info.preamble & WIFI_RTT_PREAMBLE_LEGACY) {
1969         printMsg("Responder preamble = %d \n",responder_info.preamble);
1970     }
1971 }
1972 
getRttResponderInfo()1973 static int getRttResponderInfo()
1974 {
1975     int ret;
1976     wifi_rtt_responder responder_info;
1977     ret = hal_fn.wifi_rtt_get_responder_info(wlan0Handle, &responder_info);
1978     if (ret == WIFI_SUCCESS) {
1979         showResponderCapability(responder_info);
1980     }
1981     return ret;
1982 }
1983 
RttEnableResponder()1984 static int RttEnableResponder()
1985 {
1986     int ret = 0;
1987     wifi_request_id id = 0;
1988     wifi_channel_info channel_hint;
1989     memset(&channel_hint, 0, sizeof(wifi_channel_info));
1990     wifi_rtt_responder responder_info;
1991     unsigned int max_duration_sec = 0;
1992 
1993     ret = hal_fn.wifi_enable_responder(id, wlan0Handle, channel_hint,
1994         max_duration_sec, &responder_info);
1995     if (ret == WIFI_SUCCESS) {
1996         showResponderCapability(responder_info);
1997     }
1998     return ret;
1999 }
2000 
cancelRttResponder()2001 static int cancelRttResponder()
2002 {
2003     int ret = 0;
2004     wifi_request_id id = 0;
2005 
2006     ret = hal_fn.wifi_disable_responder(id, wlan0Handle);
2007     return ret;
2008 }
2009 
2010 /* CHRA NAN RTT related */
OnChreNanRttStateChanged(chre_nan_rtt_state state)2011 static void OnChreNanRttStateChanged(chre_nan_rtt_state state) {
2012     printMsg("CHRE NAN RTT state update : %d\n", state);
2013     putEventInCache(EVENT_TYPE_CHRE_NAN_RTT_STATE_UPDATED, "CHRE NAN RTT state updated");
2014 }
2015 
enableChreNanRtt()2016 static void enableChreNanRtt() {
2017     wifi_error ret = WIFI_SUCCESS;
2018     ret = hal_fn.wifi_nan_rtt_chre_enable_request(0, wlan0Handle, NULL);
2019     if (ret != WIFI_SUCCESS) {
2020         printMsg("Failed to enable CHRE NAN RTT: %d\n", ret);
2021     }
2022 
2023     return;
2024 }
2025 
disableChreNanRtt()2026 static void disableChreNanRtt() {
2027     wifi_error ret = WIFI_SUCCESS;
2028     ret = hal_fn.wifi_nan_rtt_chre_disable_request(0, wlan0Handle);
2029     if (ret != WIFI_SUCCESS) {
2030         printMsg("Failed to disable CHRE NAN RTT: %d\n", ret);
2031     }
2032 
2033     return;
2034 }
2035 
registerChreCallback()2036 static void registerChreCallback() {
2037     wifi_error ret = WIFI_SUCCESS;
2038     EventInfo info;
2039     wifi_chre_handler handler;
2040     handler.on_chre_nan_rtt_change = OnChreNanRttStateChanged;
2041     ret = hal_fn.wifi_chre_register_handler(wlan0Handle, handler);
2042     if (ret != WIFI_SUCCESS) {
2043         printMsg("Failed to register CHRE callback: %d\n", ret);
2044     } else {
2045         while (true) {
2046             memset(&info, 0, sizeof(info));
2047             getEventFromCache(info);
2048             if (info.type == EVENT_TYPE_CHRE_NAN_RTT_STATE_UPDATED) {
2049                 printMsg("Received CHRE NAN RTT state, end the CHRE NAN RTT monitor!!\n");
2050                 break;
2051             }
2052         }
2053     }
2054     return;
2055 }
2056 
printCachedScanResults(wifi_cached_scan_report * cache_report)2057 static void printCachedScanResults(wifi_cached_scan_report *cache_report) {
2058     int scanned_channel[MAX_CH_BUF_SIZE] = {0};
2059     wifi_cached_scan_result cached_results[MAX_CACHED_SCAN_RESULT];
2060     memset(&cached_results, 0, sizeof(cached_results));
2061 
2062     if (cache_report->ts) {
2063         printMsg("Printing scan results were queried at (%lu) (in microseconds):\n",
2064             cache_report->ts);
2065     }
2066     printMsg("--------------------------------------\n");
2067     if (cache_report->scanned_freq_num > MAX_CH_BUF_SIZE ) {
2068         cache_report->scanned_freq_num = MAX_CH_BUF_SIZE;
2069     }
2070 
2071     if (cache_report->scanned_freq_num && cache_report->scanned_freq_list) {
2072         memcpy(scanned_channel, cache_report->scanned_freq_list,
2073             cache_report->scanned_freq_num * sizeof(u32));
2074     }
2075 
2076     if (cache_report->result_cnt > MAX_CACHED_SCAN_RESULT) {
2077          cache_report->result_cnt = MAX_CACHED_SCAN_RESULT;
2078     }
2079 
2080     if (cache_report->result_cnt && cache_report->results) {
2081         memcpy(cached_results, cache_report->results,
2082            cache_report->result_cnt * sizeof(wifi_cached_scan_result));
2083     }
2084 
2085     printMsg("(%d) channels were scanned:\n", cache_report->scanned_freq_num);
2086     for (int i = 0; i < cache_report->scanned_freq_num; i++) {
2087          printMsg("%d, ", scanned_channel[i]);
2088     }
2089     printMsg("\n");
2090     printMsg("(%d) results reported:\n", cache_report->result_cnt);
2091     for (int i = 0; i < cache_report->result_cnt; i++) {
2092         printMsg("ssid:%s,bssid: %02x:%02x:%02x:%02x:%02x:%02x,"
2093                 "rssi: %d, primary_freq: %d, bw: %d, capability: 0x%x,"
2094                 "flags: 0x%x, age_ms: %d\n",
2095                 cached_results[i].ssid,
2096                 cached_results[i].bssid[0], cached_results[i].bssid[1],
2097                 cached_results[i].bssid[2], cached_results[i].bssid[3],
2098                 cached_results[i].bssid[4], cached_results[i].bssid[5],
2099                 cached_results[i].rssi,
2100                 cached_results[i].chanspec.primary_frequency,
2101                 cached_results[i].chanspec.width,
2102                 cached_results[i].capability, cached_results[i].flags,
2103                 cached_results[i].age_ms);
2104     }
2105 }
2106 
on_cached_scan_results(wifi_cached_scan_report * cache_report)2107 static void on_cached_scan_results(wifi_cached_scan_report *cache_report) {
2108     if (!cache_report) {
2109         printf("Scan results not found! Issue scan first\n");
2110         return;
2111     }
2112 
2113     printf("onCachedScanResult scanned_freq_num = %d result_cnt %d \n",
2114             cache_report->scanned_freq_num, cache_report->result_cnt);
2115     printCachedScanResults(cache_report);
2116 }
2117 
getWifiCachedScanResults(void)2118 static void getWifiCachedScanResults(void) {
2119     wifi_cached_scan_result_handler handler;
2120     handler.on_cached_scan_results = on_cached_scan_results;
2121 
2122     wifi_error ret = hal_fn.wifi_get_cached_scan_results(wlan0Handle, handler);
2123     if (ret != WIFI_SUCCESS) {
2124         printMsg("Failed to get cached scan results: %d\n", ret);
2125     }
2126     return;
2127 }
2128 
GetCachedGScanResults(int max,wifi_scan_result * results,int * num)2129 static int GetCachedGScanResults(int max, wifi_scan_result *results, int *num)
2130 {
2131     int num_results = 64;
2132     wifi_cached_scan_results *results2;
2133     results2 = (wifi_cached_scan_results *)malloc(num_results * sizeof(wifi_cached_scan_results));
2134     memset(results2, 0, sizeof(wifi_cached_scan_results) * num_results);
2135     int ret = hal_fn.wifi_get_cached_gscan_results(wlan0Handle, 1, num_results, results2,
2136         &num_results);
2137     if (ret < 0) {
2138         printMsg("failed to fetch scan results : %d\n", ret);
2139         goto exit;
2140     } else {
2141         printMsg("fetched %d scan data\n", num_results);
2142     }
2143 
2144     *num = 0;
2145     for (int i = 0; i < num_results; i++) {
2146         for (int j = 0; j < results2[i].num_results; j++, (*num)++) {
2147             memcpy(&(results[*num]), &(results2[i].results[j]), sizeof(wifi_scan_result));
2148         }
2149     }
2150 
2151 exit:
2152     if (results2) {
2153         free(results2);
2154     }
2155     return ret;
2156 }
2157 
2158 
setHotlistAPsUsingScanResult(wifi_bssid_hotlist_params * params)2159 static wifi_error setHotlistAPsUsingScanResult(wifi_bssid_hotlist_params *params)
2160 {
2161     printMsg("testHotlistAPs Scan started, waiting for event ...\n");
2162     EventInfo info;
2163     memset(&info, 0, sizeof(info));
2164     getEventFromCache(info);
2165 
2166     wifi_scan_result *results;
2167     results = (wifi_scan_result *)malloc(256 * sizeof(wifi_scan_result));
2168     memset(results, 0, sizeof(wifi_scan_result) * 256);
2169 
2170     printMsg("Retrieving scan results for Hotlist AP setting\n");
2171     int num_results = 256;
2172     int result = GetCachedGScanResults(num_results, results, &num_results);
2173     if (result < 0) {
2174         printMsg("failed to fetch scan results : %d\n", result);
2175         if (results) {
2176             free(results);
2177         }
2178         return WIFI_ERROR_UNKNOWN;
2179     } else {
2180         printMsg("fetched %d scan results\n", num_results);
2181     }
2182 
2183     for (int i = 0; i < num_results; i++) {
2184         printScanResult(results[i]);
2185     }
2186 
2187     for (int i = 0; i < stest_max_ap; i++) {
2188         memcpy(params->ap[i].bssid, results[i].bssid, sizeof(mac_addr));
2189         params->ap[i].low  = -htest_low_threshold;
2190         params->ap[i].high = -htest_high_threshold;
2191     }
2192     params->num_bssid = stest_max_ap;
2193 
2194     if (results) {
2195         free(results);
2196     }
2197 
2198     return WIFI_SUCCESS;
2199 }
2200 
setHotlistAPs()2201 static wifi_error setHotlistAPs() {
2202     wifi_bssid_hotlist_params params;
2203     memset(&params, 0, sizeof(params));
2204 
2205     params.lost_ap_sample_size = HOTLIST_LOST_WINDOW;
2206     if (num_hotlist_bssids > 0) {
2207         for (int i = 0; i < num_hotlist_bssids; i++) {
2208             memcpy(params.ap[i].bssid, hotlist_bssids[i], sizeof(mac_addr));
2209             params.ap[i].low  = -htest_low_threshold;
2210             params.ap[i].high = -htest_high_threshold;
2211         }
2212         params.num_bssid = num_hotlist_bssids;
2213     } else {
2214         setHotlistAPsUsingScanResult(&params);
2215     }
2216 
2217     printMsg("BSSID\t\t\tHIGH\tLOW\n");
2218     for (int i = 0; i < params.num_bssid; i++) {
2219         mac_addr &addr = params.ap[i].bssid;
2220         printMsg("%02x:%02x:%02x:%02x:%02x:%02x\t%d\t%d\n", addr[0],
2221                 addr[1], addr[2], addr[3], addr[4], addr[5],
2222                 params.ap[i].high, params.ap[i].low);
2223     }
2224 
2225     wifi_hotlist_ap_found_handler handler;
2226     handler.on_hotlist_ap_found = &onHotlistAPFound;
2227     handler.on_hotlist_ap_lost = &onHotlistAPLost;
2228     hotlistCmdId = getNewCmdId();
2229     printMsg("Setting hotlist APs threshold\n");
2230     return hal_fn.wifi_set_bssid_hotlist(hotlistCmdId, wlan0Handle, params, handler);
2231 }
2232 
resetHotlistAPs()2233 static void resetHotlistAPs() {
2234     printMsg(", stoping Hotlist AP scanning\n");
2235     hal_fn.wifi_reset_bssid_hotlist(hotlistCmdId, wlan0Handle);
2236 }
2237 
setPnoMacOui()2238 static void setPnoMacOui() {
2239     hal_fn.wifi_set_scanning_mac_oui(wlan0Handle, mac_oui);
2240 }
2241 
testHotlistAPs()2242 static void testHotlistAPs(){
2243 
2244     EventInfo info;
2245     memset(&info, 0, sizeof(info));
2246 
2247     printMsg("starting Hotlist AP scanning\n");
2248     bool startScanResult = startScan(stest_max_ap,
2249             stest_base_period, stest_threshold_percent, stest_threshold_num_scans);
2250     if (!startScanResult) {
2251         printMsg("testHotlistAPs failed to start scan!!\n");
2252         return;
2253     }
2254 
2255     int result = setHotlistAPs();
2256     if (result == WIFI_SUCCESS) {
2257         printMsg("Waiting for Hotlist AP event\n");
2258         while (true) {
2259             memset(&info, 0, sizeof(info));
2260             getEventFromCache(info);
2261 
2262             if (info.type == EVENT_TYPE_SCAN_COMPLETE) {
2263                 retrieveScanResults();
2264             } else if (info.type == EVENT_TYPE_HOTLIST_AP_FOUND ||
2265                     info.type == EVENT_TYPE_HOTLIST_AP_LOST) {
2266                 printMsg("Hotlist APs");
2267                 if (--max_event_wait > 0)
2268                     printMsg(", waiting for more event ::%d\n", max_event_wait);
2269                 else
2270                     break;
2271             }
2272         }
2273         resetHotlistAPs();
2274     } else {
2275         printMsg("Could not set AP hotlist : %d\n", result);
2276     }
2277 }
2278 
testPNO(bool clearOnly,bool scan)2279 static void testPNO(bool clearOnly, bool scan){
2280 
2281     EventInfo info;
2282     int result;
2283     wifi_epno_handler handler;
2284     handler.on_network_found = &onePnoSsidFound;
2285     memset(&info, 0, sizeof(info));
2286     if (clearOnly) {
2287         result = wifi_reset_epno_list(-1, wlan0Handle);
2288         if (result != WIFI_SUCCESS) {
2289             printMsg("Failed to reset ePNO!!\n");
2290         }
2291         return;
2292     }
2293     epnoCmdId = getNewCmdId();
2294     printMsg("configuring ePNO SSIDs num %u\n", epno_cfg.num_networks);
2295     result = hal_fn.wifi_set_epno_list(epnoCmdId, wlan0Handle, &epno_cfg, handler);
2296     if (result == WIFI_SUCCESS && scan) {
2297         bool startScanResult = startScan(stest_max_ap,
2298             stest_base_period, stest_threshold_percent, stest_threshold_num_scans);
2299         if (!startScanResult) {
2300             printMsg("testPNO failed to start scan!!\n");
2301             return;
2302         }
2303         printMsg("Waiting for ePNO events\n");
2304         while (true) {
2305             memset(&info, 0, sizeof(info));
2306             getEventFromCache(info);
2307 
2308             if (info.type == EVENT_TYPE_SCAN_COMPLETE) {
2309                 retrieveScanResults();
2310             } else if (info.type == EVENT_TYPE_EPNO_SSID) {
2311                 printMsg("FOUND ePNO event");
2312                 if (--max_event_wait > 0)
2313                   printMsg(", waiting for more event ::%d\n", max_event_wait);
2314                 else
2315                   break;
2316             }
2317         }
2318         //wifi_reset_epno_list(epnoCmdId, wlan0Handle);
2319     } else if (result != WIFI_SUCCESS) {
2320         printMsg("Could not set ePNO : %d\n", result);
2321     }
2322 }
2323 
onSignificantWifiChange(wifi_request_id id,unsigned num_results,wifi_significant_change_result ** results)2324 static void onSignificantWifiChange(wifi_request_id id,
2325         unsigned num_results, wifi_significant_change_result **results)
2326 {
2327     printMsg("Significant wifi change for %d\n", num_results);
2328     for (unsigned i = 0; i < num_results; i++) {
2329         printSignificantChangeResult(results[i]);
2330     }
2331     putEventInCache(EVENT_TYPE_SIGNIFICANT_WIFI_CHANGE, "significant wifi change noticed");
2332 }
2333 
SelectSignificantAPsFromScanResults()2334 static int SelectSignificantAPsFromScanResults() {
2335     wifi_scan_result *results;
2336     results = (wifi_scan_result *)malloc(256 * sizeof(wifi_scan_result));
2337     memset(results, 0, sizeof(wifi_scan_result) * 256);
2338     printMsg("Retrieving scan results for significant wifi change setting\n");
2339     int num_results = 256;
2340     int result = GetCachedGScanResults(num_results, results, &num_results);
2341     if (result < 0) {
2342         printMsg("failed to fetch scan results : %d\n", result);
2343         if (results) {
2344             free(results);
2345         }
2346         return WIFI_ERROR_UNKNOWN;
2347     } else {
2348         printMsg("fetched %d scan results\n", num_results);
2349     }
2350 
2351     for (int i = 0; i < num_results; i++) {
2352         printScanResult(results[i]);
2353     }
2354 
2355     wifi_significant_change_params params;
2356     memset(&params, 0, sizeof(params));
2357 
2358     params.rssi_sample_size = swctest_rssi_sample_size;
2359     params.lost_ap_sample_size = swctest_rssi_lost_ap;
2360     params.min_breaching = swctest_rssi_min_breaching;
2361 
2362     for (int i = 0; i < stest_max_ap; i++) {
2363         memcpy(params.ap[i].bssid, results[i].bssid, sizeof(mac_addr));
2364         params.ap[i].low  = results[i].rssi - swctest_rssi_ch_threshold;
2365         params.ap[i].high = results[i].rssi + swctest_rssi_ch_threshold;
2366     }
2367     params.num_bssid = stest_max_ap;
2368 
2369     printMsg("Settting Significant change params rssi_sample_size#%d lost_ap_sample_size#%d"
2370             " and min_breaching#%d\n", params.rssi_sample_size,
2371             params.lost_ap_sample_size , params.min_breaching);
2372     printMsg("BSSID\t\t\tHIGH\tLOW\n");
2373     for (int i = 0; i < params.num_bssid; i++) {
2374         mac_addr &addr = params.ap[i].bssid;
2375         printMsg("%02x:%02x:%02x:%02x:%02x:%02x\t%d\t%d\n", addr[0],
2376                 addr[1], addr[2], addr[3], addr[4], addr[5],
2377                 params.ap[i].high, params.ap[i].low);
2378     }
2379     wifi_significant_change_handler handler;
2380     memset(&handler, 0, sizeof(handler));
2381     handler.on_significant_change = &onSignificantWifiChange;
2382 
2383     int id = getNewCmdId();
2384     if (results) {
2385         free(results);
2386     }
2387     return hal_fn.wifi_set_significant_change_handler(id, wlan0Handle, params, handler);
2388 
2389 }
2390 
untrackSignificantChange()2391 static void untrackSignificantChange() {
2392     printMsg(", Stop tracking SignificantChange\n");
2393     hal_fn.wifi_reset_bssid_hotlist(hotlistCmdId, wlan0Handle);
2394 }
2395 
trackSignificantChange()2396 static void trackSignificantChange() {
2397     printMsg("starting trackSignificantChange\n");
2398 
2399     if (!startScan(stest_max_ap,
2400                 stest_base_period, stest_threshold_percent, stest_threshold_num_scans)) {
2401         printMsg("trackSignificantChange failed to start scan!!\n");
2402         return;
2403     } else {
2404         printMsg("trackSignificantChange Scan started, waiting for event ...\n");
2405     }
2406 
2407     EventInfo info;
2408     memset(&info, 0, sizeof(info));
2409     getEventFromCache(info);
2410 
2411     int result = SelectSignificantAPsFromScanResults();
2412     if (result == WIFI_SUCCESS) {
2413         printMsg("Waiting for significant wifi change event\n");
2414         while (true) {
2415             memset(&info, 0, sizeof(info));
2416             getEventFromCache(info);
2417 
2418             if (info.type == EVENT_TYPE_SCAN_COMPLETE) {
2419                 retrieveScanResults();
2420             } else if(info.type == EVENT_TYPE_SIGNIFICANT_WIFI_CHANGE) {
2421                 printMsg("Received significant wifi change");
2422                 if (--max_event_wait > 0)
2423                     printMsg(", waiting for more event ::%d\n", max_event_wait);
2424                 else
2425                     break;
2426             }
2427         }
2428         untrackSignificantChange();
2429     } else {
2430         printMsg("Failed to set significant change  ::%d\n", result);
2431     }
2432 }
2433 
2434 
testScan()2435 void testScan() {
2436     printf("starting scan with max_ap_per_scan#%d  base_period#%d  threshold#%d \n",
2437             stest_max_ap,stest_base_period, stest_threshold_percent);
2438     if (!startScan(stest_max_ap,
2439                 stest_base_period, stest_threshold_percent, stest_threshold_num_scans)) {
2440         printMsg("failed to start scan!!\n");
2441         return;
2442     } else {
2443         EventInfo info;
2444         memset(&info, 0, sizeof(info));
2445 
2446         while (true) {
2447             getEventFromCache(info);
2448             printMsg("retrieved event %d : %s\n", info.type, info.buf);
2449             if (info.type == EVENT_TYPE_SCAN_COMPLETE)
2450                 continue;
2451             retrieveScanResults();
2452             if(--max_event_wait > 0)
2453                 printMsg("Waiting for more :: %d event \n", max_event_wait);
2454             else
2455                 break;
2456         }
2457 
2458         stopScan();
2459         printMsg("stopped scan\n");
2460     }
2461 }
2462 
testStopScan()2463 void testStopScan() {
2464     stopScan();
2465     printMsg("stopped scan\n");
2466 }
2467 
2468 
2469 ///////////////////////////////////////////////////////////////////////////////
2470 // Logger feature set
2471 
onRingBufferData(char * ring_name,char * buffer,int buffer_size,wifi_ring_buffer_status * status)2472 static void onRingBufferData(char *ring_name, char *buffer, int buffer_size,
2473                                 wifi_ring_buffer_status *status)
2474 {
2475     // helper for LogHandler
2476 
2477     static int cnt = 1;
2478     FILE* w_fp;
2479     static int f_count = 0;
2480     char ring_file[FILE_NAME_LEN];
2481     char *pBuff;
2482 
2483     if (!buffer || buffer_size <= 0) {
2484         printMsg("No data in dump buffer\n");
2485         return;
2486     }
2487 
2488     printMsg("\n%d) RingId=%d, Name=%s, Flags=%u, DebugLevel=%u, "
2489             "wBytes=%u, rBytes=%u, RingSize=%u, wRecords=%u\n",
2490             cnt++, status->ring_id, status->name, status->flags,
2491             status->verbose_level, status->written_bytes,
2492             status->read_bytes, status->ring_buffer_byte_size,
2493             status->written_records);
2494 
2495     wifi_ring_buffer_entry *buffer_entry = (wifi_ring_buffer_entry *) buffer;
2496 
2497     printMsg("Format: (%d) ", buffer_entry->flags);
2498     if (buffer_entry->flags & RING_BUFFER_ENTRY_FLAGS_HAS_BINARY)
2499         printMsg("\"BINARY\" ");
2500     if (buffer_entry->flags & RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP)
2501         printMsg("\"TIMESTAMP\"");
2502 
2503     printMsg(", Type: %s (%d)", RBentryTypeToString(buffer_entry->type), buffer_entry->type);
2504     printMsg(", TS: %llu ms", buffer_entry->timestamp);
2505     printMsg(", Size: %d bytes\n", buffer_entry->entry_size);
2506 
2507     pBuff = (char *) (buffer_entry + 1);
2508     snprintf(ring_file, FILE_NAME_LEN, "%s%s-%d.bin", RINGDATA_PREFIX, ring_name, f_count);
2509     w_fp = fopen(ring_file, "a");
2510     if (w_fp == NULL) {
2511         printMsg("Failed to open a file: %s\n", ring_file);
2512         return;
2513     }
2514 
2515     fwrite(pBuff, 1, buffer_entry->entry_size, w_fp);
2516     if (ftell(w_fp) >= FILE_MAX_SIZE) {
2517         f_count++;
2518         if (f_count >= NUM_ALERT_DUMPS)
2519             f_count = 0;
2520     }
2521     fclose(w_fp);
2522     w_fp = NULL;
2523 
2524     printMsg("Data: ");
2525     if (buffer_entry->flags & RING_BUFFER_ENTRY_FLAGS_HAS_BINARY) {
2526         for (int i = 0; i < buffer_size; i++)
2527             printMsg("%02x ", buffer[i]);
2528         printMsg("\n");
2529     } else {
2530         printMsg("%s\n", pBuff);
2531     }
2532 
2533     /*
2534      * Parsing Wake Lock event
2535      */
2536     if (buffer_entry->type == ENTRY_TYPE_WAKE_LOCK) {
2537         const char *strStatus[] = {"Taken", "Released", "Timeout"};
2538         wake_lock_event *wlock_event = (wake_lock_event *) pBuff;
2539 
2540         printMsg("Wakelock Event: Status=%s (%02x), Name=%s, Reason=%s (%02x)\n",
2541             strStatus[wlock_event->status], wlock_event->status,
2542             wlock_event->name, "\"TO BE\"", wlock_event->reason);
2543         return;
2544     }
2545 
2546     /*
2547      * Parsing TLV data
2548      */
2549     if (buffer_entry->type == ENTRY_TYPE_CONNECT_EVENT) {
2550         wifi_ring_buffer_driver_connectivity_event *connect_event =
2551             (wifi_ring_buffer_driver_connectivity_event *) (pBuff);
2552 
2553         tlv_log *tlv_data = (tlv_log *) (connect_event + 1);
2554         printMsg("Event type: %s (%u)\n", RBconnectEventToString(connect_event->event),
2555                 connect_event->event);
2556 
2557         char *pos = (char *)tlv_data;
2558         char *end = (char *)connect_event + buffer_entry->entry_size;
2559         while (pos < end) {
2560             printMsg("TLV.type: %s (%d), TLV.len=%d (%02x)\n",
2561                     RBTlvTagToString(tlv_data->tag),
2562                     tlv_data->tag, tlv_data->length, tlv_data->length);
2563 
2564             switch (tlv_data->tag) {
2565                 case WIFI_TAG_VENDOR_SPECIFIC:
2566                     break;
2567 
2568                 case WIFI_TAG_BSSID:
2569                 case WIFI_TAG_ADDR:
2570                 case WIFI_TAG_ADDR1:
2571                 case WIFI_TAG_ADDR2:
2572                 case WIFI_TAG_ADDR3:
2573                 case WIFI_TAG_ADDR4:
2574                 {
2575                     if (tlv_data->length == sizeof(mac_addr)) {
2576                         mac_addr addr;
2577                         memcpy(&addr, tlv_data->value, sizeof(mac_addr));
2578                         printMsg("Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
2579                             addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
2580                     } else
2581                         printMsg("wrong lenght of address\n");
2582                     break;
2583                 }
2584 
2585                 case WIFI_TAG_SSID:
2586                 {
2587                     char ssid[MAX_SSID_LEN];
2588                     memset(ssid, 0, sizeof(ssid));
2589                     if (tlv_data->length > MAX_SSID_LEN)
2590                         tlv_data->length = MAX_SSID_LEN;
2591                     memcpy(ssid, tlv_data->value, tlv_data->length);
2592                     printMsg("SSID = %s\n", ssid);
2593                     break;
2594                 }
2595 
2596                 case WIFI_TAG_STATUS:
2597                 {
2598                     unsigned int tag_status = 0;
2599                     memcpy(&tag_status, tlv_data->value, tlv_data->length);
2600                     printMsg("tag_Status = %u\n", tag_status);
2601                     break;
2602                 }
2603 
2604                 case WIFI_TAG_CHANNEL_SPEC:
2605                 {
2606                     wifi_channel_info *ch_spec = (wifi_channel_info *) tlv_data->value;
2607                     printMsg("Channel Info: center_freq=%d, freq0=%d, freq1=%d, width=%s (%d)\n",
2608                         RBchanWidthToString(ch_spec->width), ch_spec->center_freq,
2609                         ch_spec->center_freq0, ch_spec->center_freq1);
2610                     break;
2611                 }
2612 
2613                 case WIFI_TAG_WAKE_LOCK_EVENT:
2614                 {
2615                     printMsg("Wake lock event = \"TO BE DONE LATER\"\n", tlv_data->value);
2616                     break;
2617                 }
2618 
2619                 case WIFI_TAG_TSF:
2620                 {
2621                     u64 tsf = 0;
2622                     memcpy(&tsf, tlv_data->value, tlv_data->length);
2623                     printMsg("TSF value = %d\n", tsf);
2624                     break;
2625                 }
2626 
2627                 case WIFI_TAG_IE:
2628                 {
2629                     printMsg("Information Element = \"TO BE\"\n");
2630                     break;
2631                 }
2632 
2633                 case WIFI_TAG_INTERFACE:
2634                 {
2635                     const int len = 32;
2636                     char inf_name[len];
2637 
2638                     if (tlv_data->length > len)
2639                         tlv_data->length = len;
2640                     memset(inf_name, 0, 32);
2641                     memcpy(inf_name, tlv_data->value, tlv_data->length);
2642                     printMsg("Interface = %s\n", inf_name);
2643                     break;
2644                 }
2645 
2646                 case WIFI_TAG_REASON_CODE:
2647                 {
2648                     u16 reason = 0;
2649                     memcpy(&reason, tlv_data->value, 2);
2650                     printMsg("Reason code = %d\n", reason);
2651                     break;
2652                 }
2653 
2654                 case WIFI_TAG_RATE_MBPS:
2655                 {
2656                     u32 rate = 0;
2657                     memcpy(&rate, tlv_data->value, tlv_data->length);
2658                     printMsg("Rate = %.1f Mbps\n", rate * 0.5);    // rate unit is 500 Kbps.
2659                     break;
2660                 }
2661 
2662                 case WIFI_TAG_CHANNEL:
2663                 {
2664                     u16 channel = 0;
2665                     memcpy(&channel, tlv_data->value, tlv_data->length);
2666                     printMsg("Channel = %d\n", channel);
2667                     break;
2668                 }
2669 
2670                 case WIFI_TAG_RSSI:
2671                 {
2672                     short rssi = 0;
2673                     memcpy(&rssi, tlv_data->value, tlv_data->length);
2674                     printMsg("RSSI = %d\n", rssi);
2675                     break;
2676                 }
2677             }
2678             pos = (char *)(tlv_data + 1);
2679             pos += tlv_data->length;
2680             tlv_data = (tlv_log *) pos;
2681         }
2682     }
2683 }
2684 
onAlert(wifi_request_id id,char * buffer,int buffer_size,int err_code)2685 static void onAlert(wifi_request_id id, char *buffer, int buffer_size, int err_code)
2686 {
2687 
2688     // helper for AlertHandler
2689 
2690     printMsg("Getting FW Memory dump: (%d bytes), err code: %d\n", buffer_size, err_code);
2691 
2692     FILE* w_fp = NULL;
2693     static int f_count = 0;
2694     char dump_file[FILE_NAME_LEN];
2695 
2696     if (!buffer || buffer_size <= 0) {
2697         printMsg("No data in alert buffer\n");
2698         return;
2699     }
2700 
2701     snprintf(dump_file, FILE_NAME_LEN, "%s-%d.bin", ALERT_MEMDUMP_PREFIX, f_count++);
2702     if (f_count >= NUM_ALERT_DUMPS)
2703         f_count = 0;
2704 
2705     w_fp = fopen(dump_file, "w");
2706     if (w_fp == NULL) {
2707         printMsg("Failed to create a file: %s\n", dump_file);
2708         return;
2709     }
2710 
2711     printMsg("Write to \"%s\"\n", dump_file);
2712     fwrite(buffer, 1, buffer_size, w_fp);
2713     fclose(w_fp);
2714     w_fp = NULL;
2715 
2716 }
2717 
onFirmwareMemoryDump(char * buffer,int buffer_size)2718 static void onFirmwareMemoryDump(char *buffer, int buffer_size)
2719 {
2720     // helper for LoggerGetMemdump()
2721 
2722     printMsg("Getting FW Memory dump: (%d bytes)\n", buffer_size);
2723 
2724     // Write a raw dump data into default local file or specified name
2725     FILE* w_fp = NULL;
2726 
2727     if (!buffer || buffer_size <= 0) {
2728         printMsg("No data in dump buffer\n");
2729         return;
2730     }
2731 
2732     w_fp = fopen(mem_dump_file, "w");
2733     if (w_fp == NULL) {
2734         printMsg("Failed to create a file: %s\n", mem_dump_file);
2735         return;
2736     }
2737 
2738     printMsg("Write to \"%s\"\n", mem_dump_file);
2739     fwrite(buffer, 1, buffer_size, w_fp);
2740     fclose(w_fp);
2741     w_fp = NULL;
2742 
2743     putEventInCache(EVENT_TYPE_LOGGER_MEMDUMP_DATA, "Memdump data");
2744 }
2745 
LoggerStart()2746 static wifi_error LoggerStart()
2747 {
2748     int ret;
2749 
2750     ret = hal_fn.wifi_start_logging(wlan0Handle,
2751         default_logger_param.verbose_level, default_logger_param.flags,
2752         default_logger_param.max_interval_sec, default_logger_param.min_data_size,
2753         default_logger_param.ring_name);
2754 
2755     if (ret != WIFI_SUCCESS) {
2756         printMsg("Failed to start Logger: %d\n", ret);
2757         return WIFI_ERROR_UNKNOWN;
2758     }
2759 
2760     /*
2761      * debug mode (0) which means no more debug events will be triggered.
2762      *
2763      * Hopefully, need to extend this functionality by additional interfaces such as
2764      * set verbose level to each ring buffer.
2765      */
2766     return WIFI_SUCCESS;
2767 }
2768 
LoggerGetMemdump()2769 static wifi_error LoggerGetMemdump()
2770 {
2771     wifi_firmware_memory_dump_handler handler;
2772     handler.on_firmware_memory_dump = &onFirmwareMemoryDump;
2773 
2774     printMsg("Create Memdump event\n");
2775     int result = hal_fn.wifi_get_firmware_memory_dump(wlan0Handle, handler);
2776 
2777     if (result == WIFI_SUCCESS) {
2778         EventInfo info;
2779         while (true) {
2780             memset(&info, 0, sizeof(info));
2781             getEventFromCache(info);
2782             if (info.type == EVENT_TYPE_LOGGER_MEMDUMP_DATA)
2783                 break;
2784             else
2785                 printMsg("Could not get memdump data: %d\n", result);
2786         }
2787     }
2788     return WIFI_SUCCESS;
2789 }
2790 
LoggerGetRingData()2791 static wifi_error LoggerGetRingData()
2792 {
2793     int result = hal_fn.wifi_get_ring_data(wlan0Handle, default_ring_name);
2794 
2795     if (result == WIFI_SUCCESS)
2796         printMsg("Get Ring data command success\n");
2797     else
2798         printMsg("Failed to execute get ring data command\n");
2799 
2800     return WIFI_SUCCESS;
2801 }
2802 
LoggerGetFW()2803 static wifi_error LoggerGetFW()
2804 {
2805     int ret;
2806     const int BSIZE = 256;
2807     int buffer_size = BSIZE;
2808 
2809     char buffer[BSIZE];
2810     memset(buffer, 0, BSIZE);
2811 
2812     ret = hal_fn.wifi_get_firmware_version(wlan0Handle, buffer, buffer_size);
2813 
2814     if (ret == WIFI_SUCCESS)
2815         printMsg("FW version (len=%d):\n%s\n", strlen(buffer), buffer);
2816     else
2817         printMsg("Failed to get FW version\n");
2818 
2819     return WIFI_SUCCESS;
2820 }
2821 
LoggerGetDriver()2822 static wifi_error LoggerGetDriver()
2823 {
2824     int ret;
2825     const int BSIZE = 256;
2826     int buffer_size = BSIZE;
2827 
2828     char buffer[BSIZE];
2829     memset(buffer, 0, BSIZE);
2830 
2831     ret = hal_fn.wifi_get_driver_version(wlan0Handle, buffer, buffer_size);
2832 
2833     if (ret == WIFI_SUCCESS)
2834         printMsg("Driver version (len=%d):\n%s\n", strlen(buffer), buffer);
2835     else
2836         printMsg("Failed to get driver version\n");
2837 
2838     return WIFI_SUCCESS;
2839 }
2840 
LoggerGetRingbufferStatus()2841 static wifi_error LoggerGetRingbufferStatus()
2842 {
2843     int ret;
2844     const int NRING = 10;
2845     u32 num_rings = NRING;
2846 
2847     wifi_ring_buffer_status *status =
2848         (wifi_ring_buffer_status *)malloc(sizeof(wifi_ring_buffer_status) * num_rings);
2849 
2850     if (status == NULL)
2851         return WIFI_ERROR_OUT_OF_MEMORY;
2852     memset(status, 0, sizeof(wifi_ring_buffer_status) * num_rings);
2853 
2854     ret = hal_fn.wifi_get_ring_buffers_status(wlan0Handle, &num_rings, status);
2855 
2856     if (ret == WIFI_SUCCESS) {
2857         printMsg("RingBuffer status: [%d ring(s)]\n", num_rings);
2858 
2859         for (unsigned int i = 0; i < num_rings; i++) {
2860             printMsg("[%d] RingId=%d, Name=%s, Flags=%u, DebugLevel=%u, "
2861                     "wBytes=%u, rBytes=%u, RingSize=%u, wRecords=%u, status_addr=%p\n",
2862                     i+1,
2863                     status->ring_id,
2864                     status->name,
2865                     status->flags,
2866                     status->verbose_level,
2867                     status->written_bytes,
2868                     status->read_bytes,
2869                     status->ring_buffer_byte_size,
2870                     status->written_records, status);
2871             status++;
2872         }
2873     } else {
2874         printMsg("Failed to get Ringbuffer status\n");
2875     }
2876 
2877     free(status);
2878     status = NULL;
2879 
2880     return WIFI_SUCCESS;
2881 }
2882 
LoggerGetFeature()2883 static wifi_error LoggerGetFeature()
2884 {
2885     int ret;
2886     unsigned int support = 0;
2887 
2888     const char *mapFeatures[] = {
2889         "MEMORY_DUMP",
2890         "PER_PACKET_TX_RX_STATUS",
2891         "CONNECT_EVENT",
2892         "POWER_EVENT",
2893         "WAKE_LOCK",
2894         "VERBOSE",
2895         "WATCHDOG_TIMER",
2896         "DRIVER_DUMP",
2897         "PACKET_FATE"
2898     };
2899 
2900     ret = hal_fn.wifi_get_logger_supported_feature_set(wlan0Handle, &support);
2901 
2902     if (ret == WIFI_SUCCESS) {
2903         printMsg("Logger supported features: %02x  [", support);
2904 
2905         if (support & WIFI_LOGGER_MEMORY_DUMP_SUPPORTED)
2906             printMsg(" \"%s\" ", mapFeatures[0]);
2907         if (support & WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED)
2908             printMsg(" \"%s\" ", mapFeatures[1]);
2909         if (support & WIFI_LOGGER_CONNECT_EVENT_SUPPORTED)
2910             printMsg(" \"%s\" ", mapFeatures[2]);
2911         if (support & WIFI_LOGGER_POWER_EVENT_SUPPORTED)
2912             printMsg(" \"%s\" ", mapFeatures[3]);
2913         if (support & WIFI_LOGGER_WAKE_LOCK_SUPPORTED)
2914             printMsg(" \"%s\" ", mapFeatures[4]);
2915         if (support & WIFI_LOGGER_VERBOSE_SUPPORTED)
2916             printMsg(" \"%s\" ", mapFeatures[5]);
2917         if (support & WIFI_LOGGER_WATCHDOG_TIMER_SUPPORTED)
2918             printMsg(" \"%s\" ", mapFeatures[6]);
2919         if (support & WIFI_LOGGER_DRIVER_DUMP_SUPPORTED)
2920             printMsg(" \"%s\" ", mapFeatures[7]);
2921         if (support & WIFI_LOGGER_PACKET_FATE_SUPPORTED)
2922             printMsg(" \"%s\" ", mapFeatures[8]);
2923         printMsg("]\n");
2924     } else {
2925         printMsg("Failed to get Logger supported features\n");
2926     }
2927 
2928     return WIFI_SUCCESS;
2929 }
2930 
LoggerSetLogHandler()2931 static wifi_error LoggerSetLogHandler()
2932 {
2933     wifi_ring_buffer_data_handler handler;
2934     handler.on_ring_buffer_data = &onRingBufferData;
2935 
2936     printMsg("Setting log handler\n");
2937     int result = hal_fn.wifi_set_log_handler(loggerCmdId, wlan0Handle, handler);
2938 
2939     if (result == WIFI_SUCCESS) {
2940         EventInfo info;
2941         while (true) {
2942             memset(&info, 0, sizeof(info));
2943             getEventFromCache(info);
2944             if (info.type == EVENT_TYPE_LOGGER_RINGBUFFER_DATA)
2945                 break;
2946         }
2947     } else {
2948         printMsg("Failed set Log handler: %d\n", result);
2949     }
2950     return WIFI_SUCCESS;
2951 }
2952 
LoggerSetAlertHandler()2953 static wifi_error LoggerSetAlertHandler()
2954 {
2955     loggerCmdId = getNewCmdId();
2956     wifi_alert_handler handler;
2957     handler.on_alert = &onAlert;
2958 
2959     printMsg("Create alert handler\n");
2960     int result = hal_fn.wifi_set_alert_handler(loggerCmdId, wlan0Handle, handler);
2961 
2962     if (result == WIFI_SUCCESS) {
2963         EventInfo info;
2964         while (true) {
2965             memset(&info, 0, sizeof(info));
2966             getEventFromCache(info);
2967             if (info.type == EVENT_TYPE_LOGGER_ALERT_DATA)
2968                 break;
2969         }
2970     } else {
2971         printMsg("Failed set Alert handler: %d\n", result);
2972     }
2973     return WIFI_SUCCESS;
2974 }
2975 
LoggerMonitorPktFate()2976 static wifi_error LoggerMonitorPktFate()
2977 {
2978     printMsg("Start packet fate monitor \n");
2979     wifi_error result = hal_fn.wifi_start_pkt_fate_monitoring(wlan0Handle);
2980 
2981     if (result == WIFI_SUCCESS) {
2982         printMsg("Start packet fate monitor command successful\n");
2983     } else {
2984         printMsg("Start packet fate monitor command failed, err = %d\n", result);
2985     }
2986     return result;
2987 }
2988 
LoggerGetTxPktFate()2989 static wifi_error LoggerGetTxPktFate()
2990 {
2991     wifi_tx_report *tx_report, *report_ptr;
2992     size_t frame_len, n_provided_fates = 0;
2993     wifi_error result = WIFI_SUCCESS;
2994     FILE *w_fp = NULL;
2995 
2996     printMsg("Logger get tx pkt fate command\n");
2997     if (!n_requested_pkt_fate || n_requested_pkt_fate > MAX_FATE_LOG_LEN) {
2998         n_requested_pkt_fate = MAX_FATE_LOG_LEN;
2999     }
3000 
3001     tx_report = (wifi_tx_report *)malloc(n_requested_pkt_fate * sizeof(*tx_report));
3002     if (!tx_report) {
3003         printMsg("%s: Memory allocation failed\n",__FUNCTION__);
3004         return WIFI_ERROR_OUT_OF_MEMORY;
3005     }
3006     memset(tx_report, 0, n_requested_pkt_fate * sizeof(*tx_report));
3007 
3008     result = hal_fn.wifi_get_tx_pkt_fates(wlan0Handle, tx_report,
3009             n_requested_pkt_fate, &n_provided_fates);
3010     if (result != WIFI_SUCCESS) {
3011         printMsg("Logger get tx pkt fate command failed, err = %d\n", result);
3012         goto exit;
3013     }
3014 
3015     if (!n_provided_fates) {
3016         printMsg("Got empty pkt fates\n");
3017         result = WIFI_ERROR_NOT_AVAILABLE;
3018         goto exit;
3019     }
3020 
3021     printMsg("No: of tx pkt fates provided = %d\n", n_provided_fates);
3022 
3023     w_fp = fopen(tx_pkt_fate_file, "w");
3024     if (!w_fp) {
3025         printMsg("Failed to create file: %s\n", tx_pkt_fate_file);
3026         result = WIFI_ERROR_NOT_AVAILABLE;
3027         goto exit;
3028     }
3029 
3030     fprintf(w_fp, "--- BEGIN ---\n\n");
3031     fprintf(w_fp, "No: of pkt fates provided = %zd\n\n", n_provided_fates);
3032     report_ptr = tx_report;
3033     for (size_t i = 0; i < n_provided_fates; i++) {
3034         fprintf(w_fp, "--- REPORT : %zu ---\n\n", (i + 1));
3035         if (report_ptr->frame_inf.frame_len == 0 ||
3036                 report_ptr->frame_inf.payload_type == FRAME_TYPE_UNKNOWN) {
3037             fprintf(w_fp, "Invalid frame...!!!\n\n");
3038         }
3039         fprintf(w_fp, "MD5 Prefix                 :  ");
3040         fprhex(w_fp, report_ptr->md5_prefix, MD5_PREFIX_LEN, false);
3041         fprintf(w_fp, "Packet Fate                :  %d\n", report_ptr->fate);
3042         fprintf(w_fp, "Frame Type                 :  %d\n", report_ptr->frame_inf.payload_type);
3043         fprintf(w_fp, "Frame Len                  :  %zu\n", report_ptr->frame_inf.frame_len);
3044         fprintf(w_fp, "Driver Timestamp           :  %u\n",
3045             report_ptr->frame_inf.driver_timestamp_usec);
3046         fprintf(w_fp, "Firmware Timestamp         :  %u\n",
3047             report_ptr->frame_inf.firmware_timestamp_usec);
3048         if (report_ptr->frame_inf.payload_type == FRAME_TYPE_ETHERNET_II) {
3049             frame_len = min(report_ptr->frame_inf.frame_len, (size_t)MAX_FRAME_LEN_ETHERNET);
3050             fprintf(w_fp, "Frame Content (%04zu bytes) :  \n", frame_len);
3051             fprhex(w_fp, report_ptr->frame_inf.frame_content.ethernet_ii_bytes, frame_len, true);
3052         } else {
3053             frame_len = min(report_ptr->frame_inf.frame_len, (size_t)MAX_FRAME_LEN_80211_MGMT);
3054             fprintf(w_fp, "Frame Content (%04zu bytes) :  \n", frame_len);
3055             fprhex(w_fp, report_ptr->frame_inf.frame_content.ieee_80211_mgmt_bytes,
3056                 frame_len, true);
3057         }
3058         fprintf(w_fp, "\n--- END OF REPORT ---\n\n");
3059 
3060         report_ptr++;
3061     }
3062     fprintf(w_fp, "--- EOF ---\n");
3063 
3064 exit:
3065     if (w_fp) {
3066         fclose(w_fp);
3067     }
3068     if (tx_report) {
3069         free(tx_report);
3070     }
3071 
3072     return result;
3073 }
3074 
LoggerGetRxPktFate()3075 static wifi_error LoggerGetRxPktFate()
3076 {
3077     wifi_rx_report *rx_report, *report_ptr;
3078     size_t frame_len, n_provided_fates = 0;
3079     wifi_error result = WIFI_SUCCESS;
3080     FILE *w_fp = NULL;
3081 
3082     printMsg("Logger get rx pkt fate command\n");
3083     if (!n_requested_pkt_fate || n_requested_pkt_fate > MAX_FATE_LOG_LEN) {
3084         n_requested_pkt_fate = MAX_FATE_LOG_LEN;
3085     }
3086 
3087     rx_report = (wifi_rx_report *)malloc(n_requested_pkt_fate * sizeof(*rx_report));
3088     if (!rx_report) {
3089         printMsg("%s: Memory allocation failed\n",__FUNCTION__);
3090         return WIFI_ERROR_OUT_OF_MEMORY;
3091     }
3092     memset(rx_report, 0, n_requested_pkt_fate * sizeof(*rx_report));
3093 
3094     result = hal_fn.wifi_get_rx_pkt_fates(wlan0Handle, rx_report,
3095             n_requested_pkt_fate, &n_provided_fates);
3096     if (result != WIFI_SUCCESS) {
3097         printMsg("Logger get rx pkt fate command failed, err = %d\n", result);
3098         goto exit;
3099     }
3100 
3101     if (!n_provided_fates) {
3102         printMsg("Got empty pkt fates\n");
3103         result = WIFI_ERROR_NOT_AVAILABLE;
3104         goto exit;
3105     }
3106 
3107     printMsg("No: of rx pkt fates provided = %d\n", n_provided_fates);
3108 
3109     w_fp = fopen(rx_pkt_fate_file, "w");
3110     if (!w_fp) {
3111         printMsg("Failed to create file: %s\n", rx_pkt_fate_file);
3112         result = WIFI_ERROR_NOT_AVAILABLE;
3113         goto exit;
3114     }
3115 
3116     fprintf(w_fp, "--- BEGIN ---\n\n");
3117     fprintf(w_fp, "No: of pkt fates provided = %zd\n\n", n_provided_fates);
3118     report_ptr = rx_report;
3119     for (size_t i = 0; i < n_provided_fates; i++) {
3120         fprintf(w_fp, "--- REPORT : %zu ---\n\n", (i + 1));
3121         if (report_ptr->frame_inf.frame_len == 0 ||
3122                 report_ptr->frame_inf.payload_type == FRAME_TYPE_UNKNOWN) {
3123             fprintf(w_fp, "Invalid frame...!!!\n\n");
3124         }
3125         fprintf(w_fp, "MD5 Prefix                 :  ");
3126         fprhex(w_fp, report_ptr->md5_prefix, MD5_PREFIX_LEN, false);
3127         fprintf(w_fp, "Packet Fate                :  %d\n", report_ptr->fate);
3128         fprintf(w_fp, "Frame Type                 :  %d\n", report_ptr->frame_inf.payload_type);
3129         fprintf(w_fp, "Frame Len                  :  %zu\n", report_ptr->frame_inf.frame_len);
3130         fprintf(w_fp, "Driver Timestamp           :  %u\n", report_ptr->frame_inf.driver_timestamp_usec);
3131         fprintf(w_fp, "Firmware Timestamp         :  %u\n", report_ptr->frame_inf.firmware_timestamp_usec);
3132         if (report_ptr->frame_inf.payload_type == FRAME_TYPE_ETHERNET_II) {
3133             frame_len = min(report_ptr->frame_inf.frame_len, (size_t)MAX_FRAME_LEN_ETHERNET);
3134 			fprintf(w_fp, "Frame Content (%04zu bytes) :  \n", frame_len);
3135 			fprhex(w_fp, report_ptr->frame_inf.frame_content.ethernet_ii_bytes, frame_len,
3136 				true);
3137         } else {
3138             frame_len = min(report_ptr->frame_inf.frame_len, (size_t)MAX_FRAME_LEN_80211_MGMT);
3139 			fprintf(w_fp, "Frame Content (%04zu bytes) :  \n", frame_len);
3140 			fprhex(w_fp, report_ptr->frame_inf.frame_content.ieee_80211_mgmt_bytes, frame_len,
3141 				true);
3142         }
3143         fprintf(w_fp, "\n--- END OF REPORT ---\n\n");
3144 
3145         report_ptr++;
3146     }
3147     fprintf(w_fp, "--- EOF ---\n");
3148 
3149 exit:
3150     if (w_fp) {
3151         fclose(w_fp);
3152     }
3153     if (rx_report) {
3154         free(rx_report);
3155     }
3156 
3157     return result;
3158 }
3159 
runLogger()3160 static void runLogger()
3161 {
3162     switch (log_cmd) {
3163         case LOG_GET_FW_VER:
3164             LoggerGetFW();
3165             break;
3166         case LOG_GET_DRV_VER:
3167             LoggerGetDriver();
3168             break;
3169         case LOG_GET_RING_STATUS:
3170             LoggerGetRingbufferStatus();
3171             break;
3172         case LOG_GET_FEATURE:
3173             LoggerGetFeature();
3174             break;
3175         case LOG_GET_MEMDUMP:
3176             LoggerGetMemdump();
3177             break;
3178         case LOG_GET_RING_DATA:
3179             LoggerGetRingData();
3180             break;
3181         case LOG_START:
3182             LoggerStart();
3183             break;
3184         case LOG_SET_LOG_HANDLER:
3185             LoggerSetLogHandler();
3186             break;
3187         case LOG_SET_ALERT_HANDLER:
3188             LoggerSetAlertHandler();
3189             break;
3190         case LOG_MONITOR_PKTFATE:
3191             LoggerMonitorPktFate();
3192             break;
3193         case LOG_GET_TXPKTFATE:
3194             LoggerGetTxPktFate();
3195             break;
3196         case LOG_GET_RXPKTFATE:
3197             LoggerGetRxPktFate();
3198             break;
3199         default:
3200             break;
3201     }
3202 }
3203 
start_mkeep_alive(int index,u32 period_msec,u16 ether_type,u8 * src_mac,u8 * dst_mac,u8 * ip_pkt,u16 ip_pkt_len)3204 static wifi_error start_mkeep_alive(int index, u32 period_msec, u16 ether_type,
3205                                         u8* src_mac, u8* dst_mac, u8* ip_pkt,
3206                                         u16 ip_pkt_len)
3207 {
3208     int ret;
3209 
3210     ret = hal_fn.wifi_start_sending_offloaded_packet(index, wlan0Handle, ether_type, ip_pkt,
3211           ip_pkt_len, src_mac, dst_mac, period_msec);
3212 
3213     if (ret == WIFI_SUCCESS) {
3214         printMsg("Start mkeep_alive with ID %d, %u period(msec), src(" MACSTR "), "
3215             "dst(" MACSTR ")\n", index, period_msec, MAC2STR(src_mac), MAC2STR(dst_mac));
3216     } else {
3217         printMsg("Failed to start mkeep_alive by ID %d: %d\n", index, ret);
3218         return WIFI_ERROR_NOT_AVAILABLE;
3219     }
3220     return WIFI_SUCCESS;
3221 }
3222 
stop_mkeep_alive(int index)3223 static wifi_error stop_mkeep_alive(int index)
3224 {
3225     int ret;
3226 
3227     ret = hal_fn.wifi_stop_sending_offloaded_packet(index, wlan0Handle);
3228 
3229     if (ret == WIFI_SUCCESS) {
3230         printMsg("Stop mkeep_alive with ID %d\n", index);
3231     } else {
3232         printMsg("Failed to stop mkeep_alive by ID %d: %d\n", index, ret);
3233         return WIFI_ERROR_NOT_AVAILABLE;
3234     }
3235     return WIFI_SUCCESS;
3236 }
3237 
parseHexChar(char ch)3238 byte parseHexChar(char ch) {
3239     if (isdigit(ch))
3240         return ch - '0';
3241     else if ('A' <= ch && ch <= 'F')
3242         return ch - 'A' + 10;
3243     else if ('a' <= ch && ch <= 'f')
3244         return ch - 'a' + 10;
3245     else {
3246         printMsg("invalid character in bssid %c\n", ch);
3247         return 0;
3248     }
3249 }
3250 
parseHexByte(char ch1,char ch2)3251 byte parseHexByte(char ch1, char ch2) {
3252     return (parseHexChar(ch1) << 4) | parseHexChar(ch2);
3253 }
3254 
parseMacAddress(const char * str,mac_addr addr)3255 void parseMacAddress(const char *str, mac_addr addr) {
3256     addr[0] = parseHexByte(str[0], str[1]);
3257     addr[1] = parseHexByte(str[3], str[4]);
3258     addr[2] = parseHexByte(str[6], str[7]);
3259     addr[3] = parseHexByte(str[9], str[10]);
3260     addr[4] = parseHexByte(str[12], str[13]);
3261     addr[5] = parseHexByte(str[15], str[16]);
3262 }
3263 
parseMacOUI(char * str,unsigned char * addr)3264 void parseMacOUI(char *str, unsigned char *addr) {
3265     addr[0] = parseHexByte(str[0], str[1]);
3266     addr[1] = parseHexByte(str[3], str[4]);
3267     addr[2] = parseHexByte(str[6], str[7]);
3268     printMsg("read mac OUI: %02x:%02x:%02x\n", addr[0],
3269             addr[1], addr[2]);
3270 }
3271 
3272 int
ether_atoe(const char * a,u8 * addr)3273 ether_atoe(const char *a, u8 *addr)
3274 {
3275     char *c = NULL;
3276     int i = 0;
3277     memset(addr, 0, ETHER_ADDR_LEN);
3278     for (; i < ETHER_ADDR_LEN; i++) {
3279         addr[i] = (u8)strtoul(a, &c, 16);
3280         if (*c != ':' && *c != '\0') {
3281             return 0;
3282         }
3283         a = ++c;
3284     }
3285     return (i == ETHER_ADDR_LEN);
3286 }
3287 
readTestOptions(int argc,char * argv[])3288 void readTestOptions(int argc, char *argv[]) {
3289 
3290     printf("Total number of argc #%d\n", argc);
3291     wifi_epno_network *epno_ssid = epno_cfg.networks;
3292     for (int j = 1; j < argc-1; j++) {
3293         if (strcmp(argv[j], "-max_ap") == 0 && isdigit(argv[j+1][0])) {
3294             stest_max_ap = atoi(argv[++j]);
3295             printf(" max_ap #%d\n", stest_max_ap);
3296         } else if (strcmp(argv[j], "-base_period") == 0 && isdigit(argv[j+1][0])) {
3297             stest_base_period = atoi(argv[++j]);
3298             printf(" base_period #%d\n", stest_base_period);
3299         } else if (strcmp(argv[j], "-threshold") == 0 && isdigit(argv[j+1][0])) {
3300             stest_threshold_percent = atoi(argv[++j]);
3301             printf(" threshold #%d\n", stest_threshold_percent);
3302         } else if (strcmp(argv[j], "-avg_RSSI") == 0 && isdigit(argv[j+1][0])) {
3303             swctest_rssi_sample_size = atoi(argv[++j]);
3304             printf(" avg_RSSI #%d\n", swctest_rssi_sample_size);
3305         } else if (strcmp(argv[j], "-ap_loss") == 0 && isdigit(argv[j+1][0])) {
3306             swctest_rssi_lost_ap = atoi(argv[++j]);
3307             printf(" ap_loss #%d\n", swctest_rssi_lost_ap);
3308         } else if (strcmp(argv[j], "-ap_breach") == 0 && isdigit(argv[j+1][0])) {
3309             swctest_rssi_min_breaching = atoi(argv[++j]);
3310             printf(" ap_breach #%d\n", swctest_rssi_min_breaching);
3311         } else if (strcmp(argv[j], "-ch_threshold") == 0 && isdigit(argv[j+1][0])) {
3312             swctest_rssi_ch_threshold = atoi(argv[++j]);
3313             printf(" ch_threshold #%d\n", swctest_rssi_ch_threshold);
3314         } else if (strcmp(argv[j], "-wt_event") == 0 && isdigit(argv[j+1][0])) {
3315             max_event_wait = atoi(argv[++j]);
3316             printf(" wt_event #%d\n", max_event_wait);
3317         } else if (strcmp(argv[j], "-low_th") == 0 && isdigit(argv[j+1][0])) {
3318             htest_low_threshold = atoi(argv[++j]);
3319             printf(" low_threshold #-%d\n", htest_low_threshold);
3320         } else if (strcmp(argv[j], "-high_th") == 0 && isdigit(argv[j+1][0])) {
3321             htest_high_threshold = atoi(argv[++j]);
3322             printf(" high_threshold #-%d\n", htest_high_threshold);
3323         } else if (strcmp(argv[j], "-hotlist_bssids") == 0 && isxdigit(argv[j+1][0])) {
3324             j++;
3325             for (num_hotlist_bssids = 0; j < argc && isxdigit(argv[j][0]);
3326                 j++, num_hotlist_bssids++) {
3327                     parseMacAddress(argv[j], hotlist_bssids[num_hotlist_bssids]);
3328             }
3329             j -= 1;
3330         } else if (strcmp(argv[j], "-channel_list") == 0 && isxdigit(argv[j+1][0])) {
3331             j++;
3332             for (num_channels = 0; j < argc && isxdigit(argv[j][0]); j++, num_channels++) {
3333                 channel_list[num_channels] = atoi(argv[j]);
3334             }
3335             j -= 1;
3336         } else if ((strcmp(argv[j], "-get_ch_list") == 0)) {
3337             if(strcmp(argv[j + 1], "a") == 0) {
3338                 band = WIFI_BAND_A_WITH_DFS;
3339             } else if(strcmp(argv[j + 1], "bg") == 0) {
3340                 band = WIFI_BAND_BG;
3341             } else if(strcmp(argv[j + 1], "abg") == 0) {
3342                 band = WIFI_BAND_ABG_WITH_DFS;
3343             } else if(strcmp(argv[j + 1], "a_nodfs") == 0) {
3344                 band = WIFI_BAND_A;
3345             } else if(strcmp(argv[j + 1], "dfs") == 0) {
3346                 band = WIFI_BAND_A_DFS;
3347             } else if(strcmp(argv[j + 1], "abg_nodfs") == 0) {
3348                 band = WIFI_BAND_ABG;
3349             }
3350             j++;
3351         } else if (strcmp(argv[j], "-scan_mac_oui") == 0 && isxdigit(argv[j+1][0])) {
3352             parseMacOUI(argv[++j], mac_oui);
3353         } else if ((strcmp(argv[j], "-ssid") == 0)) {
3354             epno_cfg.num_networks++;
3355             if (epno_cfg.num_networks < (int)MAX_EPNO_NETWORKS) {
3356                 memcpy(epno_ssid[epno_cfg.num_networks].ssid, argv[j + 1], (size_t)(MAX_SSID_LEN));
3357                 printf(" SSID %s\n", epno_ssid[epno_cfg.num_networks].ssid);
3358                 j++;
3359             }
3360         } else if ((strcmp(argv[j], "-auth") == 0)) {
3361             if (epno_cfg.num_networks < (int)MAX_EPNO_NETWORKS) {
3362                epno_ssid[epno_cfg.num_networks].auth_bit_field = atoi(argv[++j]);
3363                printf(" auth %d\n", epno_ssid[epno_cfg.num_networks].auth_bit_field);
3364             }
3365         } else if ((strcmp(argv[j], "-hidden") == 0)) {
3366             if (epno_cfg.num_networks < (int)MAX_EPNO_NETWORKS) {
3367                epno_ssid[epno_cfg.num_networks].flags |= atoi(argv[++j]) ? EPNO_HIDDEN: 0;
3368                printf(" flags %d\n", epno_ssid[epno_cfg.num_networks].flags);
3369             }
3370         } else if ((strcmp(argv[j], "-strict") == 0)) {
3371             if (epno_cfg.num_networks < (int)MAX_EPNO_NETWORKS) {
3372                epno_ssid[epno_cfg.num_networks].flags |= atoi(argv[++j]) ? EPNO_FLAG_STRICT_MATCH: 0;
3373                printf(" flags %d\n", epno_ssid[epno_cfg.num_networks].flags);
3374             }
3375         } else if ((strcmp(argv[j], "-same_network") == 0)) {
3376             if (epno_cfg.num_networks < (int)MAX_EPNO_NETWORKS) {
3377                epno_ssid[epno_cfg.num_networks].flags |= atoi(argv[++j]) ? EPNO_FLAG_SAME_NETWORK: 0;
3378                printf(" flags %d\n", epno_ssid[epno_cfg.num_networks].flags);
3379             }
3380         } else if (strcmp(argv[j], "-min5g_rssi") == 0 && isdigit(argv[j+1][0])) {
3381             epno_cfg.min5GHz_rssi = -atoi(argv[++j]);
3382             printf(" min5g_rssi %d\n", epno_cfg.min5GHz_rssi);
3383         } else if (strcmp(argv[j], "-min2g_rssi") == 0 && isdigit(argv[j+1][0])) {
3384             epno_cfg.min24GHz_rssi = -atoi(argv[++j]);
3385             printf(" min2g_rssi %d\n", epno_cfg.min24GHz_rssi);
3386         } else if (strcmp(argv[j], "-init_score_max") == 0 && isdigit(argv[j+1][0])) {
3387             epno_cfg.initial_score_max = atoi(argv[++j]);
3388             printf(" initial_score_max %d\n", epno_cfg.initial_score_max);
3389         } else if (strcmp(argv[j], "-cur_conn_bonus") == 0 && isdigit(argv[j+1][0])) {
3390             epno_cfg.current_connection_bonus = atoi(argv[++j]);
3391             printf(" cur_conn_bonus %d\n", epno_cfg.current_connection_bonus);
3392         } else if (strcmp(argv[j], "-same_network_bonus") == 0 && isdigit(argv[j+1][0])) {
3393             epno_cfg.same_network_bonus = atoi(argv[++j]);
3394             printf(" same_network_bonus %d\n", epno_cfg.same_network_bonus);
3395         } else if (strcmp(argv[j], "-secure_bonus") == 0 && isdigit(argv[j+1][0])) {
3396             epno_cfg.secure_bonus = atoi(argv[++j]);
3397             printf(" secure_bonus %d\n", epno_cfg.secure_bonus);
3398         } else if (strcmp(argv[j], "-band5g_bonus") == 0 && isdigit(argv[j+1][0])) {
3399             epno_cfg.band5GHz_bonus = atoi(argv[++j]);
3400             printf(" band5GHz_bonus %d\n", epno_cfg.band5GHz_bonus);
3401         } else if ((strcmp(argv[j], "-trig") == 0)) {
3402             if (epno_cfg.num_networks < (int)MAX_EPNO_NETWORKS) {
3403                 if ((strcmp(argv[j + 1], "a") == 0)) {
3404                    epno_ssid[epno_cfg.num_networks].flags |= EPNO_A_BAND_TRIG;
3405                 } else if ((strcmp(argv[j + 1], "bg") == 0)) {
3406                    epno_ssid[epno_cfg.num_networks].flags |= EPNO_BG_BAND_TRIG;
3407                 } else if ((strcmp(argv[j + 1], "abg") == 0)) {
3408                    epno_ssid[epno_cfg.num_networks].flags |= EPNO_ABG_BAND_TRIG;
3409                 }
3410                printf(" flags %d\n", epno_ssid[epno_cfg.num_networks].flags);
3411             }
3412             j++;
3413         } else if ((strcmp(argv[j], "-blacklist_bssids") == 0 && isxdigit(argv[j+1][0])) ||
3414             (strcmp(argv[j], "-whitelist_ssids") == 0)) {
3415             if (strcmp(argv[j], "-blacklist_bssids") == 0 && isxdigit(argv[j+1][0])) {
3416                 j++;
3417                 for (num_blacklist_bssids = 0;
3418                     j < argc && isxdigit(argv[j][0]) &&
3419                     num_blacklist_bssids < MAX_BLACKLIST_BSSID;
3420                     j++, num_blacklist_bssids++) {
3421                     parseMacAddress(argv[j], blacklist_bssids[num_blacklist_bssids]);
3422                 }
3423             }
3424             if (strcmp(argv[j], "-whitelist_ssids") == 0) {
3425                 j++;
3426                 for (num_whitelist_ssids = 0;
3427                     j < argc && (num_whitelist_ssids < MAX_WHITELIST_SSID);
3428                     j++, num_whitelist_ssids++) {
3429                         if ((strcmp(argv[j], "-blacklist_bssids") == 0) ||
3430                             isxdigit(argv[j][0])) {
3431                             num_whitelist_ssids--;
3432                             continue;
3433                         }
3434                     strncpy(whitelist_ssids[num_whitelist_ssids], argv[j],
3435                     min(strlen(argv[j]), (size_t)(MAX_SSID_LEN-1)));
3436                 }
3437                 /* Setting this flag to true here as -blacklist_bssids has already existing explicit handler */
3438                 set_roaming_configuration = true;
3439             }
3440             j -= 1;
3441         } else if (strcmp(argv[j], "-rssi_monitor") == 0 && isdigit(argv[j+1][0])) {
3442             rssi_monitor = atoi(argv[++j]);
3443             printf(" rssi_monitor #%d\n", rssi_monitor);
3444         } else if (strcmp(argv[j], "-max_rssi") == 0 && isdigit(argv[j+1][0])) {
3445             max_rssi = -atoi(argv[++j]);
3446             printf(" max_rssi #%d\n", max_rssi);
3447         } else if (strcmp(argv[j], "-min_rssi") == 0 && isdigit(argv[j+1][0])) {
3448             min_rssi = -atoi(argv[++j]);
3449             printf(" min_rssi #%d\n", min_rssi);
3450         }
3451     }
3452 }
3453 
readRTTOptions(int argc,char * argv[])3454 void readRTTOptions(int argc, char *argv[]) {
3455     for (int j = 1; j < argc-1; j++) {
3456         if ((strcmp(argv[j], "-get_ch_list") == 0)) {
3457             if(strcmp(argv[j + 1], "a") == 0) {
3458                 band = WIFI_BAND_A_WITH_DFS;
3459             } else if(strcmp(argv[j + 1], "bg") == 0) {
3460                 band = WIFI_BAND_BG;
3461             } else if(strcmp(argv[j + 1], "abg") == 0) {
3462                 band = WIFI_BAND_ABG_WITH_DFS;
3463             } else if(strcmp(argv[j + 1], "a_nodfs") == 0) {
3464                 band = WIFI_BAND_A;
3465             } else if(strcmp(argv[j + 1], "dfs") == 0) {
3466                 band = WIFI_BAND_A_DFS;
3467             } else if(strcmp(argv[j + 1], "abg_nodfs") == 0) {
3468                 band = WIFI_BAND_ABG;
3469             }
3470             ALOGE("band chosen = %s[band = %d]\n", argv[j + 1], band);
3471             j++;
3472         } else if ((strcmp(argv[j], "-l") == 0)) {
3473             /*
3474              * If this option is specified but there is no file name,
3475              * use a default file from rtt_aplist.
3476              */
3477             if (++j != argc-1) {
3478                 strncpy(rtt_aplist, argv[j], (FILE_NAME_LEN -1));
3479                 rtt_aplist[FILE_NAME_LEN -1] = '\0';
3480             }
3481             rtt_from_file = 1;
3482         } else if ((strcmp(argv[j], "-n") == 0) && isdigit(argv[j+1][0])) {
3483             default_rtt_param.num_burst = atoi(argv[++j]);
3484         } else if ((strcmp(argv[j], "-f") == 0) && isdigit(argv[j+1][0])) {
3485             default_rtt_param.num_frames_per_burst = atoi(argv[++j]);
3486         } else if ((strcmp(argv[j], "-r") == 0) && isdigit(argv[j+1][0])) {
3487             default_rtt_param.num_retries_per_ftm = atoi(argv[++j]);
3488         } else if ((strcmp(argv[j], "-m") == 0) && isdigit(argv[j+1][0])) {
3489             default_rtt_param.num_retries_per_ftmr = atoi(argv[++j]);
3490         } else if ((strcmp(argv[j], "-b") == 0) && isdigit(argv[j+1][0])) {
3491             default_rtt_param.burst_duration = atoi(argv[++j]);
3492         } else if ((strcmp(argv[j], "-max_ap") == 0) && isdigit(argv[j+1][0])) {
3493             max_ap = atoi(argv[++j]);
3494         } else if ((strcmp(argv[j], "-lci") == 0) && isdigit(argv[j+1][0])) {
3495             default_rtt_param.LCI_request = atoi(argv[++j]);
3496         } else if ((strcmp(argv[j], "-lcr") == 0) && isdigit(argv[j+1][0])) {
3497             default_rtt_param.LCR_request = atoi(argv[++j]);
3498         } else if ((strcmp(argv[j], "-type") == 0) && isdigit(argv[j+1][0])) {
3499             u8 rtt_type = atoi(argv[++j]);
3500             if (rtt_type == 1) {
3501                 printf("RTT Type is ONE-SIDED\n");
3502                 default_rtt_param.type = RTT_TYPE_1_SIDED;
3503             }
3504         } else if ((strcmp(argv[j], "-o") == 0)) {
3505             /*
3506              * If this option is specified but there is no file name,
3507              * use a default file from rtt_aplist.
3508              */
3509             if (++j != argc-1) {
3510                 strncpy(rtt_aplist, argv[j], (FILE_NAME_LEN -1));
3511                 rtt_aplist[FILE_NAME_LEN -1] = '\0';
3512             }
3513             rtt_to_file = 1;
3514         } else if ((strcmp(argv[j], "-sta") == 0) ||
3515             (strcmp(argv[j], "-nan") == 0)) {
3516             if (strcmp(argv[j], "-sta") == 0) {
3517                 rtt_sta = true;
3518             } else {
3519                 rtt_nan = true;
3520             }
3521             if (isxdigit(argv[j+1][0])) {
3522                 j++;
3523                 parseMacAddress(argv[j], responder_addr);
3524                 printMsg("Target mac(" MACSTR ")", MAC2STR(responder_addr));
3525             }
3526             /* Read channel if present */
3527             if (argv[j+1]) {
3528                 if (isdigit(argv[j+1][0])) {
3529                     j++;
3530                     responder_channel = atoi(argv[j]);
3531                     printf("Channel set as %d \n", responder_channel);
3532                 }
3533                 /* Read band width if present */
3534                 if (argv[j+1]) {
3535                     if (isdigit(argv[j+1][0])) {
3536                         j++;
3537                         channel_width = atoi(argv[j]);
3538                         printf("channel_width as %d \n", channel_width);
3539                     }
3540                 }
3541                 /* check its 6g channel */
3542                 if (argv[j+1]) {
3543                     if (isdigit(argv[j+1][0])) {
3544                         j++;
3545                         if(atoi(argv[j]) == 1) {
3546                             printf(" IS 6G CHANNEL \n");
3547                             is_6g = true;
3548                         }
3549                     }
3550                 }
3551             }
3552         }
3553     }
3554 }
3555 
readLoggerOptions(int argc,char * argv[])3556 void readLoggerOptions(int argc, char *argv[])
3557 {
3558     void printUsage();          // declaration for below printUsage()
3559     int j = 1;
3560 
3561     if (argc < 3) {
3562         printUsage();
3563         return;
3564     }
3565 
3566     if ((strcmp(argv[j], "-start") == 0)) {
3567         if ((strcmp(argv[j+1], "pktmonitor") == 0)){
3568             log_cmd = LOG_MONITOR_PKTFATE;
3569             return;
3570         } else if (argc != 13) {
3571             printf("\nUse correct logger option:\n");
3572             printUsage();
3573             return;
3574         }
3575         log_cmd = LOG_START;
3576         memset(&default_logger_param, 0, sizeof(default_logger_param));
3577 
3578         j++;
3579         if ((strcmp(argv[j], "-d") == 0) && isdigit(argv[j+1][0]))
3580             default_logger_param.verbose_level = (unsigned int)atoi(argv[++j]);
3581         if ((strcmp(argv[++j], "-f") == 0) && isdigit(argv[j+1][0]))
3582             default_logger_param.flags = atoi(argv[++j]);
3583         if ((strcmp(argv[++j], "-i") == 0) && isdigit(argv[j+1][0]))
3584             default_logger_param.max_interval_sec = atoi(argv[++j]);
3585         if ((strcmp(argv[++j], "-s") == 0) && isdigit(argv[j+1][0]))
3586             default_logger_param.min_data_size = atoi(argv[++j]);
3587         if ((strcmp(argv[++j], "-n") == 0))
3588             memcpy(default_logger_param.ring_name, argv[j+1], (MAX_RING_NAME_SIZE));
3589         return;
3590     } else if ((strcmp(argv[j], "-get") == 0) && (argc > 3)) {
3591         if ((strcmp(argv[j+1], "fw") == 0)) {
3592             log_cmd = LOG_GET_FW_VER;
3593         } else if ((strcmp(argv[j+1], "driver") == 0)) {
3594             log_cmd = LOG_GET_DRV_VER;
3595         } else if ((strcmp(argv[j+1], "memdump") == 0)) {
3596             log_cmd = LOG_GET_MEMDUMP;
3597             j++;
3598             if ((j+1 < argc-1) && (strcmp(argv[j+1], "-o") == 0)) {
3599                 // If this option is specified but there is no file name,
3600                 // use a default file from DEFAULT_MEMDUMP_FILE.
3601                 j++;
3602                 if (j+1 < argc-1) {
3603                     strncpy(mem_dump_file, argv[j+1] , (FILE_NAME_LEN -1));
3604                     mem_dump_file[FILE_NAME_LEN -1] = '\0';
3605                 }
3606             }
3607         } else if ((strcmp(argv[j+1], "ringstatus") == 0)) {
3608             log_cmd = LOG_GET_RING_STATUS;
3609         } else if ((strcmp(argv[j+1], "feature") == 0)) {
3610             log_cmd = LOG_GET_FEATURE;
3611         } else if ((strcmp(argv[j+1], "ringdata") == 0)) {
3612             log_cmd = LOG_GET_RING_DATA;
3613             j+=2;
3614             if ((strcmp(argv[j], "-n") == 0))
3615                 memcpy(default_ring_name, argv[j+1], MAX_RING_NAME_SIZE);
3616         } else if ((strcmp(argv[j+1], "txfate") == 0)) {
3617             log_cmd = LOG_GET_TXPKTFATE;
3618             j++;
3619             while (j+1 < argc-1) {
3620                 if (strcmp(argv[j+1], "-n") == 0) {
3621                     j++;
3622                     if (j+1 < argc-1) {
3623                         n_requested_pkt_fate = atoi(argv[j+1]);
3624                     }
3625                 } else if (strcmp(argv[j+1], "-f") == 0) {
3626                     j++;
3627                     if (j+1 < argc-1) {
3628                         size_t len = min(strlen(argv[j+1]), (size_t)(FILE_NAME_LEN - 1));
3629                         strncpy(tx_pkt_fate_file, argv[j+1], len);
3630                         tx_pkt_fate_file[len] = '\0';
3631                     }
3632                 }
3633                 j++;
3634             }
3635         } else if ((strcmp(argv[j+1], "rxfate") == 0)) {
3636             log_cmd = LOG_GET_RXPKTFATE;
3637             j++;
3638             while (j+1 < argc-1) {
3639                 if (strcmp(argv[j+1], "-n") == 0) {
3640                     j++;
3641                     if (j+1 < argc-1) {
3642                         n_requested_pkt_fate = atoi(argv[j+1]);
3643                     }
3644                 } else if (strcmp(argv[j+1], "-f") == 0) {
3645                     j++;
3646                     if (j+1 < argc-1) {
3647                         size_t len = min(strlen(argv[j+1]), (size_t)(FILE_NAME_LEN - 1));
3648                         strncpy(rx_pkt_fate_file, argv[j+1], len);
3649                         rx_pkt_fate_file[len] = '\0';
3650                     }
3651                 }
3652                 j++;
3653             }
3654         } else {
3655             printf("\nUse correct logger option:\n");
3656             printUsage();
3657         }
3658         return;
3659     } else if ((strcmp(argv[j], "-set") == 0) && (argc > 3)) {
3660         if ((strcmp(argv[j+1], "loghandler") == 0)) {
3661             log_cmd = LOG_SET_LOG_HANDLER;
3662         } else if ((strcmp(argv[j+1], "alerthandler") == 0)) {
3663             log_cmd = LOG_SET_ALERT_HANDLER;
3664         }
3665     } else {
3666         printf("\nUse correct logger option:\n");
3667         printUsage();
3668 
3669         return;
3670     }
3671 }
3672 
str2hex(char * src,char * dst)3673 static int str2hex(char *src, char *dst)
3674 {
3675     int i;
3676     if (strlen(src) % 2 != 0) {
3677         printMsg(("Mask invalid format. Needs to be of even length\n"));
3678         return -1;
3679     }
3680 
3681     if (strncmp(src, "0x", 2) == 0 || strncmp(src, "0X", 2) == 0) {
3682         src = src + 2; /* Skip past 0x */
3683     }
3684 
3685     for (i = 0; *src != '\0'; i++) {
3686         char num[3];
3687         strncpy(num, src, 2);
3688         num[2] = '\0';
3689         dst[i] = (u8)strtoul(num, NULL, 16);
3690         src += 2;
3691     }
3692     return i;
3693 }
3694 
readKeepAliveOptions(int argc,char * argv[])3695 void readKeepAliveOptions(int argc, char *argv[])
3696 {
3697     void printUsage();          // declaration for below printUsage()
3698 
3699     int index = 0;
3700     u32 period_msec = 0;
3701     mac_addr src_mac;                           // byte array of src mac address
3702     mac_addr dst_mac;                           // byte array of dest mac address
3703     u8 ip_pkt[MKEEP_ALIVE_IP_PKT_MAX] = {0};    // IP pkt including UDP and headers
3704     u16 ip_pkt_len = 0, ether_type = 0;
3705     int j = 1;
3706     int ret = 0;
3707 
3708     /**
3709      * For example,
3710      *
3711      * u8 ip_pkt[] =
3712      * "0014a54b164f000f66f45b7e08004500001e000040004011c52a0a8830700a88302513c413c4000a00000a0d"
3713      *
3714      *  length: 44 bytes
3715      *
3716      *  Ethernet header
3717      *       0014a54b164f   - dest addr
3718      *       000f66f45b7e   - src addr
3719      *       0800           - ether-type    ETHERTYPE_IP (IP protocol) or
3720      *       86dd           - ether-type    ETHERTYPE_IPV6 (IPv6 protocol)
3721      *  IP header
3722      *       4500001e       - Version, IHL, TOS, Total length
3723      *       00004000       - Identification, fragment
3724      *       4011c52a       - TTL, Protocol, Checksum
3725      *       0a883070       - src addr
3726      *       0a883025       - dest addr
3727      *  UDP header
3728      *       13c4           - src port
3729      *       13c4           - dest port
3730      *       000a           - UDP length
3731      *       0000           - checksum
3732      *  UDP payload
3733      *       0a0d
3734      */
3735 
3736     if ((argc == 9) && (strcmp(argv[j], "-start") == 0)) {
3737         // Mapping index
3738         index = atoi(argv[++j]);
3739         if (index < 1 || index > N_AVAIL_ID) {
3740             printMsg("Select proper index number (1 to 3) for mkeep_alive.\n");
3741             return;
3742         }
3743 
3744         // Mapping period
3745         period_msec = atoi(argv[++j]);
3746         if (period_msec <= 0) {
3747             printMsg("Select proper retransmission period for mkeep_alive, great than zero\n");
3748             return;
3749         }
3750 
3751         // Mapping mac addresses
3752         if ((str2hex(argv[++j], (char *)src_mac) != ETHER_ADDR_LEN)
3753                 || (str2hex(argv[++j], (char *)dst_mac) != ETHER_ADDR_LEN)) {
3754             printMsg("Source or destination mac address is not correct. Please make sure.\n");
3755             return;
3756         }
3757 
3758         // Mapping ether_type
3759         ether_type = atoi(argv[++j]);
3760         if (!((ether_type == ETHERTYPE_IP) ||
3761             (ether_type == ETHERTYPE_IPV6))) {
3762             printMsg("Select proper ether_type, valid values 0x0800(2048) for IP or 0x86dd(34525) IP6\n");
3763             return;
3764         }
3765 
3766         // Mapping string pkt length by hexa byte
3767         ip_pkt_len = strlen(argv[++j])/2;
3768         if (ip_pkt_len > MKEEP_ALIVE_IP_PKT_MAX) {
3769             printMsg("IP pkt size is bigger than max_len (%d) for mkeep_alive. "
3770                      "Please check up the size of IP packet contents.\n",
3771                 MKEEP_ALIVE_IP_PKT_MAX);
3772                 return;
3773         }
3774 
3775         // Mapping pkt contents by hexa format
3776         memset(ip_pkt, 0, MKEEP_ALIVE_IP_PKT_MAX);
3777         if (str2hex(argv[j], (char *)ip_pkt) != ip_pkt_len) {
3778             printMsg("Conversion of hexa byte on IP pkt has been failed.\n");
3779             return;
3780         }
3781 
3782         ret = start_mkeep_alive(index, period_msec, ether_type, src_mac,
3783                 dst_mac, ip_pkt, ip_pkt_len);
3784         if (ret == WIFI_SUCCESS)
3785             printMsg("Success to register mkeep_alive by ID %d\n", index);
3786     } else if ((argc == 4) && (strcmp(argv[j], "-stop") == 0)) {
3787         // mapping index
3788         index = atoi(argv[++j]);
3789         if (index < 1 || index > N_AVAIL_ID) {
3790             printMsg("Select proper index number (1 to 3) for mkeep_alive.\n");
3791             return;
3792         }
3793 
3794         ret = stop_mkeep_alive(index);
3795         if (ret == WIFI_SUCCESS)
3796             printMsg("Success to stop mkeep_alive by ID %d\n", index);
3797     } else {
3798         printf("Use correct mkeep_alive option:\n");
3799     }
3800 }
3801 
3802 const char *eht_rates[] = {
3803     "OFDM/LEGACY 1Mbps               ",
3804     "OFDM/LEGACY 2Mbps               ",
3805     "OFDM/LEGACY 5.5Mbps             ",
3806     "OFDM/LEGACY 6Mbps               ",
3807     "OFDM/LEGACY 9Mbps               ",
3808     "OFDM/LEGACY 11Mbps              ",
3809     "OFDM/LEGACY 12Mbps              ",
3810     "OFDM/LEGACY 18Mbps              ",
3811     "OFDM/LEGACY 24Mbps              ",
3812     "OFDM/LEGACY 36Mbps              ",
3813     "OFDM/LEGACY 48Mbps              ",
3814     "OFDM/LEGACY 54Mbps              ",
3815     "HT MCS0  | VHT/HE/EHT MCS0  NSS1",
3816     "HT MCS1  | VHT/HE/EHT MCS1  NSS1",
3817     "HT MCS2  | VHT/HE/EHT MCS2  NSS1",
3818     "HT MCS3  | VHT/HE/EHT MCS3  NSS1",
3819     "HT MCS4  | VHT/HE/EHT MCS4  NSS1",
3820     "HT MCS5  | VHT/HE/EHT MCS5  NSS1",
3821     "HT MCS6  | VHT/HE/EHT MCS6  NSS1",
3822     "HT MCS7  | VHT/HE/EHT MCS7  NSS1",
3823     "HT MCS8  | VHT/HE/EHT MCS8  NSS1",
3824     "HT MCS9  | VHT/HE/EHT MCS9  NSS1",
3825     "HT MCS10 | VHT/HE/EHT MCS10 NSS1",
3826     "HT MCS11 | VHT/HE/EHT MCS11 NSS1",
3827     "HT MCS12 |        EHT MCS12 NSS1",
3828     "HT MCS13 |        EHT MCS13 NSS1",
3829     "HT MCS14 |        EHT MCS14 NSS1",
3830     "HT MCS15 |        EHT MCS15 NSS1",
3831     "HT N/A   | VHT/HE/EHT MCS0  NSS2",
3832     "HT N/A   | VHT/HE/EHT MCS1  NSS2",
3833     "HT N/A   | VHT/HE/EHT MCS2  NSS2",
3834     "HT N/A   | VHT/HE/EHT MCS3  NSS2",
3835     "HT N/A   | VHT/HE/EHT MCS4  NSS2",
3836     "HT N/A   | VHT/HE/EHT MCS5  NSS2",
3837     "HT N/A   | VHT/HE/EHT MCS6  NSS2",
3838     "HT N/A   | VHT/HE/EHT MCS7  NSS2",
3839     "HT N/A   | VHT/HE/EHT MCS8  NSS2",
3840     "HT N/A   | VHT/HE/EHT MCS9  NSS2",
3841     "HT N/A   | VHT/HE/EHT MCS10 NSS2",
3842     "HT N/A   | VHT/HE/EHT MCS11 NSS2",
3843     "HT N/A   |        EHT MCS12 NSS2",
3844     "HT N/A   |        EHT MCS13 NSS2",
3845     "HT N/A   |        EHT MCS14 NSS2",
3846     "HT N/A   |        EHT MCS15 NSS2",
3847 };
3848 
3849 const char *rates[] = {
3850     "OFDM/LEGACY 1Mbps",
3851     "OFDM/LEGACY 2Mbps",
3852     "OFDM/LEGACY 5.5Mbps",
3853     "OFDM/LEGACY 6Mbps",
3854     "OFDM/LEGACY 9Mbps",
3855     "OFDM/LEGACY 11Mbps",
3856     "OFDM/LEGACY 12Mbps",
3857     "OFDM/LEGACY 18Mbps",
3858     "OFDM/LEGACY 24Mbps",
3859     "OFDM/LEGACY 36Mbps",
3860     "OFDM/LEGACY 48Mbps",
3861     "OFDM/LEGACY 54Mbps",
3862     "HT MCS0  | VHT/HE MCS0  NSS1",
3863     "HT MCS1  | VHT/HE MCS1  NSS1",
3864     "HT MCS2  | VHT/HE MCS2  NSS1",
3865     "HT MCS3  | VHT/HE MCS3  NSS1",
3866     "HT MCS4  | VHT/HE MCS4  NSS1",
3867     "HT MCS5  | VHT/HE MCS5  NSS1",
3868     "HT MCS6  | VHT/HE MCS6  NSS1",
3869     "HT MCS7  | VHT/HE MCS7  NSS1",
3870     "HT MCS8  | VHT/HE MCS8  NSS1",
3871     "HT MCS9  | VHT/HE MCS9  NSS1",
3872     "HT MCS10 | VHT/HE MCS10 NSS1",
3873     "HT MCS11 | VHT/HE MCS11 NSS1",
3874     "HT MCS12 | VHT/HE MCS0  NSS2",
3875     "HT MCS13 | VHT/HE MCS1  NSS2",
3876     "HT MCS14 | VHT/HE MCS2  NSS2",
3877     "HT MCS15 | VHT/HE MCS3  NSS2",
3878     "HT N/A   | VHT/HE MCS4  NSS2",
3879     "HT N/A   | VHT/HE MCS5  NSS2",
3880     "HT N/A   | VHT/HE MCS6  NSS2",
3881     "HT N/A   | VHT/HE MCS7  NSS2",
3882     "HT N/A   | VHT/HE MCS8  NSS2",
3883     "HT N/A   | VHT/HE MCS9  NSS2",
3884     "HT N/A   | VHT/HE MCS10 NSS2",
3885     "HT N/A   | VHT/HE MCS11 NSS2",
3886 };
3887 
3888 #define NUM_EHT_RATES (sizeof(eht_rates)/sizeof(eht_rates[0]))
3889 #define NUM_RATES (sizeof(rates)/sizeof(rates[0]))
3890 
3891 #define RATE_SPEC_STR_LEN 10
3892 #define RATE_SPEC_CHECK_INDEX 27
3893 const char rate_stat_preamble[][RATE_SPEC_STR_LEN] = {
3894     "OFDM",
3895     "CCK",
3896     "HT",
3897     "VHT",
3898     "HE",
3899     "EHT"
3900 };
3901 
3902 const short int rate_stat_bandwidth[] = {
3903     20,
3904     40,
3905     80,
3906     160,
3907     320
3908 };
3909 
3910 int radios = 0;
3911 int ml_links = 0;
3912 
3913 wifi_radio_stat rx_stat[MAX_NUM_RADIOS];
3914 wifi_channel_stat cca_stat[MAX_CH_BUF_SIZE];
3915 
updateRateStats(u8 ** buf,int num_rates)3916 void updateRateStats(u8 **buf, int num_rates) {
3917     printMsg("\nPrinting rate statistics: ");
3918     printMsg("------------------------------------------------------\n");
3919     printMsg("%40s %12s %14s %15s\n", "TX",  "RX", "LOST", "RETRIES");
3920     for (int k = 0; k < num_rates; k++) {
3921         if (!*buf) {
3922             ALOGE("No valid buf of rate_stats for index %d\n", k);
3923             continue;
3924         }
3925         wifi_rate_stat *local_ratestat_ptr = (wifi_rate_stat*)(*buf);
3926         if (!local_ratestat_ptr) {
3927             printMsg("rate stat data of index %d not found\n", k);
3928             continue;
3929         }
3930         if (num_rates == NUM_EHT_RATES) {
3931             printMsg("%-28s  %10d   %10d     %10d      %10d\n",
3932                 eht_rates[k], local_ratestat_ptr->tx_mpdu, local_ratestat_ptr->rx_mpdu,
3933                     local_ratestat_ptr->mpdu_lost, local_ratestat_ptr->retries);
3934         } else if (num_rates == NUM_RATES) {
3935             printMsg("%-28s  %10d   %10d     %10d      %10d\n",
3936                 rates[k], local_ratestat_ptr->tx_mpdu, local_ratestat_ptr->rx_mpdu,
3937                     local_ratestat_ptr->mpdu_lost, local_ratestat_ptr->retries);
3938         } else {
3939             printMsg("num_rates %d value is not supported\n", num_rates);
3940             continue;
3941         }
3942         *buf += sizeof(wifi_rate_stat);
3943     }
3944 }
3945 
printPeerinfoStats(wifi_peer_info * local_peer_ptr)3946 void printPeerinfoStats(wifi_peer_info *local_peer_ptr) {
3947     printMsg("Peer type = %d\n", local_peer_ptr->type);
3948     printMsg("Peer mac address: ( " MACSTR " )\n",
3949         MAC2STR(local_peer_ptr->peer_mac_address));
3950     printMsg("Peer Capabilities = %d\n", local_peer_ptr->capabilities);
3951     printMsg("Load_info(Station Count) = %d\n", local_peer_ptr->bssload.sta_count);
3952     printMsg("CCA_level(Channel Utilization) = %d\n", local_peer_ptr->bssload.chan_util);
3953     printMsg("Num rate %d \n", local_peer_ptr->num_rate);
3954     return;
3955 }
3956 
update_peer_info_per_link(u8 ** buf)3957 void update_peer_info_per_link(u8 **buf) {
3958     wifi_peer_info *local_peer_ptr = (wifi_peer_info*)(*buf);
3959     if (!local_peer_ptr) {
3960         printMsg("peer data not found, skip\n");
3961         return;
3962     }
3963 
3964     printPeerinfoStats(local_peer_ptr);
3965 
3966     if (local_peer_ptr->num_rate) {
3967         *buf += offsetof(wifi_peer_info, rate_stats);
3968         if (!*buf) {
3969             ALOGE("No valid rate_stats\n");
3970             return;
3971         }
3972         updateRateStats(buf, local_peer_ptr->num_rate);
3973     }
3974 }
3975 
printPerLinkStats(wifi_link_stat * local_link_ptr,int link_id)3976 void printPerLinkStats(wifi_link_stat *local_link_ptr, int link_id) {
3977     printMsg("Printing link statistics of the link:%d\n", link_id);
3978     printMsg("Identifier for the link = %d\n", local_link_ptr->link_id);
3979     printMsg("Radio on which link stats are sampled. = %d\n", local_link_ptr->radio);
3980     printMsg("Frequency on which link is operating. = %d MHz\n", local_link_ptr->frequency);
3981     printMsg("beacon_rx = %d\n", local_link_ptr->beacon_rx);
3982     printMsg("average_tsf_offset= %d\n", local_link_ptr->average_tsf_offset);
3983     printMsg("leaky_ap_detected= %d\n", local_link_ptr->leaky_ap_detected);
3984     printMsg("leaky_ap_avg_num_frames_leaked= %d\n",
3985         local_link_ptr->leaky_ap_avg_num_frames_leaked);
3986     printMsg("leaky_ap_guard_time= %d\n", local_link_ptr->leaky_ap_guard_time);
3987     printMsg("mgmt_rx= %d\n", local_link_ptr->mgmt_rx);
3988     printMsg("mgmt_action_rx= %d\n", local_link_ptr->mgmt_action_rx);
3989     printMsg("mgmt_action_tx= %d\n", local_link_ptr->mgmt_action_tx);
3990     printMsg("RSSI mgmt = %d\n", local_link_ptr->rssi_mgmt);
3991     printMsg("RSSI data = %d\n", local_link_ptr->rssi_data);
3992     printMsg("RSSI ack = %d\n", local_link_ptr->rssi_ack);
3993     printMsg("AC_BE:\n");
3994     printMsg("txmpdu = %d\n", local_link_ptr->ac[WIFI_AC_BE].tx_mpdu);
3995     printMsg("rxmpdu = %d\n", local_link_ptr->ac[WIFI_AC_BE].rx_mpdu);
3996     printMsg("mpdu_lost = %d\n", local_link_ptr->ac[WIFI_AC_BE].mpdu_lost);
3997     printMsg("retries = %d\n", local_link_ptr->ac[WIFI_AC_BE].retries);
3998     printMsg("AC_BK:\n");
3999     printMsg("txmpdu = %d\n", local_link_ptr->ac[WIFI_AC_BK].tx_mpdu);
4000     printMsg("rxmpdu = %d\n", local_link_ptr->ac[WIFI_AC_BK].rx_mpdu);
4001     printMsg("mpdu_lost = %d\n", local_link_ptr->ac[WIFI_AC_BK].mpdu_lost);
4002     printMsg("AC_VI:\n");
4003     printMsg("txmpdu = %d\n", local_link_ptr->ac[WIFI_AC_VI].tx_mpdu);
4004     printMsg("rxmpdu = %d\n", local_link_ptr->ac[WIFI_AC_VI].rx_mpdu);
4005     printMsg("mpdu_lost = %d\n", local_link_ptr->ac[WIFI_AC_VI].mpdu_lost);
4006     printMsg("AC_VO:\n");
4007     printMsg("txmpdu = %d\n", local_link_ptr->ac[WIFI_AC_VO].tx_mpdu);
4008     printMsg("rxmpdu = %d\n", local_link_ptr->ac[WIFI_AC_VO].rx_mpdu);
4009     printMsg("mpdu_lost = %d\n", local_link_ptr->ac[WIFI_AC_VO].mpdu_lost);
4010     printMsg("time slicing duty_cycle = %d\n", local_link_ptr->time_slicing_duty_cycle_percent);
4011     printMsg("Num peers = %d\n", local_link_ptr->num_peers);
4012 }
4013 
update_per_link_data(u8 ** buf,int link_id)4014 void update_per_link_data(u8 **buf, int link_id) {
4015     wifi_link_stat *local_link_ptr = (wifi_link_stat*)(*buf);
4016     if (!local_link_ptr) {
4017        printMsg("link data not found, skip\n");
4018        return;
4019     }
4020 
4021     printPerLinkStats(local_link_ptr, link_id);
4022 
4023     if (local_link_ptr->num_peers) {
4024         for (int j = 0; j < local_link_ptr->num_peers; j++) {
4025             *buf += offsetof(wifi_link_stat, peer_info);
4026             if (!*buf) {
4027                 ALOGE("No valid peer info\n");
4028                 continue;
4029             }
4030             update_peer_info_per_link(buf);
4031         }
4032     }
4033 }
4034 
onMultiLinkStatsResults(wifi_request_id id,wifi_iface_ml_stat * iface_ml_stat,int num_radios,wifi_radio_stat * radio_stat)4035 void onMultiLinkStatsResults(wifi_request_id id, wifi_iface_ml_stat *iface_ml_stat,
4036         int num_radios, wifi_radio_stat *radio_stat)
4037 {
4038     u8 *local_rx_ptr = NULL, *local_cca_ptr = NULL, *buf_ptr = NULL;
4039     int channel_size = 0, num_channels = 0;
4040     int cca_avail_size = MAX_CH_BUF_SIZE;
4041 
4042     if (!num_radios || !iface_ml_stat || !radio_stat) {
4043         ALOGE("No valid radio stat data\n");
4044         return;
4045     }
4046 
4047     radios = num_radios;
4048     local_rx_ptr = (u8*)radio_stat;
4049     local_cca_ptr = (u8*)cca_stat;
4050 
4051     for (int i = 0; i < num_radios; i++) {
4052         memset(&rx_stat[i], 0, sizeof(&rx_stat[i]));
4053         memcpy(&rx_stat[i], (u8*)local_rx_ptr, offsetof(wifi_radio_stat, channels));
4054         local_rx_ptr += offsetof(wifi_radio_stat, channels);
4055         num_channels = rx_stat[i].num_channels;
4056         if (num_channels) {
4057             channel_size = sizeof(wifi_channel_stat)*num_channels;
4058 	    if (cca_avail_size > num_channels) {
4059                 memcpy(local_cca_ptr, (u8*)local_rx_ptr, channel_size);
4060                 cca_avail_size -= num_channels;
4061             } else {
4062                 ALOGE("No space left for chan_stat!!: cca_avail: %d, req: %d\n",
4063                 cca_avail_size, num_channels);
4064                 break;
4065 	    }
4066 	}
4067         if (i == (num_radios - 1)) {
4068             break;
4069         }
4070         local_rx_ptr += channel_size;
4071         local_cca_ptr += channel_size;
4072     }
4073     /* radio stat data and channel stats data is printed in printMultiLinkStats */
4074 
4075     buf_ptr = (u8*)iface_ml_stat;
4076     ml_links = iface_ml_stat->num_links;
4077 
4078     if (ml_links) {
4079         buf_ptr += offsetof(wifi_iface_ml_stat, links);
4080         for (int i = 0; i < ml_links; i++) {
4081             if (!buf_ptr) {
4082                 ALOGE("No valid multilink data\n");
4083                 continue;
4084             }
4085             printMsg("-----------------------------------------------------\n\n");
4086             update_per_link_data(&buf_ptr, i);
4087         }
4088     }
4089 }
4090 
4091 wifi_iface_stat link_stat;
4092 int num_rate;
4093 bssload_info_t bssload;
4094 wifi_peer_info peer_info[32];
4095 wifi_rate_stat rate_stat[NUM_RATES];
4096 wifi_rate_stat eht_rate_stat[NUM_EHT_RATES];
4097 
onLinkStatsResults(wifi_request_id id,wifi_iface_stat * iface_stat,int num_radios,wifi_radio_stat * radio_stat)4098 void onLinkStatsResults(wifi_request_id id, wifi_iface_stat *iface_stat,
4099         int num_radios, wifi_radio_stat *radio_stat)
4100 {
4101     int num_peer = 0;
4102     u8 *local_rx_stat_ptr = NULL, *local_cca_ptr = NULL;
4103     int channel_size = 0, num_channels = 0;
4104     int cca_avail_size = MAX_CH_BUF_SIZE;
4105 
4106     if (!num_radios || !iface_stat || !radio_stat) {
4107         ALOGE("No valid radio stat data\n");
4108         return;
4109     }
4110 
4111     radios = num_radios;
4112     local_rx_stat_ptr = (u8*)radio_stat;
4113     local_cca_ptr = (u8*)cca_stat;
4114     for (int i = 0; i < num_radios; i++) {
4115         memset(&rx_stat[i], 0, sizeof(&rx_stat[i]));
4116         memcpy(&rx_stat[i], (u8*)local_rx_stat_ptr, offsetof(wifi_radio_stat, channels));
4117         local_rx_stat_ptr += offsetof(wifi_radio_stat, channels);
4118         num_channels = rx_stat[i].num_channels;
4119         if (num_channels) {
4120             channel_size = sizeof(wifi_channel_stat)*num_channels;
4121             if (cca_avail_size > num_channels) {
4122                 memcpy(local_cca_ptr, (u8*)local_rx_stat_ptr, channel_size);
4123                 cca_avail_size -= num_channels;
4124             } else {
4125                 ALOGE("No space left for chan_stat!!: cca_avail: %d, req: %d\n",
4126                 cca_avail_size, num_channels);
4127                 break;
4128             }
4129         }
4130         if (i == (num_radios - 1)) {
4131             break;
4132         }
4133         local_rx_stat_ptr += channel_size;
4134         local_cca_ptr += channel_size;
4135     }
4136 
4137     num_peer = iface_stat->num_peers;
4138     printMsg("onLinkStatsResults num_peer = %d \n", num_peer);
4139     memset(&link_stat, 0, sizeof(wifi_iface_stat));
4140     memcpy(&link_stat, iface_stat, sizeof(wifi_iface_stat));
4141     memcpy(peer_info, iface_stat->peer_info, num_peer*sizeof(wifi_peer_info));
4142     num_rate = peer_info[0].num_rate;
4143     printMsg("onLinkStatsResults num_rate = %d \n", num_rate);
4144 
4145     memset(&bssload, 0, sizeof(bssload_info_t));
4146     memcpy(&bssload, &iface_stat->peer_info->bssload, sizeof(bssload_info_t));
4147 
4148     if (num_rate == NUM_EHT_RATES) {
4149         memset(eht_rate_stat, 0, num_rate*sizeof(wifi_rate_stat));
4150         memcpy(&eht_rate_stat, iface_stat->peer_info->rate_stats, num_rate*sizeof(wifi_rate_stat));
4151     } else if (num_rate == NUM_RATES) {
4152         memset(rate_stat, 0, num_rate*sizeof(wifi_rate_stat));
4153         memcpy(&rate_stat, iface_stat->peer_info->rate_stats, num_rate*sizeof(wifi_rate_stat));
4154     }
4155 }
4156 
printFeatureListBitMask(void)4157 void printFeatureListBitMask(void)
4158 {
4159     printMsg("WIFI_FEATURE_INFRA              0x000000001 - Basic infrastructure mode\n");
4160     printMsg("WIFI_FEATURE_INFRA_5G           0x000000002 - Support for 5 GHz Band\n");
4161     printMsg("WIFI_FEATURE_HOTSPOT            0x000000004 - Support for GAS/ANQP\n");
4162     printMsg("WIFI_FEATURE_P2P                0x000000008 - Wifi-Direct\n");
4163     printMsg("WIFI_FEATURE_SOFT_AP            0x000000010 - Soft AP\n");
4164     printMsg("WIFI_FEATURE_GSCAN              0x000000020 - Google-Scan APIs\n");
4165     printMsg("WIFI_FEATURE_NAN                0x000000040 - Neighbor Awareness Networking\n");
4166     printMsg("WIFI_FEATURE_D2D_RTT            0x000000080 - Device-to-device RTT\n");
4167     printMsg("WIFI_FEATURE_D2AP_RTT           0x000000100 - Device-to-AP RTT\n");
4168     printMsg("WIFI_FEATURE_BATCH_SCAN         0x000000200 - Batched Scan (legacy)\n");
4169     printMsg("WIFI_FEATURE_PNO                0x000000400 - Preferred network offload\n");
4170     printMsg("WIFI_FEATURE_ADDITIONAL_STA     0x000000800 - Support for two STAs\n");
4171     printMsg("WIFI_FEATURE_TDLS               0x000001000 - Tunnel directed link setup\n");
4172     printMsg("WIFI_FEATURE_TDLS_OFFCHANNEL    0x000002000 - Support for TDLS off channel\n");
4173     printMsg("WIFI_FEATURE_EPR                0x000004000 - Enhanced power reporting\n");
4174     printMsg("WIFI_FEATURE_AP_STA             0x000008000 - Support for AP STA Concurrency\n");
4175     printMsg("WIFI_FEATURE_LINK_LAYER_STATS   0x000010000 - Link layer stats collection\n");
4176     printMsg("WIFI_FEATURE_LOGGER             0x000020000 - WiFi Logger\n");
4177     printMsg("WIFI_FEATURE_HAL_EPNO           0x000040000 - iFi PNO enhanced\n");
4178     printMsg("WIFI_FEATURE_RSSI_MONITOR       0x000080000 - RSSI Monitor\n");
4179     printMsg("WIFI_FEATURE_MKEEP_ALIVE        0x000100000 - WiFi mkeep_alive\n");
4180     printMsg("WIFI_FEATURE_CONFIG_NDO         0x000200000 - ND offload configure\n");
4181     printMsg("WIFI_FEATURE_TX_TRANSMIT_POWER  0x000400000 - apture Tx transmit power levels\n");
4182     printMsg("WIFI_FEATURE_CONTROL_ROAMING    0x000800000 - Enable/Disable firmware roaming\n");
4183     printMsg("WIFI_FEATURE_IE_WHITELIST       0x001000000 - Support Probe IE white listing\n");
4184     printMsg("WIFI_FEATURE_SCAN_RAND          0x002000000 - Support MAC & Probe Sequence Number randomization\n");
4185     printMsg("WIFI_FEATURE_SET_TX_POWER_LIMIT 0x004000000 - Support Tx Power Limit setting\n");
4186     printMsg("WIFI_FEATURE_USE_BODY_HEAD_SAR  0x008000000 - Support Using Body/Head Proximity for SAR\n");
4187     printMsg("WIFI_FEATURE_DYNAMIC_SET_MAC    0x010000000 - Support changing MAC address without iface reset(down and up)\n");
4188     printMsg("WIFI_FEATURE_SET_LATENCY_MODE   0x040000000 - Support Latency mode setting\n");
4189     printMsg("WIFI_FEATURE_P2P_RAND_MAC       0x080000000 - Support P2P MAC randomization\n");
4190     printMsg("WIFI_FEATURE_INFRA_60G          0x100000000 - Support for 60GHz Band\n");
4191 }
4192 
printRadioComboMatrix(wifi_radio_combination_matrix * rc)4193 void printRadioComboMatrix(wifi_radio_combination_matrix *rc)
4194 {
4195     u32 num_radio_combinations = rc->num_radio_combinations;
4196     wifi_radio_combination *radio_combinations = rc->radio_combinations;
4197     u32 num_radio_configurations;
4198     int i,j;
4199 
4200     printMsg("printing band info for combinations:%d\n", num_radio_combinations);
4201 
4202     for (i=0; i < num_radio_combinations; i++) {
4203         num_radio_configurations = radio_combinations->num_radio_configurations;
4204         printMsg("combination:%d num_radio_configurations:%d\n", i, num_radio_configurations);
4205         for (j=0; j < num_radio_configurations; j++) {
4206             printMsg("band:%s (%d) antenna cfg:%s (%d)\n",
4207                 BandToString(radio_combinations->radio_configurations[j].band),
4208                 radio_combinations->radio_configurations[j].band,
4209                 AntennCfgToString(radio_combinations->radio_configurations[j].antenna_cfg),
4210                 radio_combinations->radio_configurations[j].antenna_cfg);
4211         }
4212 
4213         if (j == (num_radio_combinations - 1)) {
4214             break;
4215         }
4216         radio_combinations = (wifi_radio_combination *)((u8*)radio_combinations + sizeof(u32) +
4217             (num_radio_configurations * sizeof(wifi_radio_configuration)));
4218         if (!radio_combinations) {
4219             break;
4220         }
4221     }
4222     return;
4223 }
4224 
4225 #define CHAN_STR_LEN 10
4226 static char chan_str[CHAN_STR_LEN];
4227 
frequency_to_channel(int center_freq)4228 static char* frequency_to_channel(int center_freq)
4229 {
4230     if (center_freq >= 2412 && center_freq <= 2484) {
4231         if (center_freq == 2484) {
4232             snprintf(chan_str, CHAN_STR_LEN, "2g/ch14");
4233         } else {
4234             snprintf(chan_str, CHAN_STR_LEN, "2g/ch%d", (center_freq - 2407) / 5);
4235         }
4236     } else if (center_freq >= 5180 && center_freq <= 5825) {
4237         snprintf(chan_str, CHAN_STR_LEN, "5g/ch%d", (center_freq - 5000) / 5);
4238     } else if (center_freq >= 5845 && center_freq <= 5885) {
4239         /* UNII-4 channels */
4240         snprintf(chan_str, CHAN_STR_LEN, "5g/ch%d", (center_freq - 5000) / 5);
4241     } else if (center_freq >= 5935 && center_freq <= 7115) {
4242         if (center_freq == 5935) {
4243             snprintf(chan_str, CHAN_STR_LEN, "6g/ch2");
4244         } else {
4245             snprintf(chan_str, CHAN_STR_LEN, "6g/ch%d", (center_freq - 5950) / 5);
4246         }
4247     } else {
4248         snprintf(chan_str, CHAN_STR_LEN, "Err");
4249     }
4250 
4251    return &chan_str[0];
4252 }
4253 
printMultiLinkStats(wifi_channel_stat cca_stat[],wifi_radio_stat rx_stat[],int radios)4254 void printMultiLinkStats(wifi_channel_stat cca_stat[],
4255     wifi_radio_stat rx_stat[], int radios)
4256 {
4257     int new_chan_base = 0;
4258     printMsg("\nPrinting radio statistics of multi link\n");
4259     printMsg("--------------------------------------\n");
4260     for (int i = 0; i < radios; i++) {
4261         printMsg("radio = %d\n", rx_stat[i].radio);
4262         printMsg("on time = %d\n", rx_stat[i].on_time);
4263         printMsg("tx time = %d\n", rx_stat[i].tx_time);
4264         printMsg("num_tx_levels = %d\n", rx_stat[i].num_tx_levels);
4265         printMsg("rx time = %d\n", rx_stat[i].rx_time);
4266         printMsg("SCAN\n");
4267         printMsg("on_time_scan(duration)= %d\n", rx_stat[i].on_time_scan);
4268         printMsg("on_time_nbd(duration)= %d\n", rx_stat[i].on_time_nbd);
4269         printMsg("on_time_gscan(duration)= %d\n", rx_stat[i].on_time_gscan);
4270         printMsg("on_time_roam_scan(duration)= %d\n", rx_stat[i].on_time_roam_scan);
4271         printMsg("on_time_pno_scan(duration)= %d\n", rx_stat[i].on_time_pno_scan);
4272         printMsg("on_time_hs20 = %d\n", rx_stat[i].on_time_hs20);
4273         printMsg("cca channel statistics: (num_channels: %d)\n", rx_stat[i].num_channels);
4274         for (int j = new_chan_base; j < (new_chan_base + rx_stat[i].num_channels); j++) {
4275             printMsg("center_freq=%d (%8s), radio_on_time %10d, cca_busytime %10d\n",
4276                 cca_stat[j].channel.center_freq,
4277                 frequency_to_channel(cca_stat[j].channel.center_freq),
4278                 cca_stat[j].on_time, cca_stat[j].cca_busy_time);
4279         }
4280         new_chan_base += rx_stat[i].num_channels;
4281     }
4282     printMsg("\n");
4283 }
4284 /////////////////////////////////////////////////////////////////////
printLinkStats(wifi_iface_stat * link_stat,wifi_channel_stat cca_stat[],wifi_radio_stat rx_stat[],bssload_info_t * bssload,int radios)4285 void printLinkStats(wifi_iface_stat *link_stat, wifi_channel_stat cca_stat[],
4286     wifi_radio_stat rx_stat[], bssload_info_t *bssload, int radios)
4287 {
4288     int new_chan_base = 0;
4289     printMsg("Printing link layer statistics:\n");
4290     printMsg("--------------------------------------\n");
4291     printMsg("Num peer = %d\n", link_stat->num_peers);
4292     printMsg("beacon_rx = %d\n", link_stat->beacon_rx);
4293     printMsg("RSSI = %d\n", link_stat->rssi_mgmt);
4294     printMsg("Load_info(Station Count) = %d\n", bssload->sta_count);
4295     printMsg("CCA_level(Channel Utilization) = %d\n", bssload->chan_util);
4296     printMsg("AC_BE:\n");
4297     printMsg("txmpdu = %d\n", link_stat->ac[WIFI_AC_BE].tx_mpdu);
4298     printMsg("rxmpdu = %d\n", link_stat->ac[WIFI_AC_BE].rx_mpdu);
4299     printMsg("mpdu_lost = %d\n", link_stat->ac[WIFI_AC_BE].mpdu_lost);
4300     printMsg("retries = %d\n", link_stat->ac[WIFI_AC_BE].retries);
4301     printMsg("AC_BK:\n");
4302     printMsg("txmpdu = %d\n", link_stat->ac[WIFI_AC_BK].tx_mpdu);
4303     printMsg("rxmpdu = %d\n", link_stat->ac[WIFI_AC_BK].rx_mpdu);
4304     printMsg("mpdu_lost = %d\n", link_stat->ac[WIFI_AC_BK].mpdu_lost);
4305     printMsg("AC_VI:\n");
4306     printMsg("txmpdu = %d\n", link_stat->ac[WIFI_AC_VI].tx_mpdu);
4307     printMsg("rxmpdu = %d\n", link_stat->ac[WIFI_AC_VI].rx_mpdu);
4308     printMsg("mpdu_lost = %d\n", link_stat->ac[WIFI_AC_VI].mpdu_lost);
4309     printMsg("AC_VO:\n");
4310     printMsg("txmpdu = %d\n", link_stat->ac[WIFI_AC_VO].tx_mpdu);
4311     printMsg("rxmpdu = %d\n", link_stat->ac[WIFI_AC_VO].rx_mpdu);
4312     printMsg("mpdu_lost = %d\n", link_stat->ac[WIFI_AC_VO].mpdu_lost);
4313     printMsg("time slicing duty_cycle = %d\n", link_stat->info.time_slicing_duty_cycle_percent);
4314     printMsg("\n");
4315     printMsg("Printing radio statistics:\n");
4316     printMsg("--------------------------------------\n");
4317     for (int i = 0; i < radios; i++) {
4318         printMsg("--------------------------------------\n");
4319         printMsg("radio = %d\n", rx_stat[i].radio);
4320         printMsg("on time = %d\n", rx_stat[i].on_time);
4321         printMsg("tx time = %d\n", rx_stat[i].tx_time);
4322         printMsg("num_tx_levels = %d\n", rx_stat[i].num_tx_levels);
4323         printMsg("rx time = %d\n", rx_stat[i].rx_time);
4324         printMsg("SCAN\n");
4325         printMsg("on_time_scan(duration)= %d\n", rx_stat[i].on_time_scan);
4326         printMsg("on_time_nbd(duration)= %d\n", rx_stat[i].on_time_nbd);
4327         printMsg("on_time_gscan(duration)= %d\n", rx_stat[i].on_time_gscan);
4328         printMsg("on_time_roam_scan(duration)= %d\n", rx_stat[i].on_time_roam_scan);
4329         printMsg("on_time_pno_scan(duration)= %d\n", rx_stat[i].on_time_pno_scan);
4330         printMsg("on_time_hs20 = %d\n", rx_stat[i].on_time_hs20);
4331         printMsg("cca channel statistics: (num_channels: %d)\n", rx_stat[i].num_channels);
4332         for (int j = new_chan_base; j < (new_chan_base + rx_stat[i].num_channels); j++) {
4333             printMsg("center_freq=%d (%8s), radio_on_time %10d, cca_busytime %10d\n",
4334                 cca_stat[j].channel.center_freq,
4335                 frequency_to_channel(cca_stat[j].channel.center_freq),
4336                 cca_stat[j].on_time, cca_stat[j].cca_busy_time);
4337         }
4338         new_chan_base += rx_stat[i].num_channels;
4339     }
4340     printMsg("\n");
4341     if (num_rate == NUM_EHT_RATES) {
4342         printMsg("(current BSS info: %s, %dMhz)\n",
4343             rate_stat_preamble[eht_rate_stat[RATE_SPEC_CHECK_INDEX].rate.preamble],
4344             rate_stat_bandwidth[eht_rate_stat[RATE_SPEC_CHECK_INDEX].rate.bw]);
4345     } else if (num_rate == NUM_RATES) {
4346         printMsg("(current BSS info: %s, %dMhz)\n",
4347             rate_stat_preamble[rate_stat[RATE_SPEC_CHECK_INDEX].rate.preamble],
4348             rate_stat_bandwidth[rate_stat[RATE_SPEC_CHECK_INDEX].rate.bw]);
4349     } else {
4350         printMsg("No peer found!");
4351         return;
4352     }
4353     printMsg("Printing rate statistics: num_rate %d", num_rate);
4354     printMsg("--------------------------------------\n");
4355     printMsg("%40s %12s %14s %15s\n", "TX",  "RX", "LOST", "RETRIES");
4356     for (int i=0; i < num_rate; i++) {
4357         if (num_rate == NUM_EHT_RATES) {
4358             printMsg("%-28s  %10d   %10d     %10d      %10d\n",
4359                 eht_rates[i], eht_rate_stat[i].tx_mpdu, eht_rate_stat[i].rx_mpdu,
4360                 eht_rate_stat[i].mpdu_lost, eht_rate_stat[i].retries);
4361 	} else if (num_rate == NUM_RATES) {
4362             printMsg("%-28s  %10d   %10d     %10d      %10d\n",
4363                 rates[i], rate_stat[i].tx_mpdu, rate_stat[i].rx_mpdu,
4364                 rate_stat[i].mpdu_lost, rate_stat[i].retries);
4365         }
4366     }
4367 }
4368 
getLinkStats(void)4369 void getLinkStats(void)
4370 {
4371     wifi_stats_result_handler handler;
4372     memset(&handler, 0, sizeof(handler));
4373 
4374     handler.on_link_stats_results = &onLinkStatsResults;
4375     handler.on_multi_link_stats_results = &onMultiLinkStatsResults;
4376 
4377     int result = hal_fn.wifi_get_link_stats(0, wlan0Handle, handler);
4378     if (result < 0) {
4379         printMsg("failed to get link stat - %d\n", result);
4380     } else if (!radios) {
4381         printMsg("Invalid link stat data\n");
4382     } else if (ml_links) {
4383         printMultiLinkStats(cca_stat, rx_stat, radios);
4384     } else {
4385         printLinkStats(&link_stat, cca_stat, rx_stat, &bssload, radios);
4386     }
4387 }
4388 
getChannelList(void)4389 void getChannelList(void)
4390 {
4391     wifi_channel channel[MAX_CH_BUF_SIZE] =  {0, };
4392     int num_channels = 0, i = 0;
4393 
4394     int result = hal_fn.wifi_get_valid_channels(wlan0Handle, band, MAX_CH_BUF_SIZE,
4395             channel, &num_channels);
4396     if (result < 0) {
4397         printMsg("failed to get valid channels %d\n", result);
4398         return;
4399     }
4400     printMsg("Number of channels - %d\nChannel List:\n",num_channels);
4401     for (i = 0; i < num_channels; i++) {
4402         printMsg("%d MHz\n", channel[i]);
4403     }
4404 }
4405 
getFeatureSet(void)4406 void getFeatureSet(void)
4407 {
4408     feature_set set;
4409     int result = hal_fn.wifi_get_supported_feature_set(wlan0Handle, &set);
4410 
4411     if (result < 0) {
4412         printMsg("Error %d\n",result);
4413         return;
4414     }
4415     printFeatureListBitMask();
4416     printMsg("Supported feature set bit mask - %x\n", set);
4417     return;
4418 }
4419 
getFeatureSetMatrix(void)4420 void getFeatureSetMatrix(void)
4421 {
4422     feature_set set[MAX_FEATURE_SET];
4423     int size;
4424 
4425     int result = hal_fn.wifi_get_concurrency_matrix(wlan0Handle, MAX_FEATURE_SET, set, &size);
4426 
4427     if (result < 0) {
4428         printMsg("Error %d\n",result);
4429         return;
4430     }
4431     printFeatureListBitMask();
4432     for (int i = 0; i < size; i++)
4433         printMsg("Concurrent feature set - %x\n", set[i]);
4434     return;
4435 }
4436 
getSupportedRadioMatrix(void)4437 void getSupportedRadioMatrix(void)
4438 {
4439     wifi_radio_combination_matrix *radio_matrix;
4440     u32 size, max_size = 0;
4441     int result;
4442 
4443     max_size = sizeof(wifi_radio_combination_matrix) +
4444         MAX_RADIO_COMBO*(sizeof(wifi_radio_combination) +
4445         MAX_CORE * sizeof(wifi_radio_configuration));
4446 
4447     radio_matrix = (wifi_radio_combination_matrix*)malloc(max_size);
4448     if (!radio_matrix) {
4449         printMsg("%s:Malloc failed\n",__FUNCTION__);
4450         return;
4451     }
4452     memset(radio_matrix, 0 , max_size);
4453 
4454     result = hal_fn.wifi_get_supported_radio_combinations_matrix(halHandle,
4455         max_size, &size, radio_matrix);
4456     if (!radio_matrix || !size || result < 0) {
4457         printMsg("Error %d\n", result);
4458         goto free_mem;
4459     }
4460 
4461     printRadioComboMatrix(radio_matrix);
4462 
4463 free_mem:
4464     if (radio_matrix) {
4465         free(radio_matrix);
4466     }
4467 
4468     return;
4469 }
4470 
getWakeStats()4471 int getWakeStats()
4472 {
4473     WLAN_DRIVER_WAKE_REASON_CNT *wake_reason_cnt;
4474 
4475     wake_reason_cnt = (WLAN_DRIVER_WAKE_REASON_CNT*) malloc(sizeof(WLAN_DRIVER_WAKE_REASON_CNT));
4476     if (!wake_reason_cnt) {
4477         printMsg("%s:Malloc failed\n",__FUNCTION__);
4478         return WIFI_ERROR_OUT_OF_MEMORY;
4479     }
4480     memset(wake_reason_cnt, 0 , sizeof(WLAN_DRIVER_WAKE_REASON_CNT));
4481     wake_reason_cnt->cmd_event_wake_cnt_sz = EVENT_COUNT;
4482     wake_reason_cnt->cmd_event_wake_cnt = (int*)malloc(EVENT_COUNT * sizeof(int));
4483 
4484     int result = hal_fn.wifi_get_wake_reason_stats(wlan0Handle, wake_reason_cnt);
4485     if (result < 0) {
4486         printMsg("Error %d\n",result);
4487         free(wake_reason_cnt->cmd_event_wake_cnt);
4488         free(wake_reason_cnt);
4489         return WIFI_ERROR_NOT_SUPPORTED;
4490     }
4491 
4492     printMsg(" ------- DRIVER WAKE REASON STATS -------\n");
4493     printMsg("TotalCmdWake = %d\n", wake_reason_cnt->total_cmd_event_wake);
4494     printMsg("MaxCmdEvent  = %d\n", wake_reason_cnt->cmd_event_wake_cnt_sz);
4495     printMsg("MaxCmdEventUsed = %d\n", wake_reason_cnt->cmd_event_wake_cnt_used);
4496     printMsg("-----------------------------------------------------------\n");
4497     printMsg("TotalRxDataWake = %d\n", wake_reason_cnt->total_rx_data_wake);
4498     printMsg("RxUniCnt = %d\n", wake_reason_cnt->rx_wake_details.rx_unicast_cnt);
4499     printMsg("RxMultiCnt = %d\n", wake_reason_cnt->rx_wake_details.rx_multicast_cnt);
4500     printMsg("RxBcastCnt = %d\n", wake_reason_cnt->rx_wake_details.rx_broadcast_cnt);
4501     printMsg("-----------------------------------------------------------\n");
4502     printMsg("ICMP count = %d\n", wake_reason_cnt->rx_wake_pkt_classification_info.icmp_pkt);
4503     printMsg("ICMP6 count = %d\n", wake_reason_cnt->rx_wake_pkt_classification_info.icmp6_pkt);
4504     printMsg("ICMP6 ra count = %d\n", wake_reason_cnt->rx_wake_pkt_classification_info.icmp6_ra);
4505     printMsg("ICMP6 na count = %d\n", wake_reason_cnt->rx_wake_pkt_classification_info.icmp6_na);
4506     printMsg("ICMP6 ns count = %d\n", wake_reason_cnt->rx_wake_pkt_classification_info.icmp6_ns);
4507     printMsg("-----------------------------------------------------------\n");
4508     printMsg("Rx IPV4 Mcast  = %d\n", wake_reason_cnt->rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt);
4509     printMsg("Rx IPV6 Mcast = %d\n", wake_reason_cnt->rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt);
4510     printMsg("Rx Other Mcast = %d\n", wake_reason_cnt->rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt);
4511     printMsg("-----------------------------------------------------------\n");
4512     printMsg("Events Received and received count\n");
4513     for (int i = 0; i <= wake_reason_cnt->cmd_event_wake_cnt_used; i++) {
4514         if (wake_reason_cnt->cmd_event_wake_cnt[i] != 0)
4515             printMsg("Event ID %d = %u\n", i, wake_reason_cnt->cmd_event_wake_cnt[i]);
4516     }
4517 
4518     free(wake_reason_cnt->cmd_event_wake_cnt);
4519     free(wake_reason_cnt);
4520     return WIFI_SUCCESS;
4521 }
4522 
setBlacklist(bool clear)4523 static wifi_error setBlacklist(bool clear)
4524 {
4525     if (num_blacklist_bssids == -1 && !clear)
4526         return WIFI_SUCCESS;
4527     wifi_roaming_config roam_config;
4528     cmdId = getNewCmdId();
4529     if (clear) {
4530         roam_config.num_blacklist_bssid = 0;
4531         printMsg("Clear Blacklist BSSIDs\n");
4532     } else {
4533         roam_config.num_blacklist_bssid = num_blacklist_bssids;
4534         printMsg("Setting %d Blacklist BSSIDs\n", num_blacklist_bssids);
4535     }
4536     for (int i = 0; i < num_blacklist_bssids; i++) {
4537         memcpy(&roam_config.blacklist_bssid[i], &blacklist_bssids[i],
4538         sizeof(mac_addr) );
4539     }
4540     return  hal_fn.wifi_configure_roaming(wlan0Handle, &roam_config);
4541 }
4542 
setRoamingConfiguration()4543 static wifi_error setRoamingConfiguration()
4544 {
4545     wifi_error ret;
4546     wifi_roaming_config roam_config;
4547     cmdId = getNewCmdId();
4548 
4549     roam_config.num_blacklist_bssid = num_blacklist_bssids;
4550     roam_config.num_whitelist_ssid = num_whitelist_ssids;
4551     if(num_blacklist_bssids != -1) {
4552         for (int i = 0; i < num_blacklist_bssids; i++) {
4553             memcpy(&roam_config.blacklist_bssid[i], &blacklist_bssids[i], sizeof(mac_addr) );
4554         }
4555     }
4556 
4557     if(num_whitelist_ssids != -1) {
4558         for (int j = 0; j < num_whitelist_ssids; j++) {
4559             printf("%s\n", whitelist_ssids[j]);
4560             strncpy(roam_config.whitelist_ssid[j].ssid_str, whitelist_ssids[j], (MAX_SSID_LENGTH - 1));
4561             roam_config.whitelist_ssid[j].ssid_str[MAX_SSID_LENGTH - 1] = '\0';
4562             roam_config.whitelist_ssid[j].length =
4563                 strlen(roam_config.whitelist_ssid[j].ssid_str);
4564         }
4565     }
4566 
4567     ret = hal_fn.wifi_configure_roaming(wlan0Handle, &roam_config);
4568 
4569     return ret;
4570 }
4571 
getRoamingCapabilities()4572 static wifi_error getRoamingCapabilities()
4573 {
4574     wifi_error ret;
4575     wifi_roaming_capabilities roam_capability;
4576 
4577     ret = hal_fn.wifi_get_roaming_capabilities(wlan0Handle, &roam_capability);
4578     if (ret == WIFI_SUCCESS) {
4579         printMsg("Roaming Capabilities\n"
4580             "max_blacklist_size = %d\n"
4581             "max_whitelist_size = %d\n", roam_capability.max_blacklist_size,
4582             roam_capability.max_whitelist_size);
4583     } else {
4584         printMsg("Failed to get Roaming capabilities\n");
4585     }
4586     return ret;
4587 }
4588 
setFWRoamingState(fw_roaming_state_t state)4589 static wifi_error setFWRoamingState(fw_roaming_state_t state)
4590 {
4591     wifi_error ret = WIFI_SUCCESS;
4592 
4593     return ret;
4594 }
4595 
testRssiMonitor()4596 static void testRssiMonitor()
4597 {
4598     int id = -1;
4599     wifi_rssi_event_handler handler;
4600     EventInfo info;
4601     handler.on_rssi_threshold_breached = onRssiThresholdbreached;
4602     if (rssi_monitor) {
4603         rssiMonId = getNewCmdId();
4604         wifi_error ret = hal_fn.wifi_start_rssi_monitoring(rssiMonId, wlan0Handle,
4605                     max_rssi, min_rssi, handler);
4606         if (ret != WIFI_SUCCESS) {
4607             printMsg("Failed to set RSSI monitor %d\n", ret);
4608             return;
4609         }
4610         printMsg("rssi_monitor: %d %d %d %d\n", rssi_monitor, max_rssi, min_rssi,rssiMonId);
4611         while (true) {
4612             memset(&info, 0, sizeof(info));
4613             getEventFromCache(info);
4614             if (info.type == EVENT_TYPE_RSSI_MONITOR) {
4615                 printMsg("done!!\n");
4616                 break;
4617             }
4618         }
4619     } else {
4620         if (rssiMonId == 0)
4621             id = -1;
4622         hal_fn.wifi_stop_rssi_monitoring(id, wlan0Handle);
4623     }
4624     return;
4625 }
4626 
setApfProgram(char * str,wifi_interface_handle ifHandle)4627 static wifi_error setApfProgram(char *str, wifi_interface_handle ifHandle)
4628 {
4629     u32 program_len;
4630     u8* program;
4631     wifi_error ret;
4632 
4633     if (str == NULL) {
4634         printMsg("APF program missing\n");
4635         printApfUsage();
4636         return WIFI_ERROR_UNINITIALIZED;
4637     }
4638 
4639     if (strncmp(str, "0x", 2) == 0 || strncmp(str, "0X", 2) == 0) {
4640         str = str + 2; /* Skip past 0x */
4641     }
4642     program_len = (strlen((const char *)str) / 2);
4643     program = (u8 *)malloc(program_len);
4644     if (!program) {
4645         printMsg("Memory allocation failed\n");
4646         return WIFI_ERROR_OUT_OF_MEMORY;
4647     }
4648 
4649     if ((u32)str2hex(str, (char *)program) != program_len) {
4650         printMsg("Invalid APF program\n");
4651         if (program) {
4652             free(program);
4653         }
4654         return WIFI_ERROR_INVALID_ARGS;
4655     }
4656 
4657     ret = hal_fn.wifi_set_packet_filter(ifHandle, program, program_len);
4658     if (ret != WIFI_SUCCESS) {
4659         if (program) {
4660             free(program);
4661         }
4662         printMsg("Failed to set APF program, ret = %d\n", ret);
4663         return WIFI_ERROR_NOT_SUPPORTED;
4664     }
4665 
4666     if (program) {
4667         free(program);
4668     }
4669 
4670     return ret;
4671 }
4672 
getApfCapabilities(wifi_interface_handle ifHandle)4673 static wifi_error getApfCapabilities(wifi_interface_handle ifHandle)
4674 {
4675     u32 version, max_len;
4676 
4677     wifi_error ret = hal_fn.wifi_get_packet_filter_capabilities(ifHandle,
4678         &version, &max_len);
4679     if (ret != WIFI_SUCCESS) {
4680         printMsg("Failed to get APF capability, ret = %d\n", ret);
4681         return WIFI_ERROR_NOT_SUPPORTED;
4682     }
4683     printMsg("APF capabilities, version = %u, max_len = %u bytes\n",
4684         version, max_len);
4685     return WIFI_SUCCESS;
4686 }
4687 
getApfFilterData(wifi_interface_handle ifHandle)4688 static wifi_error getApfFilterData(wifi_interface_handle ifHandle)
4689 {
4690     u8 *buf, *pc;
4691     u32 version, max_len, i;
4692     wifi_error ret;
4693 
4694     ret = hal_fn.wifi_get_packet_filter_capabilities(ifHandle,
4695             &version, &max_len);
4696     if (ret != WIFI_SUCCESS) {
4697         printMsg("Failed to get APF buffer size, ret = %d\n", ret);
4698         return WIFI_ERROR_NOT_SUPPORTED;
4699     }
4700 
4701     buf = (u8 *)malloc(max_len);
4702     if (!buf) {
4703         printMsg("Memory allocation failed\n");
4704         return WIFI_ERROR_OUT_OF_MEMORY;
4705     }
4706 
4707     ret = hal_fn.wifi_read_packet_filter(ifHandle, 0, buf, max_len);
4708     if (ret != WIFI_SUCCESS) {
4709         if (buf) {
4710             free(buf);
4711         }
4712         printMsg("Failed to get APF buffer dump, ret = %d\n", ret);
4713         return WIFI_ERROR_NOT_SUPPORTED;
4714     }
4715     printMsg("\nAPF buffer size = %u (0x%x) bytes\n\n", max_len, max_len);
4716     printMsg("APF buffer data =\n\n");
4717     for (i = 1, pc = buf; pc && (i <= max_len); pc++, i++) {
4718        printf("%02X", *pc);
4719        if (i && ((i % 64) == 0)) {
4720            printf("\n");
4721        }
4722     }
4723     printf("\n");
4724 
4725     if (buf) {
4726         free(buf);
4727     }
4728     return WIFI_SUCCESS;
4729 }
4730 
testApfOptions(int argc,char * argv[])4731 int testApfOptions(int argc, char *argv[])
4732 {
4733     void printApfUsage();          // declaration for below printUsage()
4734     /* Interface name */
4735     char iface_name[IFNAMSIZ+1];
4736     char *val_p = NULL;
4737     wifi_error ret;
4738     wifi_interface_handle ifHandle = NULL;
4739 
4740     argv++; /* skip utility */
4741     argv++; /* skip -apf command */
4742 
4743     val_p = *argv++;
4744     if (val_p != NULL) {
4745         if (!set_interface_params(iface_name, val_p, (IFNAMSIZ - 1))) {
4746             printMsg("set interface name successfull\n");
4747         } else {
4748             printMsg("Invalid  iface name\n");
4749             ret = WIFI_ERROR_INVALID_ARGS;
4750             goto usage;
4751         }
4752     }
4753 
4754     ifHandle = wifi_get_iface_handle(halHandle, iface_name);
4755     if (ifHandle == NULL) {
4756         printMsg("Invalid iface handle for the requested interface\n");
4757         ret = WIFI_ERROR_INVALID_ARGS;
4758         goto usage;
4759     } else {
4760         while ((val_p = *argv++) != NULL) {
4761             if (!val_p) {
4762                 printMsg("%s: Need value following %s\n", __FUNCTION__, val_p);
4763                 ret = WIFI_ERROR_NOT_SUPPORTED;
4764                 goto usage;
4765             }
4766             if (strcmp(val_p, "-set") == 0) {
4767                 val_p = *argv++;
4768                 if (strcmp(val_p, "program") == 0) {
4769                     val_p = *argv++;
4770                     printMsg("program = %s\n\n", val_p);
4771                     printMsg("set program capa: Iface handle = %p for the requested interface: %s\n",
4772                         ifHandle, iface_name);
4773                     if (ifHandle) {
4774                        ret = setApfProgram(val_p, ifHandle);
4775                     }
4776                 } else {
4777                     printMsg("Invalid value after program arg\n");
4778                     ret = WIFI_ERROR_INVALID_ARGS;
4779                     goto usage;
4780                 }
4781             } else if (strcmp(val_p, "-get") == 0) {
4782                 val_p = *argv++;
4783                 if (strcmp(val_p, "capa") == 0) {
4784                     printMsg("get capa: Iface handle = %p for the requested interface: %s\n",
4785                         ifHandle, iface_name);
4786                     if (ifHandle) {
4787                         ret = getApfCapabilities(ifHandle);
4788                     }
4789                 } else if (strcmp(val_p, "data") == 0) {
4790                     printMsg("get data: Iface handle = %p for the requested interface: %s\n",
4791                         ifHandle, iface_name);
4792                     if (ifHandle) {
4793                         ret = getApfFilterData(ifHandle);
4794                     }
4795                 } else {
4796                     printMsg("Invalid value for get cmd\n");
4797                     ret = WIFI_ERROR_INVALID_ARGS;
4798                     goto usage;
4799                 }
4800             } else {
4801                 printMsg("Invalid option for apf cmd\n");
4802                 ret = WIFI_ERROR_INVALID_ARGS;
4803                 goto usage;
4804             }
4805         }
4806     }
4807 
4808 usage:
4809     printApfUsage();
4810     return WIFI_ERROR_INVALID_ARGS;
4811 }
4812 
setDscpMap(s32 start,s32 end,s32 ac)4813 static int setDscpMap(s32 start, s32 end, s32 ac)
4814 {
4815     void printUsage();          // declaration for below printUsage()
4816     int ret;
4817 
4818     if (start == -1 || end == -1 || ac == -1) {
4819         printMsg("DSCP param missing\n");
4820         printUsage();
4821         return WIFI_ERROR_UNINITIALIZED;
4822     }
4823 
4824     ret = hal_fn.wifi_map_dscp_access_category(halHandle, start, end, ac);
4825     if (ret != WIFI_SUCCESS) {
4826         printMsg("Failed to set DSCP: %d\n", ret);
4827         return WIFI_ERROR_UNKNOWN;
4828     }
4829     return WIFI_SUCCESS;
4830 }
4831 
resetDscpMap()4832 static int resetDscpMap()
4833 {
4834     int ret;
4835 
4836     ret = hal_fn.wifi_reset_dscp_mapping(halHandle);
4837     if (ret != WIFI_SUCCESS) {
4838         printMsg("Failed to reset DSCP: %d\n", ret);
4839         return WIFI_ERROR_UNKNOWN;
4840     }
4841     return WIFI_SUCCESS;
4842 }
4843 
setChannelAvoidance(u32 num,wifi_coex_unsafe_channel configs[],u32 mandatory)4844 static int setChannelAvoidance(u32 num, wifi_coex_unsafe_channel configs[], u32 mandatory)
4845 {
4846     int ret;
4847 
4848     ret = hal_fn.wifi_set_coex_unsafe_channels(halHandle, num, configs, mandatory);
4849     if (ret != WIFI_SUCCESS) {
4850         printMsg("Failed to set Channel Avoidance: %d\n", ret);
4851         return WIFI_ERROR_UNKNOWN;
4852     }
4853     return WIFI_SUCCESS;
4854 }
4855 
testSarOptions(int argc,char * argv[])4856 void testSarOptions(int argc, char *argv[])
4857 {
4858     void printUsage();          // declaration for below printUsage()
4859     wifi_power_scenario mWifi_power_scenario;
4860     wifi_error res;
4861     int scenario;
4862 
4863     if (argc < 2) {
4864         goto usage;
4865     }
4866 
4867     if ((argc > 2) && (strcmp(argv[1], "enable") == 0)) {
4868         scenario = atoi(argv[2]);
4869         if ((scenario < WIFI_POWER_SCENARIO_DEFAULT) || (scenario > SAR_CONFIG_SCENARIO_COUNT)) {
4870             printMsg("Unsupported tx power value:%d: Allowed range -1 to 99\n", scenario);
4871             return;
4872         }
4873         mWifi_power_scenario = (wifi_power_scenario)scenario;
4874         res = hal_fn.wifi_select_tx_power_scenario(wlan0Handle, mWifi_power_scenario);
4875     } else if ((strcmp(argv[1], "disable") == 0)) {
4876         res = hal_fn.wifi_reset_tx_power_scenario(wlan0Handle);
4877     } else {
4878         goto usage;
4879     }
4880 
4881     if (res == WIFI_SUCCESS) {
4882         printMsg("Success to execute sar test command\n");
4883     } else {
4884         printMsg("Failed to execute sar test command, res = %d\n", res);
4885     }
4886     return;
4887 
4888 usage:
4889     printUsage();
4890     return;
4891 }
4892 
testThermalMitigationOptions(int argc,char * argv[])4893 void testThermalMitigationOptions(int argc, char *argv[])
4894 {
4895   void printUsage();  //declaration for below printUsage()
4896   wifi_thermal_mode mode;
4897   wifi_error result;
4898 
4899   if (argc < 2) {
4900       goto usage;
4901   }
4902 
4903   if (strcmp(argv[1], "none") == 0) {
4904       mode = WIFI_MITIGATION_NONE;
4905   } else if (strcmp(argv[1], "light") == 0) {
4906       mode = WIFI_MITIGATION_LIGHT;
4907   } else if (strcmp(argv[1], "moderate") == 0) {
4908       mode = WIFI_MITIGATION_MODERATE;
4909   } else if (strcmp(argv[1], "severe") == 0) {
4910       mode = WIFI_MITIGATION_SEVERE;
4911   } else if (strcmp(argv[1], "critical") == 0) {
4912       mode = WIFI_MITIGATION_CRITICAL;
4913   } else if (strcmp(argv[1], "emergency") == 0) {
4914       mode = WIFI_MITIGATION_EMERGENCY;
4915   } else {
4916       printMsg("unknown thermal mode %s\n", argv[1]);
4917       goto usage;
4918   }
4919 
4920   result = hal_fn.wifi_set_thermal_mitigation_mode(halHandle, mode, 0);
4921   if (result == WIFI_ERROR_NONE) {
4922       printMsg("Success set thermal mode\n");
4923   } else {
4924       printMsg("Failed set thermal mode, result = %d\n", result);
4925   }
4926   return;
4927 
4928 usage:
4929   printUsage();
4930 }
4931 
testLatencyModeOptions(int argc,char * argv[])4932 void testLatencyModeOptions(int argc, char *argv[])
4933 {
4934     void printUsage();          // declaration for below printUsage()
4935     wifi_latency_mode mWifi_latency_mode;
4936     wifi_error res;
4937 
4938     if (argc < 2) {
4939         goto usage;
4940     }
4941 
4942     if (strcmp(argv[1], "normal") == 0) {
4943         mWifi_latency_mode = WIFI_LATENCY_MODE_NORMAL;
4944     } else if (strcmp(argv[1], "low") == 0) {
4945         mWifi_latency_mode = WIFI_LATENCY_MODE_LOW;
4946     } else if (strcmp(argv[1], "ultra-low") == 0) {
4947         mWifi_latency_mode = (wifi_latency_mode)2 ; //TODO: To be removed
4948     } else {
4949         goto usage;
4950     }
4951 
4952     res = hal_fn.wifi_set_latency_mode(wlan0Handle, mWifi_latency_mode);
4953     if (res == WIFI_SUCCESS) {
4954         printMsg("Success to execute set wifi latency mode test command\n");
4955     } else {
4956         printMsg("Failed to execute set wifi latency mode test command, res = %d\n", res);
4957     }
4958     return;
4959 
4960 usage:
4961     printUsage();
4962     return;
4963 }
4964 
testDscpOptions(int argc,char * argv[])4965 void testDscpOptions(int argc, char *argv[])
4966 {
4967     void printUsage();          // declaration for below printUsage()
4968     int j = 1;
4969     s32 start = -1;
4970     s32 end = -1;
4971     s32 ac = -1;
4972 
4973     if (argc < 3) {
4974         goto usage;
4975     }
4976 
4977     if ((strcmp(argv[j], "-reset") == 0) && (argc == 3)) {
4978         resetDscpMap();
4979     } else if ((strcmp(argv[j], "-set") == 0) && (argc == 9)) {
4980         if ((strcmp(argv[++j], "-s") == 0) && isdigit(argv[j+1][0]))
4981             start = atoi(argv[++j]);
4982         if ((strcmp(argv[++j], "-e") == 0) && isdigit(argv[j+1][0]))
4983             end = atoi(argv[++j]);
4984         if ((strcmp(argv[++j], "-ac") == 0) && isdigit(argv[j+1][0]))
4985             ac = atoi(argv[++j]);
4986         setDscpMap(start, end, ac);
4987     } else {
4988         goto usage;
4989     }
4990     return;
4991 
4992 usage:
4993     printUsage();
4994     return;
4995 }
4996 
printTxPowerUsage()4997 static void printTxPowerUsage() {
4998     printf("Usage: halutil [OPTION]\n");
4999     printf(" -tx_pwr_cap -enable\n");
5000     printf(" -tx_pwr_cap -disable\n");
5001     return;
5002 }
5003 
printApfUsage()5004 static void printApfUsage() {
5005     printf("Usage: halutil [OPTION]\n");
5006     printf(" -apf [-ifname] <interface name> [-get] [capa]\n");
5007     printf(" -apf [-ifname] <interface name> [-get] [data]\n");
5008     printf(" -apf [-ifname] <interface name> [-set] [program] <bytecodes>\n");
5009     return;
5010 }
5011 
printTwtUsage()5012 static void printTwtUsage() {
5013     printf("Usage: halutil [OPTION]\n");
5014     printf("halutil -twt -setup -config_id <> -neg_type <0 for individual TWT, 1 for broadcast TWT> "
5015             "-trigger_type <0 for non-triggered TWT, 1 for triggered TWT> "
5016             "-wake_dur_us <> -wake_int_us <> -wake_int_min_us <> "
5017             "-wake_int_max_us <> -wake_dur_min_us <> -wake_dur_max_us <> "
5018             "-avg_pkt_size <> -avg_pkt_num <> -wake_time_off_us <>\n");
5019     printf("halutil -twt -info_frame -config_id <>"
5020             " -all_twt <0 for individual setp request, 1 for all TWT> -resume_time_us <>\n");
5021     printf("halutil -twt -teardown -config_id <> -all_twt <> "
5022             " -neg_type <0 for individual TWT, 1 for broadcast TWT>\n");
5023     printf("halutil -twt -get_stats -config_id <>\n");
5024     printf("halutil -twt -clear_stats -config_id <>\n");
5025     printf("halutil -get_capa_twt\n");
5026     printf("halutil -twt -event_chk\n");
5027     return;
5028 }
5029 
printChreNanRttUsage()5030 static void printChreNanRttUsage() {
5031     printf("Usage: halutil [OPTION]\n");
5032     printf("halutil -chre_nan_rtt -enable\n");
5033     printf("halutil -chre_nan_rtt -disable\n");
5034     printf("halutil -chre -register\n");
5035     return;
5036 }
5037 
5038 void
bandstr_to_macband(char * band_str,wlan_mac_band * band)5039 bandstr_to_macband(char *band_str, wlan_mac_band *band)
5040 {
5041     if (!strcasecmp(band_str, "a")) {
5042         *band = WLAN_MAC_5_0_BAND;
5043     } else if (!strcasecmp(band_str, "b")) {
5044         *band = WLAN_MAC_2_4_BAND;
5045     } else if (!strcasecmp(band_str, "6g")) {
5046         *band = WLAN_MAC_6_0_BAND;
5047     } else if (!strcasecmp(band_str, "60")) {
5048         *band = WLAN_MAC_60_0_BAND;
5049     }
5050 }
5051 void
bandstr_to_band(char * band_str,u32 * band)5052 bandstr_to_band(char *band_str, u32 *band)
5053 {
5054    if (!strcasecmp(band_str, "a")) {
5055        *band = WIFI_BAND_A;
5056    } else if (!strcasecmp(band_str, "b")) {
5057        *band = WIFI_BAND_BG;
5058    } else if (!strcasecmp(band_str, "all")) {
5059        *band = WIFI_BAND_ABG;
5060    } else {
5061        *band = WIFI_BAND_UNSPECIFIED;
5062    }
5063 }
5064 
parse_unsafe(char * val_p,wifi_coex_unsafe_channel ca_configs[],int * idx)5065 void parse_unsafe(char *val_p, wifi_coex_unsafe_channel ca_configs[], int *idx)
5066 {
5067    char *space_end;
5068    char *comma_end;
5069    char *space = strtok_r(val_p, ":", &space_end);
5070    wlan_mac_band band;
5071    while (space != NULL) {
5072        char *token = strtok_r(space, ",", &comma_end);
5073        if (!token) {
5074            printf("Need 3 values\n");
5075            return;
5076        }
5077        bandstr_to_macband(token, &band);
5078        if (band != WLAN_MAC_2_4_BAND && band != WLAN_MAC_5_0_BAND) {
5079            printMsg("Unsupported band\n");
5080            return;
5081        }
5082        ca_configs[*idx].band = band;
5083        token = strtok_r(NULL, ",", &comma_end);
5084        if (!token) {
5085            printf("Need 3 values\n");
5086            return;
5087        }
5088        ca_configs[*idx].channel = atoi(token);
5089        token = strtok_r(NULL, ",", &comma_end);
5090        if (!token) {
5091            printf("Need 3 values\n");
5092            return;
5093        }
5094        ca_configs[*idx].power_cap_dbm = atoi(token);
5095 
5096        token = strtok_r(NULL, ",", &comma_end);
5097        if (token) {
5098            printf("Need only 3 values\n");
5099            return;
5100        }
5101        (*idx)++;
5102 
5103        space = strtok_r(NULL, ":", &space_end);
5104    }
5105 }
5106 
5107 
testChannelAvoidanceOptions(int argc,char * argv[])5108 void testChannelAvoidanceOptions(int argc, char *argv[])
5109 {
5110     char *param;
5111     char *val_p;
5112     wifi_coex_unsafe_channel ca_configs[MAX_CH_AVOID];
5113     u32 mandatory;
5114     int idx = 0;
5115     memset(ca_configs, 0, MAX_CH_AVOID * sizeof(wifi_coex_unsafe_channel));
5116 
5117     argv++;
5118 
5119     while ((param = *argv++) != NULL) {
5120         val_p = *argv++;
5121         if (!val_p || *val_p == '-') {
5122             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
5123             return;
5124         }
5125 
5126         if (!strncmp(param, "-unsafe", 7)) {
5127             parse_unsafe(val_p, ca_configs, &idx);
5128         } else if (!strncmp(param, "-m", 2)) {
5129             mandatory = atoi(val_p);
5130         }
5131     }
5132 
5133     for (int i=0; i<idx; i++) {
5134         printMsg("CONFIG  %d %d %d\n",
5135             ca_configs[i].band, ca_configs[i].channel, ca_configs[i].power_cap_dbm);
5136     }
5137 
5138     setChannelAvoidance(idx, ca_configs, mandatory);
5139     return;
5140 }
5141 
5142 void
bandstr_to_wlan_mac_band(char * band_str,u32 * band)5143 bandstr_to_wlan_mac_band(char *band_str, u32 *band)
5144 {
5145    if (!strcasecmp(band_str, "2g")) {
5146        *band = WLAN_MAC_2_4_BAND;
5147    } else if (!strcasecmp(band_str, "5g")) {
5148        *band = WLAN_MAC_5_0_BAND;
5149    } else if (!strcasecmp(band_str, "6g")) {
5150        *band = WLAN_MAC_6_0_BAND;
5151    }
5152 }
5153 
5154 void
ifacestr_to_wifi_interface_mode(char * iface_str,u8 * mode)5155 ifacestr_to_wifi_interface_mode(char *iface_str, u8 *mode)
5156 {
5157    if (!strcasecmp(iface_str, "sta")) {
5158        *mode = WIFI_INTERFACE_STA;
5159    } else if (!strcasecmp(iface_str, "softap")) {
5160        *mode = WIFI_INTERFACE_SOFTAP;
5161    } else if (!strcasecmp(iface_str, "ibss")) {
5162        *mode = WIFI_INTERFACE_IBSS;
5163    } else if (!strcasecmp(iface_str, "p2p_cli")) {
5164        *mode = WIFI_INTERFACE_P2P_CLIENT;
5165    } else if (!strcasecmp(iface_str, "p2p_go")) {
5166        *mode = WIFI_INTERFACE_P2P_GO;
5167    } else if (!strcasecmp(iface_str, "nan")) {
5168        *mode = WIFI_INTERFACE_NAN;
5169    } else if (!strcasecmp(iface_str, "mesh")) {
5170        *mode = WIFI_INTERFACE_MESH;
5171    } else if (!strcasecmp(iface_str, "tdls")) {
5172        *mode = WIFI_INTERFACE_TDLS;
5173    } else {
5174        printMsg("Incorrect iface type."
5175            " ex: sta/softap/ibss/p2p_cli/p2p_go/nan/mesh/tdls\n");
5176        *mode = WIFI_INTERFACE_UNKNOWN;
5177    }
5178 }
5179 
usable_channel_parse_band(char * val_p)5180 u32 usable_channel_parse_band(char *val_p)
5181 {
5182     char *delim_end;
5183     char *delim = strtok_r(val_p, ",", &delim_end);
5184     u32 band;
5185     u32 band_mask = 0;
5186     while (delim != NULL) {
5187         band = 0;
5188         bandstr_to_wlan_mac_band(delim, &band);
5189         if (band) {
5190             band_mask |= band;
5191         }
5192         delim = strtok_r(NULL, ",", &delim_end);
5193     }
5194     return band_mask;
5195 }
5196 
usable_channel_parse_iface(char * val_p)5197 u32 usable_channel_parse_iface(char *val_p)
5198 {
5199     char *delim_end;
5200     char *delim = strtok_r(val_p, ",", &delim_end);
5201     u8 iface_mode;
5202     u32 iface_mode_mask = 0;
5203     while (delim != NULL) {
5204         iface_mode = 0;
5205         ifacestr_to_wifi_interface_mode(delim, &iface_mode);
5206         if (iface_mode != WIFI_INTERFACE_UNKNOWN) {
5207             iface_mode_mask |= (1 << iface_mode);
5208             delim = strtok_r(NULL, ",", &delim_end);
5209         }
5210     }
5211     return iface_mode_mask;
5212 }
5213 
testUsableChannelOptions(int argc,char * argv[])5214 static wifi_error testUsableChannelOptions(int argc, char *argv[])
5215 {
5216     char *param;
5217     char *val_p;
5218     u32 band_mask;
5219     u32 iface_mode_mask;
5220     u32 filter_mask;
5221     u32 max_size = 0;
5222     u32 size;
5223     wifi_error ret;
5224     wifi_usable_channel* channels = NULL;
5225 
5226     argv++;
5227 
5228     while ((param = *argv++) != NULL) {
5229         val_p = *argv++;
5230         if (!val_p || *val_p == '-') {
5231             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
5232             return WIFI_ERROR_INVALID_ARGS;
5233         }
5234 
5235         if (!strncmp(param, "-b", 2)) {
5236             band_mask = usable_channel_parse_band(val_p);
5237         } else if (!strncmp(param, "-i", 2)) {
5238             iface_mode_mask = usable_channel_parse_iface(val_p);
5239         } else if (!strncmp(param, "-f", 2)) {
5240             filter_mask = atoi(val_p);
5241         } else if (!strncmp(param, "-m", 2)) {
5242             max_size = atoi(val_p);
5243         }
5244     }
5245 
5246     printMsg("Usable channel param BAND:%d IFACE:%d FILTER:%d MAX_SIZE:%d\n", band_mask, iface_mode_mask, filter_mask, max_size);
5247     if (max_size == 0) {
5248         printMsg("Max size should be bigger than 0\n");
5249         return WIFI_ERROR_INVALID_ARGS;
5250     }
5251     if (band_mask == 0) {
5252         printMsg("Band mask should be bigger than 0\n");
5253         return WIFI_ERROR_INVALID_ARGS;
5254     }
5255 
5256     channels = (wifi_usable_channel *)malloc(sizeof(wifi_usable_channel) * max_size);
5257     if (!channels) {
5258         printMsg("Failed to alloc channels\n");
5259         return WIFI_ERROR_OUT_OF_MEMORY;
5260     }
5261 
5262     memset(channels, 0, sizeof(wifi_usable_channel) * max_size);
5263 
5264     printMsg("Call wifi_get_usable_channels\n");
5265     ret = hal_fn.wifi_get_usable_channels(halHandle, band_mask, iface_mode_mask, filter_mask, max_size, &size, channels);
5266     if (ret == WIFI_SUCCESS) {
5267         printMsg("Usable channel success: size:%d max_size:%d\n", size, max_size);
5268 
5269         for (unsigned int i=0; i < size; i++) {
5270             printMsg("[%d] freq=%d, width=%d(%s), iface=%d ",
5271                     i+1, channels[i].freq, channels[i].width,
5272                     RBchanWidthToString(channels[i].width), channels[i].iface_mode_mask);
5273             if (channels[i].iface_mode_mask & (1 << WIFI_INTERFACE_STA)) {
5274                 printMsg("STA ");
5275             }
5276             if (channels[i].iface_mode_mask & (1 << WIFI_INTERFACE_SOFTAP)) {
5277                 printMsg("SOFTAP ");
5278             }
5279             if (channels[i].iface_mode_mask & (1 << WIFI_INTERFACE_IBSS)) {
5280                 printMsg("IBSS ");
5281             }
5282             if (channels[i].iface_mode_mask & (1 << WIFI_INTERFACE_P2P_CLIENT)) {
5283                 printMsg("P2P_CLI ");
5284             }
5285             if (channels[i].iface_mode_mask & (1 << WIFI_INTERFACE_P2P_GO)) {
5286                 printMsg("P2P_GO ");
5287             }
5288             if (channels[i].iface_mode_mask & (1 << WIFI_INTERFACE_NAN)) {
5289                 printMsg("NAN ");
5290             }
5291             if (channels[i].iface_mode_mask & (1 << WIFI_INTERFACE_MESH)) {
5292                 printMsg("MESH ");
5293             }
5294             if (channels[i].iface_mode_mask & (1 << WIFI_INTERFACE_TDLS)) {
5295                 printMsg("TDLS ");
5296             }
5297             printMsg("\n");
5298         }
5299     } else {
5300         printMsg("Failed to get usable channels\n");
5301     }
5302 
5303     free(channels);
5304 
5305     return ret;
5306 }
5307 
testTxPowerLimitOptions(int argc,char * argv[])5308 void testTxPowerLimitOptions(int argc, char *argv[])
5309 {
5310     void printUsage();          // declaration for below printUsage()
5311     wifi_error res;
5312 
5313     if (argc < 2) {
5314         goto usage;
5315     }
5316 
5317     if ((strcmp(argv[1], "-enable") == 0)) {
5318         res = hal_fn.wifi_enable_tx_power_limits(wlan0Handle, true);
5319     } else if ((strcmp(argv[1], "-disable") == 0)) {
5320         res = hal_fn.wifi_enable_tx_power_limits(wlan0Handle, false);
5321     } else {
5322         goto usage;
5323     }
5324 
5325     if (res == WIFI_SUCCESS) {
5326         printMsg("Success to execute tx power limit command\n");
5327     } else {
5328         printMsg("Failed to execute tx power limit command, res = %d\n", res);
5329     }
5330     return;
5331 
5332 usage:
5333     printUsage();
5334     return;
5335 }
5336 
printUsage()5337 void printUsage() {
5338     printf("Usage:  halutil [OPTION]\n");
5339     printf(" -v               print version\n");
5340     printf(" -s               start AP scan test\n");
5341     printf(" -swc             start Significant Wifi change test\n");
5342     printf(" -h               start Hotlist APs scan test\n");
5343     printf(" -ss              stop scan test\n");
5344     printf(" -max_ap          Max AP for scan \n");
5345     printf(" -base_period     Base period for scan \n");
5346     printf(" -threshold       Threshold scan test\n");
5347     printf(" -avg_RSSI        samples for averaging RSSI\n");
5348     printf(" -ap_loss         samples to confirm AP loss\n");
5349     printf(" -ap_breach       APs breaching threshold\n");
5350     printf(" -ch_threshold    Change in threshold\n");
5351     printf(" -wt_event        Waiting event for test\n");
5352     printf(" -low_th          Low threshold for hotlist APs\n");
5353     printf(" -hight_th        High threshold for hotlist APs\n");
5354     printf(" -hotlist_bssids  BSSIDs for hotlist test\n");
5355     printf(" -stats       print link layer statistics\n");
5356     printf(" -get_ch_list <a/bg/abg/a_nodfs/abg_nodfs/dfs/"
5357             "6g/a6g_nodfs/all_nodfs/all>  Get channel list\n");
5358     printf(" -get_feature_set  Get Feature set\n");
5359     printf(" -get_feature_matrix  Get concurrent feature matrix\n");
5360     printf(" -get_wake_stats  print wake reason statistics\n");
5361     printf(" -rtt [-get_ch_list <a/bg/abg/a_nodfs/abg_nodfs/dfs/"
5362             "6g/a6g_nodfs/all_nodfs/all>] [-i <burst_period of 100ms unit> [0 - 31] ]"
5363             "    [-n <exponents of 2 = (num_bursts)> [0 - 15]]\n"
5364             "    [-f <num_frames_per_burst>] [-r <num_retries_per_ftm>]\n"
5365             "    [-m <num_retries_per_ftmr>] [-b <burst_duration [2-11 or 15]>]"
5366             "    [-max_ap <count of allowed max AP>] [-l <file to read>] [-o <file to be stored>]\n");
5367     printf(" -cancel_rtt      cancel current RTT process\n");
5368     printf(" -enable_resp     enables the responder\n");
5369     printf(" -cancel_resp     cancel the responder\n");
5370     printf(" -get_responder_info    return the responder info\n");
5371     printf(" -rtt -sta/-nan <peer mac addr> <channel> [ <bandwidth> [0 - 2]] <is_6g>"
5372         "  bandwidth - 0 for 20, 1 for 40 , 2 for 80 . is_6g = 1 if channel is 6G\n");
5373     printf(" -get_capa_rtt Get the capability of RTT such as 11mc");
5374     printf(" -scan_mac_oui XY:AB:CD\n");
5375     printf(" -nodfs <0|1>     Turn OFF/ON non-DFS locales\n");
5376     printf(" -country <alpha2 country code> Set country\n");
5377     printf(" -ePNO Configure ePNO SSIDs\n");
5378     printf(" -blacklist_bssids blacklist bssids\n");
5379     printf(" -whitelist_ssids set whitelist ssids\n"
5380            " -whitelist_ssids ssid1 ssid2 ...\n");
5381     printf(" -get_roaming_capabilities get roaming capabilities\n");
5382     printf(" -set_fw_roaming_state set FW roaming state\n");
5383     printf(" -logger [-start] [-d <debug_level> -f <flags> -i <max_interval_sec>\n"
5384            "                   -s <min_data_size> -n <ring_name>]\n"
5385            "                  [pktmonitor]\n"
5386            "         [-get]   [fw] [driver] [feature] [memdump -o <filename>]\n"
5387            "                  [ringstatus] [ringdata -n <ring_name>]\n"
5388            "                  [txfate -n <no of pkts> -f <filename>]\n"
5389            "                  [rxfate -n <no of pkts> -f <filename>]\n"
5390            "         [-set]   [loghandler] [alerthandler]\n");
5391     printf(" -rssi_monitor enable/disable\n");
5392     printf(" -max_rssi max rssi threshold for RSSI monitor\n");
5393     printf(" -min_rssi min rssi threshold for RSSI monitor\n");
5394     printf(" -mkeep_alive [-start] <index (1 to 3)> <period_msec> <src_mac> <dst_mac> <ether_type>"
5395                                    "[IP packet contents by Hexa format string]\n");
5396     printf("              [-stop]  <index (1 to 3)>\n");
5397     printf("    e.g., -mkeep_alive -start 1 20000 000f66f45b7e 0014a54b164f 0800 4500001e0000400040"
5398            "11c52a0a8830700a88302513c413c4000a00000a0d\n");
5399     printf(" -nd_offload <0|1>   enable/disable ND offload feature\n"
5400            "                     enable also triggers IPv6 address update\n");
5401     printf(" -latency_mode set latency mode WIFI_LATENCY_MODE_NORMAL/WIFI_LATENCY_MODE_LOW on particular interface\n"
5402            " -latency_mode <interface_name> <low/normal/ultra-low mode>\n");
5403     printf(" -sar enable <wifi_power_scenario -1 to 99>\n");
5404     printf(" -sar disable\n");
5405     printf(" -thermal <mode (none/light/moderate/severe/critical/emergency)>\n");
5406     printf(" -nan [-enable] [-master_pref <master pref (2 to 254)>]\n"
5407             "                [-clus_id <cluster ID (50:6F:9A:01:XX:XX)]>\n"
5408             "                [-cluster_low <0 to 0xffff> -cluster_high <0 to 0xffff>\n"
5409             "                [-nan_addr <nan interface mac address(XX:XX:XX:XX:XX:XX)]>\n"
5410             "                [-dual_band <0/1>]\n"
5411             "                [-24g_chan <2.4GHz channel in MHz >]\n"
5412             "                [-5g_chan <5GHz channel in MHz >]\n"
5413             "                [-hc_limit <hop count limit>]\n"
5414             "                [-warmup_time <warm up time>]  [-disc_ind_cfg <0 to 7>]\n"
5415             "                [-random_factor <random factor value>]\n"
5416             "                [-rssi_close_2dot4g_val  <value>] [-rssi_middle_2dot4g_val <value>]\n"
5417             "                [-rssi_proximity_2dot4g_val <value>] [-support_2dot4g_val <0/1>]\n"
5418             "                [-beacon_2dot4g_val <0/1>] [-sdf_2dot4g_val <0/1>]\n"
5419             "                [-beacon_5g_val <0/1>] [-sdf_5g_val <0/1>] [-rssi_close_5g_val <RSSI value>]\n"
5420             "                [-rssi_middle_5g_val <RSSI value>] [-rssi_close_proximity_5g_val  <RSSI value>]\n"
5421             "                [-rssi_window_size_val <value>] [-config_cluster_attribute_val <0/1>]\n"
5422             "                [-dwell_time <value in ms>] [-scan_period <value>] [-sid_flag <0/1>] [-sid_count <1 to 127>]\n"
5423             "                [-sub_sid_flag <0/1>] [-sub_sid_count <1 to 127>]\n"
5424             "                [-dwell_time_5g <value in ms>] [-scan_period_5g <value>]\n"
5425             "                [-awake_dw_2g <value> -awake_dw_5g <value>]\n"
5426             "                [-instant_mode <0-disable, 1-enable>]\n"
5427             "                [-instant_chan <2.4/5GHz channel in MHz >]\n");
5428     printf(" -nan [-disable]\n");
5429     printf(" -nan [-config] [-sid_flag <0/1>]\n"
5430             "                [-sid_count <1 to 127>]\n"
5431             "                [-sub_sid_flag <0/1>] [-sub_sid_count <1 to 127>]\n"
5432             "                [-rssi_proximity <rssi_proximity value>]\n"
5433             "                [-numchans <No of channels> -entry_control <Availability interval duration>]\n"
5434             "                [-channel <Channel value in MHz> -avail_interval_bitmap <u32 value>]\n"
5435             "                [-master_pref <master_pref>]\n"
5436             "                [-rssi_close_prox_5g <rssi_close_prox_5g value>]\n"
5437             "                [-rssi_window_size_val <rssi_window_size_val>]\n"
5438             "                [-dwell_time <dwell_time value in ms>\n"
5439             "                [-scan_period <scan_period  value>]\n"
5440             "                [-dwell_time_5g <value in ms>] [-scan_period_5g <value>]\n"
5441             "                [-random_factor <random_factor value>]\n"
5442             "                [-hc_limit <hc_limit>]  [-disc_ind_cfg <0 to 7>]\n"
5443             "                [-awake_dw_2g <value> -awake_dw_5g <value>]\n"
5444             "                [-instant_mode <0-disable, 1-enable>]\n"
5445             "                [-instant_chan <2.4/5GHz channel in MHz >]\n");
5446     printf(" -nan [-publish] [-svc <svc_name>] [-info <svc info>\n"
5447             "                [-pub_type <0/1/2>] [-pub_count <val>] [-rssi_thresh_flag <0/1>]\n"
5448             "                [-tx_type <0/1>] [-ttl <val>] [-svc_awake_dw <val>] [-match_ind <0/1/2>]\n"
5449             "                [-match_rx <0/ascii str>] [-match_tx <0/ascii str>]  [-passphrase <Passphrase value, len must not be less than 8 or greater than 63>]\n"
5450             "                [-recv_flag <0 to 15>] [-csid <cipher suite type 0/1/2/4/8>] [-key_type <1 or 2>] [-pmk <PMK value>]\n"
5451             "                [-scid <scid value>] [-dp_type <0-Unicast, 1-multicast>]\n"
5452             "                [-secure_dp <0-No security, 1-Security>] [-ranging <0-disable, 1-enable>)]\n"
5453             "                [-ranging_intvl [intrvl in ms betw two ranging measurements] -ranging_ind \n"
5454             "                [BIT0 - Continuous Ranging event notification, BIT1 - Ingress distance is <=, BIT2 - Egress distance is >=.]\n"
5455             "                [-ingress [Ingress distance in centimeters] \n"
5456             "                [ -egress [Egress distance in centimeters] \n"
5457             "                [-auto_dp_accept [0 - User response required to accept dp, 1 - User response not required to accept dp] \n");
5458     printf(" -nan [-subscribe] [-svc <svc_name>] [-info <svc info>\n"
5459             "                [-sub_type <0/1>] [-sub_count <val>] [-pub_ssi <0/1>]\n"
5460             "                [-ttl <val>] [-svc_awake_dw <val>] [-match_ind <0/1/2>]\n"
5461             "                [-match_rx <0/ascii str>] [-match_tx <0/ascii str>]\n"
5462             "                [-mac_list <addr>] [-srf_use <0/1>] [-rssi_thresh_flag <0/1>]]\n"
5463             "                [-srf_include <0/1>] [-srf_type <0/1>] [-recv_flag <0 to 7>]\n"
5464             "                [-csid <cipher suite type 0/1/2/4/8>]  [-key_type <1 or 2>]\n"
5465             "                [-scid <scid value>] [-dp_type <0-Unicast,1-multicast>]\n"
5466             "                [-secure_dp <0-No security, 1-Security>] [-ranging <0-disable, 1-enable>)]\n"
5467             "                [-ranging_intvl [intrvl in ms betw two ranging measurements] -ranging_ind \n"
5468             "                [BIT0 - Continuous Ranging event notification, BIT1 - Ingress distance is <=, BIT2 - Egress distance is >=.]\n"
5469             "                [-ingress [Ingress distance in centimeters] \n"
5470             "                [ -egress [Egress distance in centimeters] \n");
5471     printf(" -nan [-cancel_pub <publish id>]\n");
5472     printf(" -nan [-cancel_sub <subscribe id>\n");
5473     printf(" -nan [-transmit] [-src_id <instance id>] [-dest_id <instance id>]\n"
5474             "                [-peer_addr <mac addr>] [-info <svc info>] \n"
5475             "                [-recv_flag <1-Disable followUp response, 0-Enable followup response from FW>]\n");
5476     printf(" -nan [-get_capabilities]\n");
5477     printf("\n ****** Nan Data Path Commands ***** \n");
5478     printf(" -nan [-create] [-iface <iface name>]\n");
5479     printf(" -nan [-delete] [-iface <iface name>]\n");
5480     printf(" -nan [-init] [-pub_id <pub id>] [-disc_mac <discovery mac addr>]\n"
5481             "                [-chan_req_type <NAN DP channel config options>]\n"
5482             "                [-chan <channel in mhz>] [-iface <iface>] [-sec <security>]  [-key_type <1 or 2>\n"
5483             "                [-qos <qos>] [-info <seq of values in the frame body>]  [-passphrase <Passphrase value, len must not be less than 8 or greater than 63>]\n"
5484             "                [-csid <cipher suite type 0/1/2/4/8>] [-key_type <1 or 2>]  [-pmk <PMK value>] [-svc <svc_name>]\n");
5485     printf(" -nan [-resp] [-ndp_id <NDP id>] [-iface <NDP iface name>]\n"
5486             "                [-resp_code <accept = 0, reject = 1>] [-qos <qos>]  [-key_type <1 or 2>] \n"
5487             "                [-info <seq of values in the frame body>]  [-passphrase <Passphrase value, len must not be less than 8 or greater than 63>]\n"
5488             "                [-csid <cipher suite type 0/1/2/4/8>] [-key_type <1 or 2>] [-pmk <PMK value>] [-svc <svc_name>]\n");
5489     printf(" -nan [-end] [-inst_count <count>] [-inst_id <NDP id>\n");
5490     printf(" -nan [-up] [-iface <iface name>] [-ip <ip>]\n");
5491     printf(" -nan [-addr]\n");
5492     printf(" -nan [-event_chk]\n");
5493     printf(" -nan [-ver]\n");
5494     printf(" -nan [-exit]\n");
5495     printf(" -dscp [-set] [-s <start>] [-e <end>] [-ac <access_category>]\n");
5496     printf(" -dscp [-reset] \n");
5497     printf(" -ch_avoid [-unsafe <band type, a,b>,<channel number>,<power capacity, maximum output for the channel in dBm>]\n"
5498             "               -unsafe can be used multiple times\n"
5499             "               b for BAND_24GHZ\n"
5500             "               a for BAND_5GHZ\n"
5501             "          [-m <mandatory flag as decimal>]\n"
5502             "               1 << 0 for FLAG_UNSPECIFIED \n"
5503             "               1 << 1 for FLAG_WIFI_DIRECT\n"
5504             "               1 << 2 for FLAG_SOFTAP\n"
5505             "               1 << 4 for FLAG_WIFI_AWARE\n");
5506     printf(" -usable_ch [-b <band_mask>], [-i <iface_mask>], [-f <filter_mask>], [-m <max_size of channel>]\n"
5507             "           [-b 2g,5g,6g]\n"
5508             "           [-i sta,nan,softap,p2p_go,p2p_cli]\n");
5509     printf("-ifadd -name <virtual iface name to be created>"
5510            " -type <0 for STA, 1 for AP, 2 for P2P, 3 for NAN>\n");
5511     printf("-ifdel -name <virtual iface name to be deleted>\n");
5512     printf(" -voip_mode <interface_name> <0|1>    voip mode off/on on particular interface\n");
5513     printf(" -dtim_multiplier <dtim count>  Set suspend bcn_li_dtim.\n");
5514     printf(" -on_ssr  cmd to trigger sub system restart.\n");
5515     printf(" -getSupportedRadioMatrix  cmd to get the supported radio combo matrix.\n");
5516     printf(" -get_cached_scan_results cmd to get the cached scan results.\n");
5517     printf(" -set_channel_mask <value> [1 for indoor channel, 2 for DFS channel]\n");
5518     printTwtUsage();
5519     printTxPowerUsage();
5520     printChreNanRttUsage();
5521 }
5522 
5523 /* Generic function to copy Iface_name/Ip/App specific Info to the buffer */
set_interface_params(char * p_info,char * val_p,int len)5524 static int set_interface_params(char *p_info, char *val_p, int len) {
5525     void *p;
5526     p = strncpy(p_info, val_p, len);
5527     if (p_info[len - 1] == '\n') {
5528         p_info[len - 1] = '\0';
5529     }
5530     if (!p) {
5531         printMsg("Error\n");
5532         return WIFI_ERROR_UNKNOWN;
5533     }
5534     printMsg("Info/Iface/Ip = \"%s\"\n", (char*)p);
5535     return WIFI_SUCCESS;
5536 }
5537 
OnNanNotifyResponse(transaction_id id,NanResponseMsg * rsp_data)5538 void OnNanNotifyResponse(transaction_id id, NanResponseMsg* rsp_data) {
5539     if(rsp_data) {
5540     switch(rsp_data->response_type) {
5541     case NAN_RESPONSE_ENABLED:
5542         printMsg("Nan Enable Response Received, status = %d\n", rsp_data->status);
5543         break;
5544     case NAN_RESPONSE_DISABLED:
5545         printMsg("Nan Disable Response Received, status = %d\n", rsp_data->status);
5546         break;
5547     case NAN_RESPONSE_CONFIG:
5548         printMsg("Nan Config Response Received, status = %d\n", rsp_data->status);
5549         break;
5550     case NAN_RESPONSE_PUBLISH:
5551         printMsg("Nan Publish Response Received, Publish ID "
5552             "= %d, status = %d\n",
5553             rsp_data->body.publish_response.publish_id, rsp_data->status);
5554         break;
5555     case NAN_RESPONSE_SUBSCRIBE:
5556         printMsg("Nan Subscribe Response Received, Subscribe ID "
5557             "= %d, status = %d\n",
5558             rsp_data->body.subscribe_response.subscribe_id, rsp_data->status);
5559         break;
5560     case NAN_RESPONSE_PUBLISH_CANCEL:
5561         printMsg("Nan Cancel Publish Response Received, status = %d\n", rsp_data->status);
5562         break;
5563     case NAN_RESPONSE_SUBSCRIBE_CANCEL:
5564         printMsg("Nan Cancel Subscribe Response Received, status = %d\n", rsp_data->status);
5565         break;
5566     case NAN_RESPONSE_TRANSMIT_FOLLOWUP:
5567         printMsg("Transmit followup response received, status = %d\n", rsp_data->status);
5568         break;
5569     case NAN_DP_INTERFACE_CREATE:
5570         printMsg("ndp iface create response received, status = %d\n", rsp_data->status);
5571         break;
5572     case NAN_DP_INTERFACE_DELETE:
5573         printMsg("ndp iface delete response received, status = %d\n", rsp_data->status);
5574         break;
5575     case NAN_DP_INITIATOR_RESPONSE:
5576         printMsg("ndp response received, ndp_instance_id = %d, status = %d\n",
5577             rsp_data->body.data_request_response.ndp_instance_id, rsp_data->status);
5578         break;
5579     case NAN_DP_RESPONDER_RESPONSE:
5580         printMsg("Nan Data Path Response Received, status = %d\n", rsp_data->status);
5581         break;
5582     case NAN_DP_END:
5583         printMsg("Nan Data Path End Response Received, status = %d\n", rsp_data->status);
5584         break;
5585     case NAN_GET_CAPABILITIES:
5586         printMsg("Nan Get Capabilities Response Received, status = %d\n", rsp_data->status);
5587         printMsg("max_concurrent_nan_clusters = %d\n",
5588             rsp_data->body.nan_capabilities.max_concurrent_nan_clusters);
5589         printMsg("max_publishes = %d\n",
5590             rsp_data->body.nan_capabilities.max_publishes);
5591         printMsg("max_subscribes = %d\n",
5592             rsp_data->body.nan_capabilities.max_subscribes);
5593         printMsg("max_service_name_len = %d\n",
5594             rsp_data->body.nan_capabilities.max_service_name_len);
5595         printMsg("max_match_filter_len = %d\n",
5596             rsp_data->body.nan_capabilities.max_match_filter_len);
5597         printMsg("max_total_match_filter_len = %d\n",
5598             rsp_data->body.nan_capabilities.max_total_match_filter_len);
5599         printMsg("max_service_specific_info_len = %d\n",
5600             rsp_data->body.nan_capabilities.max_service_specific_info_len);
5601         printMsg("max_ndi_interfaces = %d\n",
5602             rsp_data->body.nan_capabilities.max_ndi_interfaces);
5603         printMsg("max_ndp_sessions = %d\n",
5604             rsp_data->body.nan_capabilities.max_ndp_sessions);
5605         printMsg("max_app_info_len = %d\n",
5606             rsp_data->body.nan_capabilities.max_app_info_len);
5607         printMsg("max_queued_transmit_followup_msgs = %d\n",
5608             rsp_data->body.nan_capabilities.max_queued_transmit_followup_msgs);
5609         printMsg("max_Subscribe_Interface_Addresses = %d\n",
5610             rsp_data->body.nan_capabilities.max_subscribe_address);
5611         printMsg("supported_CipherSuites = %d\n",
5612             rsp_data->body.nan_capabilities.cipher_suites_supported);
5613         printMsg("max_Extended_ServiceSpecific_Info_Len = %d\n",
5614             rsp_data->body.nan_capabilities.max_sdea_service_specific_info_len);
5615         printMsg("ndpe_attr_supported = %d\n",
5616             rsp_data->body.nan_capabilities.ndpe_attr_supported);
5617         break;
5618     default:
5619         printMsg("Unknown Response Received, %d\n",
5620             rsp_data->response_type);
5621         }
5622     }
5623     return;
5624 }
OnNanEventPublishTerminated(NanPublishTerminatedInd * event)5625 void OnNanEventPublishTerminated(NanPublishTerminatedInd* event) {
5626     char msg_buf[MAX_NAN_MSG_BUF_SIZE] = {'\0'};
5627     printMsg("\n NanPublishTerminated\n");
5628     snprintf(msg_buf, MAX_NAN_MSG_BUF_SIZE,
5629         "NanPublishTerminated: id %u, reason %u\n",
5630         event->publish_id, event->reason);
5631     printMsg("Publish Terminated: nan_reason = %s\n", event->nan_reason);
5632     putEventInCache(EVENT_TYPE_NAN_PUBLISH_TERMINATED, msg_buf);
5633 }
OnNanEventMatch(NanMatchInd * event)5634 void OnNanEventMatch (NanMatchInd* event) {
5635     printMsg("\n Subscriber id = %d\n", event->publish_subscribe_id);
5636     printMsg("Publisher Id = %d\n", event->requestor_instance_id);
5637     printMsg("Subscribe Match found: Publisher Device Addr( " MACSTR " )\n",
5638         MAC2STR(event->addr));
5639     if (event->service_specific_info_len) {
5640         printMsg("svc info len = %d and svc info = %s\n",
5641             event->service_specific_info_len,
5642             event->service_specific_info);
5643     }
5644     if(event->sdf_match_filter_len) {
5645         printMsg("sdf match filter len = %d and sdf_match_filter = %s\n",
5646             event->sdf_match_filter_len,
5647             event->sdf_match_filter);
5648     }
5649     printMsg("Match occurred flag = %d\n", event->match_occured_flag);
5650     printMsg("Out of resource flag = %d\n", event->out_of_resource_flag);
5651     printMsg("rssi value = %d\n", event->rssi_value);
5652     printMsg("Peer cipher suite type = %d\n", event->peer_cipher_type);
5653     if (event->scid_len) {
5654         printMsg("scid len = %d and scid = %s\n",
5655             event->scid_len, event->scid);
5656     }
5657     /* Peer sdea params */
5658     printMsg("Peer config for data path needed %d\n", event->peer_sdea_params.config_nan_data_path);
5659     printMsg("Data Path type %d\n", event->peer_sdea_params.ndp_type);
5660     printMsg("Security configuration %d\n", event->peer_sdea_params.security_cfg);
5661     printMsg("Ranging report state %d\n", event->peer_sdea_params.range_report);
5662 
5663     printMsg("Distance to the device: %d mm\n", event->range_info.range_measurement_mm);
5664     printMsg("Ranging event type: %d\n", event->range_info.ranging_event_type);
5665 
5666     if (event->sdea_service_specific_info_len) {
5667         printMsg("sdea svc info len = %d and sdea svc info = %s\n",
5668             event->sdea_service_specific_info_len,
5669             event->sdea_service_specific_info);
5670     }
5671     /* Event enabled is not available in android-m */
5672     putEventInCache(EVENT_TYPE_SUBSCRIBE_MATCHED,
5673         "SubscribeMatched");
5674 }
OnNanEventMatchExpired(NanMatchExpiredInd * event)5675 void OnNanEventMatchExpired (NanMatchExpiredInd* event) {
5676     printMsg("NanMatchExpired between publish_subscribe_id = %u "
5677         "and peer_instance_id = %u\n",
5678         event->publish_subscribe_id, event->requestor_instance_id);
5679 }
OnNanEventSubscribeTerminated(NanSubscribeTerminatedInd * event)5680 void OnNanEventSubscribeTerminated (NanSubscribeTerminatedInd* event) {
5681     char msg_buf[MAX_NAN_MSG_BUF_SIZE] = {'\0'};
5682     printMsg("\n NanSubscribeTerminated\n");
5683     snprintf(msg_buf, MAX_NAN_MSG_BUF_SIZE,
5684         "NanSubscribeTerminated: id %u, reason %u\n",
5685         event->subscribe_id, event->reason);
5686     printMsg("Subscribe Terminated: nan_reason = %s\n", event->nan_reason);
5687     putEventInCache(EVENT_TYPE_NAN_SUBSCRIBE_TERMINATED, msg_buf);
5688 }
OnNanEventFollowup(NanFollowupInd * event)5689 void OnNanEventFollowup (NanFollowupInd* event) {
5690     printMsg("\n Instance id= %u\n",
5691         event->publish_subscribe_id);
5692     printMsg("Peer instance id = %u\n",
5693         event->requestor_instance_id);
5694     printMsg("Transmit Followup Received in %s\n",
5695         (event->dw_or_faw)? "FAW":"DW");
5696     printMsg("peer addr (" MACSTR ")\n", MAC2STR(event->addr));
5697     if (event->service_specific_info_len) {
5698         printMsg("followup svc_info len = %d and info = %s\n",
5699             event->service_specific_info_len,event->service_specific_info);
5700     }
5701     if (event->sdea_service_specific_info_len) {
5702         printMsg("sdea svc info len = %d and sdea svc info = %s\n",
5703             event->sdea_service_specific_info_len,
5704             event->sdea_service_specific_info);
5705     }
5706 
5707     putEventInCache(EVENT_TYPE_NAN_FOLLOWUP_RECIEVE,
5708         "NanFollowupReceived");
5709 }
OnNanTransmitFollowupInd(NanTransmitFollowupInd * event)5710 void OnNanTransmitFollowupInd (NanTransmitFollowupInd* event) {
5711     printMsg("\n Transaction id = %u\n",
5712         event->id);
5713     printMsg("Transmit Followup Status = %u\n",
5714         event->reason);
5715     printMsg("Nan Transmit Followup Ind: nan_reason = %s\n", event->nan_reason);
5716     putEventInCache(EVENT_TYPE_NAN_TRANSMIT_FOLLOWUP_INDICATION,
5717         "NanTransmitFollowupInd");
5718 }
5719 
OnNanPublishRepliedInd(NanPublishRepliedInd * event)5720 void OnNanPublishRepliedInd (NanPublishRepliedInd* event) {
5721     printMsg("\n Requestor Instance Id/Subscriber Id = %d\n", event->requestor_instance_id);
5722     printMsg("Subscriber found: Device( " MACSTR " )\n",
5723         MAC2STR(event->addr));
5724     printMsg("rssi value = %d\n", event->rssi_value);
5725 }
5726 
OnNanEventDiscEngEvent(NanDiscEngEventInd * event)5727 void OnNanEventDiscEngEvent (NanDiscEngEventInd* event) {
5728     if (event->event_type == NAN_EVENT_ID_DISC_MAC_ADDR) {
5729         printMsg("\n DE Event Received, Nan Disc Mac Addr Creation Event\n");
5730         printMsg("NMI Mac address (" MACSTR ")\n",
5731             MAC2STR(event->data.mac_addr.addr));
5732     } else if (event->event_type == NAN_EVENT_ID_STARTED_CLUSTER) {
5733         printMsg("DE Event Received, Nan Cluster Started \n");
5734     } else if (event->event_type == NAN_EVENT_ID_JOINED_CLUSTER) {
5735         printMsg("DE Event Received, Nan Cluster Joined \n");
5736         printMsg("Joined cluster ID (" MACSTR ")\n",
5737             MAC2STR(event->data.cluster.addr));
5738     } else {
5739         printMsg("Unknown DE Event Received, %d\n", event->event_type);
5740         return;
5741     }
5742 }
OnNanEventDisabled(NanDisabledInd * event)5743 void OnNanEventDisabled (NanDisabledInd* event) {
5744     printMsg("\n Nan disabledInd received, reason = %u\n", event->reason);
5745     printMsg("Nan Disabled Event: nan_reason = %s\n", event->nan_reason);
5746 }
OnNanEventTca(NanTCAInd * event)5747 void OnNanEventTca (NanTCAInd* event) {}
OnNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd * event)5748 void OnNanEventBeaconSdfPayload (NanBeaconSdfPayloadInd* event) {}
OnNanEventDataIndication(NanDataPathRequestInd * event)5749 void OnNanEventDataIndication (NanDataPathRequestInd* event) {
5750     printMsg("\n service id = %d\n", event->service_instance_id);
5751     printMsg("Discovery MAC addr of the peer/initiator(" MACSTR ")\n",
5752         MAC2STR(event->peer_disc_mac_addr));
5753     printMsg("ndp id = %d\n", event->ndp_instance_id);
5754     printMsg("qos = %d\n", event->ndp_cfg.qos_cfg);
5755     printMsg("security = %d\n", event->ndp_cfg.security_cfg);
5756     if (event->app_info.ndp_app_info_len) {
5757         printMsg("service info = %s and its length = %d\n",
5758             event->app_info.ndp_app_info,
5759             event->app_info.ndp_app_info_len);
5760     }
5761     putEventInCache(EVENT_TYPE_NAN_DATA_REQUEST_INDICATION,
5762         "NanDataEventIndication");
5763 }
OnNanEventDataConfirmation(NanDataPathConfirmInd * event)5764 void OnNanEventDataConfirmation (NanDataPathConfirmInd* event) {
5765     printMsg("\n ndp id = %d\n", event->ndp_instance_id);
5766     printMsg("NDI mac address of the peer = (" MACSTR ")\n",
5767         MAC2STR(event->peer_ndi_mac_addr));
5768     if (event->app_info.ndp_app_info_len) {
5769         printMsg("service info = %s and length = %d\n",
5770             event->app_info.ndp_app_info,
5771             event->app_info.ndp_app_info_len);
5772     }
5773     printMsg("Response code = %d\n", event->rsp_code);
5774     switch (event->rsp_code) {
5775     case NAN_DP_REQUEST_ACCEPT:
5776         printMsg("Response code [%d]:NAN_DP_REQUEST_ACCEPT\n", event->rsp_code);
5777         break;
5778     case NAN_DP_REQUEST_REJECT:
5779         printMsg("Response code [%d]:NAN_DP_REQUEST_REJECT\n", event->rsp_code);
5780         printMsg("Reason code for rejection= %d\n", event->reason_code);
5781         break;
5782     default:
5783         printMsg("Unknown response code = %d\n", event->rsp_code);
5784         break;
5785     }
5786     putEventInCache(EVENT_TYPE_NAN_DATA_CONFIRMATION,
5787         "NanDataConfirmation");
5788 }
OnNanEventDataPathEnd(NanDataPathEndInd * event)5789 void OnNanEventDataPathEnd (NanDataPathEndInd* event) {
5790     printMsg("\n ndp id count = %d\n", event->num_ndp_instances);
5791     printMsg("ndp id = %d\n",
5792         event->ndp_instance_id[event->num_ndp_instances -1]);
5793     putEventInCache(EVENT_TYPE_NAN_DATA_END_INDICAION,
5794         "NanDataEndIndication");
5795 }
5796 
OnNanRangeRequestInd(NanRangeRequestInd * event)5797 void OnNanRangeRequestInd (NanRangeRequestInd *event) {
5798     printMsg("\n Received NanRangeRequestInd\n");
5799 }
OnNanRangeReportInd(NanRangeReportInd * event)5800 void OnNanRangeReportInd (NanRangeReportInd *event) {
5801     printMsg("\n Received NanRangeReportInd\n");
5802 }
OnNanDataPathScheduleUpdateInd(NanDataPathScheduleUpdateInd * event)5803 void OnNanDataPathScheduleUpdateInd (NanDataPathScheduleUpdateInd *event) {
5804     printMsg("\n Received NanDataPathScheduleUpdateInd\n");
5805 }
5806 
nan_init_handlers(void)5807 wifi_error nan_init_handlers(void) {
5808     wifi_error ret = WIFI_SUCCESS;
5809     NanCallbackHandler handlers;
5810     memset(&handlers, 0, sizeof(handlers));
5811     handlers.NotifyResponse = OnNanNotifyResponse;
5812     handlers.EventPublishTerminated = OnNanEventPublishTerminated;
5813     handlers.EventMatch = OnNanEventMatch;
5814     handlers.EventMatchExpired = OnNanEventMatchExpired;
5815     handlers.EventSubscribeTerminated = OnNanEventSubscribeTerminated;
5816     handlers.EventFollowup = OnNanEventFollowup;
5817     handlers.EventDiscEngEvent = OnNanEventDiscEngEvent;
5818     handlers.EventDisabled = OnNanEventDisabled;
5819     handlers.EventTca = OnNanEventTca;
5820     handlers.EventBeaconSdfPayload = OnNanEventBeaconSdfPayload;
5821     handlers.EventDataRequest = OnNanEventDataIndication;
5822     handlers.EventDataConfirm = OnNanEventDataConfirmation;
5823     handlers.EventDataEnd = OnNanEventDataPathEnd;
5824     handlers.EventTransmitFollowup = OnNanTransmitFollowupInd;
5825     handlers.EventPublishReplied = OnNanPublishRepliedInd;
5826     handlers.EventRangeRequest = OnNanRangeRequestInd;
5827     handlers.EventRangeReport = OnNanRangeReportInd;
5828     handlers.EventScheduleUpdate = OnNanDataPathScheduleUpdateInd;
5829     ret = nan_register_handler(wlan0Handle , handlers);
5830     printMsg("%s: ret = %d\n", __FUNCTION__, ret);
5831     return ret;
5832 }
5833 
OnTwtNotify(TwtDeviceNotify * event)5834 static void OnTwtNotify(TwtDeviceNotify* event) {
5835     if (event) {
5836         printMsg("OnTwtNotify, notification = %d\n", event->notification);
5837     }
5838     return;
5839 }
5840 
OnTwtSetupResponse(TwtSetupResponse * event)5841 static void OnTwtSetupResponse(TwtSetupResponse* event) {
5842     printMsg("\n OnTwtSetupResponse\n");
5843     if (event) {
5844         printMsg("config id = %d\n", event->config_id);
5845         printMsg("status = %d\n", event->status);
5846         printMsg("reason_code = %d\n", event->reason_code);
5847         printMsg("negotiation_type = %d\n", event->negotiation_type);
5848         printMsg("trigger_type = %d\n", event->trigger_type);
5849         printMsg("wake_dur_us = %d\n", event->wake_dur_us);
5850         printMsg("wake_int_us = %d\n", event->wake_int_us);
5851         printMsg("wake_time_off_us = %d\n", event->wake_time_off_us);
5852     }
5853     return;
5854 }
5855 
OnTwtTearDownCompletion(TwtTeardownCompletion * event)5856 static void OnTwtTearDownCompletion(TwtTeardownCompletion* event) {
5857     printMsg("\n OnTwtTearDownCompletion\n");
5858     if (event) {
5859         printMsg("config id = %d\n", event->config_id);
5860         printMsg("status = %d\n", event->status);
5861         printMsg("all twt = %d\n", event->all_twt);
5862         printMsg("reason = %d\n", event->reason);
5863     }
5864     return;
5865 }
5866 
OnTwtInfoFrameReceived(TwtInfoFrameReceived * event)5867 static void OnTwtInfoFrameReceived(TwtInfoFrameReceived* event) {
5868     printMsg("\n OnTwtInfoFrameReceived\n");
5869     if (event) {
5870         printMsg("config id = %d\n", event->config_id);
5871         printMsg("status = %d\n", event->status);
5872         printMsg("all twt = %d\n", event->all_twt);
5873         printMsg("reason = %d\n", event->reason);
5874         printMsg("twt_resumed = %d\n", event->twt_resumed);
5875     }
5876     return;
5877 }
5878 
twt_init_handlers(void)5879 wifi_error twt_init_handlers(void) {
5880     wifi_error ret = WIFI_SUCCESS;
5881     TwtCallbackHandler handlers;
5882     memset(&handlers, 0, sizeof(handlers));
5883     handlers.EventTwtDeviceNotify = OnTwtNotify;
5884     handlers.EventTwtSetupResponse = OnTwtSetupResponse;
5885     handlers.EventTwtTeardownCompletion = OnTwtTearDownCompletion;
5886     handlers.EventTwtInfoFrameReceived = OnTwtInfoFrameReceived;
5887     ret = twt_register_handler(wlan0Handle , handlers);
5888     printMsg("%s: ret = %d\n", __FUNCTION__, ret);
5889     return ret;
5890 }
5891 
5892 /*
5893  * Debug function to see the events reaching to HAL
5894  * CTRL-C to exit the blocking command.
5895  */
twtEventCheck(void)5896 void twtEventCheck(void) {
5897     wifi_error ret = WIFI_SUCCESS;
5898 
5899     ret = twt_init_handlers();
5900     if (ret != WIFI_SUCCESS) {
5901         printMsg("Failed to initialize twt handlers %d\n", ret);
5902         return;
5903     }
5904 
5905     twtCmdId = getNewCmdId();
5906     ret = twt_event_check_request(twtCmdId, wlan0Handle);
5907     if (ret != WIFI_SUCCESS) {
5908         printMsg("Failed to check the twt events: %d\n", ret);
5909         return;
5910     }
5911 
5912     printMsg("CTRL-C to exit the thread.\n");
5913     while (1)
5914     {
5915         EventInfo info;
5916         memset(&info, 0, sizeof(info));
5917         getEventFromCache(info);
5918         printMsg("\n Retrieved event %d : %s\n\n", info.type, info.buf);
5919     }
5920 }
5921 /*
5922  * Debug function to see the events reaching to HAL
5923  * CTRL-C to exit the blocking command.
5924  */
nanEventCheck(void)5925 void nanEventCheck(void) {
5926     wifi_error ret = WIFI_SUCCESS;
5927     ret = nan_init_handlers();
5928     if (ret != WIFI_SUCCESS) {
5929         printMsg("Failed to initialize handlers %d\n", ret);
5930         return;
5931     }
5932     nanCmdId = getNewCmdId();
5933     nan_event_check_request(nanCmdId, wlan0Handle);
5934     printMsg("CTRL-C to exit the thread.\n");
5935     while (1)
5936     {
5937         EventInfo info;
5938         memset(&info, 0, sizeof(info));
5939         getEventFromCache(info);
5940         printMsg("\n Retrieved event %d : %s\n\n", info.type, info.buf);
5941     }
5942 }
5943 
nanVersion(void)5944 void nanVersion(void) {
5945     NanVersion version = 0;
5946     wifi_error err = WIFI_SUCCESS;
5947     err = nan_get_version(0, &version);
5948     if (err == WIFI_SUCCESS) {
5949         printMsg("NAN VERSION is %d\n", version);
5950     } else {
5951         printMsg("Nan Version Command Failed, err = %d\n", err);
5952     }
5953 }
5954 
set_cluster_id(char * clus_id,NanEnableRequest * msg)5955 void set_cluster_id(char *clus_id, NanEnableRequest *msg) {
5956     u8 addr[NAN_MAC_ADDR_LEN]; /* cluster id */
5957     if (!clus_id || (!ether_atoe(clus_id, addr))) {
5958         printMsg("bad cluster id !!\n");
5959     } else {
5960         msg->cluster_high = ((addr[4] << 8) | addr[5]);
5961         msg->cluster_low = msg->cluster_high;
5962         printMsg("cluster low: %x, cluster high: %x\n", msg->cluster_low, msg->cluster_high);
5963     }
5964     return;
5965 }
5966 
5967 int
get_oui_bytes(u8 * oui_str,u8 * oui)5968 get_oui_bytes(u8 *oui_str, u8 *oui)
5969 {
5970     int idx;
5971     u8 val;
5972     u8 *src, *dest;
5973     char hexstr[3];
5974     char* endptr = NULL;
5975 
5976     src = oui_str;
5977     dest = oui;
5978 
5979     for (idx = 0; idx < 3; idx++) {
5980         hexstr[0] = src[0];
5981         hexstr[1] = src[1];
5982         hexstr[2] = '\0';
5983         val = (u8) strtoul(hexstr, &endptr, 16);
5984         *dest++ = val;
5985         src += 2;
5986         if (((idx < (3 - 1)) && (*src++ != ':')) || (*endptr != '\0'))
5987             return WIFI_ERROR_UNKNOWN;
5988     }
5989     return WIFI_SUCCESS;
5990 }
5991 
nanSetOui(char * nan_oui,char * nan_type,NanEnableRequest * msg)5992 void nanSetOui(char *nan_oui, char* nan_type, NanEnableRequest *msg) {
5993     u8 type;
5994     u32 value;
5995     char* endptr;
5996 
5997     if(!nan_type) {
5998         printMsg("nan oui type is missing. Setting NAN OUI to default \n");
5999         return;
6000     }
6001 
6002     if (get_oui_bytes((u8 *)nan_oui, (u8 *)&value)) {
6003         printMsg("%s: Wrong OUI value. Setting Default OUI and type\n",__FUNCTION__);
6004         msg->oui_val = 0;
6005         return;
6006     }
6007 
6008     type = strtoul(nan_type, &endptr, 0);
6009     if (*endptr != '\0') {
6010         printMsg("%s:Wrong nan OUI type. Setting default OUI and type\n", __FUNCTION__);
6011         msg->oui_val = 0;
6012         return;
6013     }
6014     value = (value & 0xffffff) + (type << 24);
6015     msg->config_oui = 1;
6016     msg->oui_val = value;
6017 }
6018 
enableNan(char * argv[])6019 void enableNan(char *argv[]) {
6020     NanEnableRequest msg ;
6021     wifi_error ret = WIFI_SUCCESS;
6022     char *endptr, *param, *val_p;
6023     int sid_flag = 0xff, sid_count = 0xff;
6024     int sub_sid_flag = 0xff, sub_sid_count = 0xff;
6025     u8 val;
6026     u16 clust_range;
6027 
6028     /* Set Default enable params */
6029     memset(&msg, 0, sizeof(msg));
6030     msg.hop_count_limit_val = 5;
6031     msg.config_2dot4g_support = FEATURE_SUPPORTED;
6032     msg.support_2dot4g_val = FEATURE_SUPPORTED;
6033     msg.config_2dot4g_beacons = FEATURE_SUPPORTED;
6034     msg.beacon_2dot4g_val = FEATURE_SUPPORTED;
6035     msg.config_2dot4g_sdf = FEATURE_SUPPORTED;
6036     msg.sdf_2dot4g_val = FEATURE_SUPPORTED;
6037     msg.config_disc_mac_addr_randomization = true;
6038     msg.disc_mac_addr_rand_interval_sec = 0;
6039     msg.config_ndpe_attr = false;
6040     msg.cluster_low = 0;
6041     msg.cluster_high = NAN_MAX_CLUST_VALUE_RANGE;
6042 
6043     /* Parse args for nan params */
6044     /* skip utility */
6045     argv++;
6046     /* skip command */
6047     argv++;
6048     /* skip command */
6049     argv++;
6050 
6051     while ((param = *argv++) != NULL) {
6052         val_p = *argv++;
6053         if (!val_p || *val_p == '-') {
6054             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
6055             ret = WIFI_ERROR_NOT_SUPPORTED;
6056             goto exit;
6057         }
6058         if (strcmp(param, "-clus_id") == 0) {
6059             set_cluster_id(val_p, &msg);
6060         } else if (strcmp(param, "-cluster_low") == 0) {
6061             clust_range = atoi(val_p);
6062             if (clust_range < 0 || clust_range > NAN_MAX_CLUST_VALUE_RANGE) {
6063                 msg.cluster_low = 0;
6064             }
6065             msg.cluster_low = clust_range;
6066         } else if (strcmp(param, "-cluster_high") == 0) {
6067              clust_range = atoi(val_p);
6068              if (clust_range < 0 || clust_range > NAN_MAX_CLUST_VALUE_RANGE) {
6069                 msg.cluster_high = NAN_MAX_CLUST_VALUE_RANGE;
6070              }
6071              msg.cluster_high = clust_range;
6072         } else if (strcmp(param, "-master_pref") == 0) {
6073             msg.master_pref = strtoul(val_p, &endptr, 0);
6074             if (*endptr != '\0' || (msg.master_pref < 2 || msg.master_pref > 254)) {
6075                 printMsg("%s:Invalid Master Preference.Setting it to Random\n", __FUNCTION__);
6076                 msg.master_pref = 0;
6077             }
6078         } else if (strcmp(param, "-dual_band") == 0) {
6079             msg.support_5g_val = strtoul(val_p, &endptr, 0);
6080             if (*endptr != '\0' ||  msg.support_5g_val > 1) {
6081                 printMsg("%s:Invalid Dual Band Value.\n", __FUNCTION__);
6082                 msg.config_support_5g = false;
6083                 ret = WIFI_ERROR_INVALID_ARGS;
6084                 goto exit;
6085             } else {
6086                 msg.config_support_5g = true;
6087             }
6088         } else if (strcmp(param, "-hc_limit") == 0) {
6089             msg.hop_count_limit_val = strtoul(val_p, &endptr, 0);
6090             if (*endptr != '\0') {
6091                 printMsg("%s:Invalid Hop Count Limit. Setting to Default\n", __FUNCTION__);
6092                 msg.config_hop_count_limit = false;
6093                 ret = WIFI_ERROR_INVALID_ARGS;
6094                 goto exit;
6095             } else {
6096                 msg.config_hop_count_limit = true;
6097             }
6098         } else if (strcmp(param, "-oui") == 0) {
6099             nanSetOui(val_p, *argv++, &msg);
6100         } else if (strcmp(param, "-sid_flag") == 0) {
6101             sid_flag = atoi(val_p);
6102             if (sid_flag) {
6103                 msg.config_sid_beacon = true;
6104             } else {
6105                 printMsg("%s:Invalid Service Id Flag. Setting to Default\n", __FUNCTION__);
6106                 msg.config_sid_beacon = false;
6107                 ret = WIFI_ERROR_INVALID_ARGS;
6108                 goto exit;
6109             }
6110         } else if (strcmp(param, "-sid_count") == 0) {
6111             sid_count = atoi(val_p);
6112             if (sid_count < 0 || sid_count > NAN_MAX_SIDS_IN_BEACONS) {
6113                 printMsg("%s:Invalid  Service ID Count Limit. Setting to Default\n", __FUNCTION__);
6114                 sid_count = 0;
6115             } else  {
6116                 msg.sid_beacon_val = ((sid_count << 1) | sid_flag);
6117             }
6118         } else if (strcmp(param, "-sub_sid_flag") == 0) {
6119             sub_sid_flag = atoi(val_p);
6120             if (sub_sid_flag) {
6121                 msg.config_subscribe_sid_beacon = true;
6122             } else {
6123                 printMsg("%s:Invalid Subscribe Service Id Flag. Setting to Default\n", __FUNCTION__);
6124                 msg.config_subscribe_sid_beacon = false;
6125                 ret = WIFI_ERROR_INVALID_ARGS;
6126                 goto exit;
6127             }
6128         } else if (strcmp(param, "-sub_sid_count") == 0) {
6129             sub_sid_count = atoi(val_p);
6130             if (sub_sid_count < 0 || sub_sid_count > NAN_MAX_SIDS_IN_BEACONS) {
6131                 printMsg("%s:Invalid Subscribe Service ID Count Limit. Setting to Default\n", __FUNCTION__);
6132                 sub_sid_count = 0;
6133             } else  {
6134                 msg.subscribe_sid_beacon_val = ((sub_sid_count << 1) | sub_sid_flag);
6135             }
6136         } else if (strcmp(param, "-rssi_close_2dot4g_val") == 0) {
6137             msg.rssi_close_2dot4g_val = atoi(val_p);
6138             if (msg.rssi_close_2dot4g_val) {
6139                 msg.config_2dot4g_rssi_close = true;
6140             }
6141         } else if (strcmp(param, "-rssi_middle_2dot4g_val") == 0) {
6142             msg.rssi_middle_2dot4g_val = atoi(val_p);
6143             if (msg.rssi_middle_2dot4g_val) {
6144                 msg.config_2dot4g_rssi_middle = true;
6145             }
6146         } else if (strcmp(param, "-rssi_proximity_2dot4g_val") == 0) {
6147             msg.rssi_proximity_2dot4g_val = atoi(val_p);
6148             if (msg.rssi_proximity_2dot4g_val) {
6149                 msg.config_2dot4g_rssi_proximity = true;
6150             }
6151         } else if (strcmp(param, "-support_2dot4g_val") == 0) {
6152             val = atoi(val_p);
6153             /*
6154              * Defines 2.4G channel access support
6155              * 0 - No Support
6156              * 1 - Supported
6157              */
6158             switch(val) {
6159                 case FEATURE_NOT_SUPPORTED:
6160                     msg.support_2dot4g_val = FEATURE_NOT_SUPPORTED;
6161                     break;
6162                 default:
6163                     msg.support_2dot4g_val = FEATURE_SUPPORTED;
6164                     break;
6165             }
6166          } else if (strcmp(param, "-beacon_2dot4g_val") == 0) {
6167             val = atoi(val_p);
6168            /*
6169             * Defines 2.4G channels will be used for sync/discovery beacons
6170             * 0 - 2.4G channels not used for beacons
6171             * 1 - 2.4G channels used for beacons
6172             */
6173             switch(val) {
6174                 case FEATURE_NOT_SUPPORTED:
6175                     msg.beacon_2dot4g_val = FEATURE_NOT_SUPPORTED;
6176                     break;
6177                 default:
6178                     msg.beacon_2dot4g_val = FEATURE_SUPPORTED;
6179                     break;
6180             }
6181         } else if (strcmp(param, "-sdf_2dot4g_val") == 0) {
6182             val = atoi(val_p);
6183             /*
6184              * Defines 2.4G channels will be used for Service Discovery frames
6185              * 0 - 2.4G channels not used for Service Discovery frames
6186              * 1 - 2.4G channels used for Service Discovery frames
6187              */
6188             switch(val) {
6189                 case FEATURE_NOT_SUPPORTED:
6190                     msg.sdf_2dot4g_val = FEATURE_NOT_SUPPORTED;
6191                     break;
6192                 default:
6193                     msg.sdf_2dot4g_val = FEATURE_SUPPORTED;
6194                     break;
6195             }
6196         } else if (strcmp(param, "-beacon_5g_val") == 0) {
6197             val = atoi(val_p);
6198             /*
6199              * Defines 5G channels will be used for sync/discovery beacons
6200              * 0 - 5G channels not used for beacons
6201              * 1 - 5G channels used for beacons
6202              */
6203             switch(val) {
6204                 case FEATURE_SUPPORTED:
6205                     msg.beacon_5g_val = FEATURE_SUPPORTED;
6206                     break;
6207                 default:
6208                     msg.beacon_5g_val = FEATURE_NOT_SUPPORTED;
6209                     break;
6210             }
6211             msg.config_5g_beacons = true;
6212         } else if (strcmp(param, "-sdf_5g_val") == 0) {
6213             val = atoi(val_p);
6214             /*
6215              * Defines 5G channels will be used for Service Discovery frames
6216              * 0 - 5G channels not used for Service Discovery frames
6217              * 1 - 5G channels used for Service Discovery frames
6218              */
6219             switch(val) {
6220                 case FEATURE_SUPPORTED:
6221                     msg.sdf_5g_val = FEATURE_SUPPORTED;
6222                     break;
6223                 default:
6224                     msg.sdf_5g_val = FEATURE_NOT_SUPPORTED;
6225                     break;
6226             }
6227             msg.config_5g_sdf = true;
6228         } else if (strcmp(param, "-rssi_close_5g_val") == 0) {
6229             msg.rssi_close_5g_val = atoi(val_p);
6230             if (msg.rssi_close_5g_val) {
6231                 msg.config_5g_rssi_close = true;
6232             }
6233         } else if (strcmp(param, "-rssi_middle_5g_val") == 0) {
6234             msg.rssi_middle_5g_val = atoi(val_p);
6235             if (msg.rssi_middle_5g_val) {
6236                 msg.config_5g_rssi_middle = true;
6237             }
6238         } else if (strcmp(param, "-rssi_close_proximity_5g_val") == 0) {
6239             msg.rssi_close_proximity_5g_val = atoi(val_p);
6240             if (msg.rssi_close_proximity_5g_val) {
6241                 msg.config_5g_rssi_close_proximity = true;
6242             }
6243         } else if (strcmp(param, "-rssi_window_size_val") == 0) {
6244             msg.rssi_window_size_val = atoi(val_p);
6245             if (msg.rssi_window_size_val) {
6246                 msg.config_rssi_window_size = true;
6247             } else {
6248                 printMsg("%s:Invalid rssi_window_size_val\n", __FUNCTION__);
6249                 msg.config_rssi_window_size = false;
6250                 ret = WIFI_ERROR_INVALID_ARGS;
6251                 goto exit;
6252             }
6253         } else if (strcmp(param, "-config_cluster_attribute_val") == 0) {
6254             val = atoi(val_p);
6255             /*
6256              * If set to 1, the Discovery Engine will enclose the Cluster
6257              * Attribute only sent in Beacons in a Vendor Specific Attribute
6258              * and transmit in a Service Descriptor Frame.
6259              */
6260 
6261             switch(val) {
6262                 case FEATURE_SUPPORTED:
6263                     msg.config_cluster_attribute_val = FEATURE_SUPPORTED;
6264                     break;
6265                 default:
6266                     msg.config_cluster_attribute_val = FEATURE_NOT_SUPPORTED;
6267                     break;
6268             }
6269         } else if (strcmp(param, "-dwell_time") == 0) {
6270             msg.scan_params_val.dwell_time[0] = atoi(val_p);
6271             if (msg.scan_params_val.dwell_time[0]) {
6272                 msg.config_scan_params = true;
6273             } else {
6274                 msg.config_scan_params = false;
6275                 printMsg("%s:Invalid config_scan_params\n", __FUNCTION__);
6276                 ret = WIFI_ERROR_INVALID_ARGS;
6277                 goto exit;
6278             }
6279         }  else if (strcmp(param, "-scan_period") == 0) {
6280                 msg.scan_params_val.scan_period[0] = atoi(val_p);
6281             if (msg.scan_params_val.scan_period[0]) {
6282                 msg.config_scan_params = true;
6283             } else {
6284                 msg.config_scan_params = false;
6285                 printMsg("%s:Invalid config_scan_params\n", __FUNCTION__);
6286                 ret = WIFI_ERROR_INVALID_ARGS;
6287                 goto exit;
6288             }
6289         } else if (strcmp(param, "-dwell_time_5g") == 0) {
6290             msg.scan_params_val.dwell_time[1] = atoi(val_p);
6291             if (msg.scan_params_val.dwell_time[1]) {
6292                 msg.config_scan_params = true;
6293             } else {
6294                 msg.config_scan_params = false;
6295                 printMsg("%s:Invalid config_scan_params for 5g\n", __FUNCTION__);
6296                 ret = WIFI_ERROR_INVALID_ARGS;
6297                 goto exit;
6298             }
6299         }  else if (strcmp(param, "-scan_period_5g") == 0) {
6300                 msg.scan_params_val.scan_period[1] = atoi(val_p);
6301             if (msg.scan_params_val.scan_period[1]) {
6302                 msg.config_scan_params = true;
6303             } else {
6304                 msg.config_scan_params = false;
6305                 printMsg("%s:Invalid config_scan_params for 5g\n", __FUNCTION__);
6306                 ret = WIFI_ERROR_INVALID_ARGS;
6307                 goto exit;
6308             }
6309         } else if (strcmp(param, "-random_factor") == 0) {
6310             msg.random_factor_force_val = atoi(val_p);
6311             if (msg.random_factor_force_val) {
6312                 msg.config_random_factor_force = true;
6313             } else {
6314                 printMsg("%s:Invalid random factor\n", __FUNCTION__);
6315                 msg.config_random_factor_force = false;
6316                 ret = WIFI_ERROR_INVALID_ARGS;
6317                 goto exit;
6318             }
6319         } else if (strcmp(param, "-24g_chan") == 0) {
6320             msg.channel_24g_val = atoi(val_p);
6321             if (msg.channel_24g_val) {
6322                 msg.config_24g_channel = true;
6323             } else {
6324                 printMsg("%s:Invalid 2.4GHz channel value\n", __FUNCTION__);
6325                 msg.config_24g_channel = false;
6326                 ret = WIFI_ERROR_INVALID_ARGS;
6327                 goto exit;
6328             }
6329         } else if (strcmp(param, "-5g_chan") == 0) {
6330             msg.channel_5g_val = atoi(val_p);
6331             if (msg.channel_5g_val) {
6332                 msg.config_5g_channel = true;
6333             } else {
6334                 printMsg("%s:Invalid 5GHz channel value\n", __FUNCTION__);
6335                 msg.config_5g_channel = false;
6336                 ret = WIFI_ERROR_INVALID_ARGS;
6337                 goto exit;
6338             }
6339         } else if (strcmp(param, "-nan_addr") == 0) {
6340             if (!ether_atoe(val_p, msg.intf_addr_val)) {
6341                 printMsg("bad nan interface mac addr, setting to random mac by fw!\n");
6342                 msg.config_intf_addr = false;
6343                 ret = WIFI_ERROR_INVALID_ARGS;
6344                 goto exit;
6345             }
6346             msg.config_intf_addr = true;
6347         } else if (strcmp(param, "-awake_dw_2g") == 0) {
6348             msg.config_dw.dw_2dot4g_interval_val = atoi(val_p);
6349             if (msg.config_dw.dw_2dot4g_interval_val) {
6350                 msg.config_dw.config_2dot4g_dw_band = true;
6351             }
6352         } else if (strcmp(param, "-awake_dw_5g") == 0) {
6353             msg.config_dw.dw_5g_interval_val = atoi(val_p);
6354             if (msg.config_dw.dw_5g_interval_val) {
6355                 msg.config_dw.config_5g_dw_band = true;
6356             }
6357         } else if (strncmp(param, "-disc_ind_cfg", strlen("-disc_ind_cfg")) == 0) {
6358             msg.discovery_indication_cfg = strtoul(val_p, &endptr, 0);
6359             printMsg("%s:disc_ind_cfg value = %d.\n",
6360                 __FUNCTION__, msg.discovery_indication_cfg);
6361         } else if (strncmp(param, "-rand_mac", strlen("-rand_mac")) == 0) {
6362             msg.config_disc_mac_addr_randomization = true;
6363             msg.disc_mac_addr_rand_interval_sec = atoi(val_p);
6364         } else if (strcmp(param, "-use_ndpe") == 0) {
6365             msg.use_ndpe_attr = atoi(val_p);
6366             msg.config_ndpe_attr = true;
6367             if ((msg.use_ndpe_attr != 1) && (msg.use_ndpe_attr != 0)) {
6368                 msg.config_ndpe_attr = false;
6369                 printMsg("%s:Invalid use_ndpe_attr value\n", __FUNCTION__);
6370                 ret = WIFI_ERROR_INVALID_ARGS;
6371                 goto exit;
6372             }
6373         } else if (strcmp(param, "-disc_bcn_interval") == 0) {
6374                 msg.discovery_beacon_interval = atoi(val_p);
6375                 msg.config_discovery_beacon_int = true;
6376         } else if (strcmp(param, "-enable_ranging") == 0) {
6377             msg.enable_ranging = atoi(val_p);
6378             if (msg.enable_ranging) {
6379                 msg.config_enable_ranging = true;
6380             }
6381         } else if (strcmp(param, "-nss") == 0) {
6382             msg.nss = atoi(val_p);
6383             if (msg.nss) {
6384                 msg.config_nss = true;
6385             }
6386         } else if (strcmp(param, "-enable_dw_term") == 0) {
6387             msg.enable_dw_termination = atoi(val_p);
6388             if (msg.enable_dw_termination) {
6389                 msg.config_dw_early_termination = true;
6390             }
6391 #ifdef NAN_3_1_SUPPORT
6392         } else if (strcmp(param, "-instant_mode") == 0) {
6393             msg.enable_instant_mode = atoi(val_p);
6394             msg.config_enable_instant_mode = true;
6395         } else if (strcmp(param, "-instant_chan") == 0) {
6396             msg.instant_mode_channel = atoi(val_p);
6397             if (msg.instant_mode_channel) {
6398                 msg.config_instant_mode_channel = true;
6399             } else {
6400                 printMsg("%s:Invalid Instant channel \n", __FUNCTION__);
6401                 msg.config_instant_mode_channel = false;
6402                 ret = WIFI_ERROR_INVALID_ARGS;
6403                 goto exit;
6404             }
6405 #endif /* NAN_3_1_SUPPORT */
6406         } else {
6407             printMsg("%s:Unsupported Parameter for Nan Enable\n", __FUNCTION__);
6408             ret = WIFI_ERROR_INVALID_ARGS;
6409             goto exit;
6410         }
6411     }
6412 
6413     nanCmdId = getNewCmdId();
6414     ret = nan_init_handlers();
6415     if (ret != WIFI_SUCCESS) {
6416         printMsg("Failed to initialize handlers %d\n", ret);
6417         goto exit;
6418     }
6419     ret = nan_enable_request(nanCmdId, wlan0Handle, &msg);
6420 exit:
6421     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
6422     return;
6423 }
6424 
disableNan(void)6425 void disableNan(void) {
6426     wifi_error ret = WIFI_SUCCESS;
6427     nanCmdId = getNewCmdId();
6428     ret = nan_init_handlers();
6429     if (ret != WIFI_SUCCESS) {
6430         printMsg("Failed to initialize handlers %d\n", ret);
6431         return;
6432     }
6433     ret = nan_disable_request(nanCmdId, wlan0Handle);
6434     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
6435 }
6436 
configNan(char * argv[])6437 void configNan(char *argv[]) {
6438     NanConfigRequest msg;
6439     wifi_error ret = WIFI_SUCCESS;
6440     char *endptr, *param, *val_p;
6441     int sid_flag = 0xff, sid_count = 0xff;
6442     int sub_sid_flag = 0xff, sub_sid_count = 0xff;
6443     u8 val, numchans = 0;
6444 
6445     memset(&msg, 0, sizeof(msg));
6446     msg.fam_val.famchan[numchans].entry_control = NAN_DURATION_16MS;
6447     msg.config_ndpe_attr = false;
6448 
6449     /* Parse args for nan params */
6450     /* skip utility */
6451     argv++;
6452     /* skip command */
6453     argv++;
6454     /* skip command */
6455     argv++;
6456 
6457     while ((param = *argv++) != NULL) {
6458         val_p = *argv++;
6459         if (!val_p) {
6460             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
6461             ret = WIFI_ERROR_NOT_SUPPORTED;
6462             goto exit;
6463         }
6464 
6465         if (strcmp(param, "-sid_flag") == 0) {
6466             sid_flag = atoi(val_p);
6467             if (sid_flag) {
6468                 msg.config_sid_beacon = true;
6469             } else {
6470                 printMsg("%s:Invalid Service Id Flag. Setting to Default\n", __FUNCTION__);
6471                 msg.config_sid_beacon = false;
6472                 ret = WIFI_ERROR_INVALID_ARGS;
6473                 goto exit;
6474             }
6475         } else if (strcmp(param, "-sid_count") == 0) {
6476             sid_count = atoi(val_p);
6477             if (sid_count < 0 || sid_count > NAN_MAX_SIDS_IN_BEACONS) {
6478                 printMsg("%s:Invalid  Service ID Count Limit. Setting to Default\n", __FUNCTION__);
6479                 sid_count = 0;
6480             } else  {
6481                 msg.sid_beacon = ((sid_count << 1) | sid_flag);
6482             }
6483         } else if (strcmp(param, "-sub_sid_flag") == 0) {
6484             sub_sid_flag = atoi(val_p);
6485             if (sub_sid_flag) {
6486                 msg.config_subscribe_sid_beacon = true;
6487             } else {
6488                 printMsg("%s:Invalid Subscribe Service Id Flag. Setting to Default\n", __FUNCTION__);
6489                 msg.config_subscribe_sid_beacon = false;
6490                 ret = WIFI_ERROR_INVALID_ARGS;
6491                 goto exit;
6492             }
6493         } else if (strcmp(param, "-sub_sid_count") == 0) {
6494             sub_sid_count = atoi(val_p);
6495             if (sub_sid_count < 0 || sub_sid_count > NAN_MAX_SIDS_IN_BEACONS) {
6496                 printMsg("%s:Invalid Subscribe Service ID Count Limit. Setting to Default\n", __FUNCTION__);
6497                 sub_sid_count = 0;
6498             } else  {
6499                 msg.subscribe_sid_beacon_val = ((sub_sid_count << 1) | sub_sid_flag);
6500             }
6501         } else if (strcmp(param, "-rssi_proximity") == 0) {
6502             msg.rssi_proximity = atoi(val_p);
6503             if (msg.rssi_proximity) {
6504                 msg.config_rssi_proximity = true;
6505             } else {
6506                 printMsg("%s:Invalid rssi proximity\n", __FUNCTION__);
6507                 msg.config_rssi_proximity = false;
6508                 ret = WIFI_ERROR_INVALID_ARGS;
6509                 goto exit;
6510             }
6511         } else if (strcmp(param, "-master_pref") == 0) {
6512             msg.master_pref = atoi(val_p);
6513             if (msg.master_pref) {
6514                 msg.config_master_pref = true;
6515             } else {
6516                 printMsg("%s:Invalid master_pref\n", __FUNCTION__);
6517                 msg.config_master_pref = false;
6518                 ret = WIFI_ERROR_INVALID_ARGS;
6519                 goto exit;
6520             }
6521         } else if (strcmp(param, "-rssi_close_prox_5g") == 0) {
6522             msg.rssi_close_proximity_5g_val = atoi(val_p);
6523             if (msg.rssi_close_proximity_5g_val) {
6524                 msg.config_5g_rssi_close_proximity = true;
6525             } else {
6526                 printMsg("%s:Invalid 5g rssi close proximity \n", __FUNCTION__);
6527                 msg.config_5g_rssi_close_proximity = false;
6528                 ret = WIFI_ERROR_INVALID_ARGS;
6529                 goto exit;
6530             }
6531         } else if (strcmp(param, "-rssi_window_size_val") == 0) {
6532             msg.rssi_window_size_val = atoi(val_p);
6533             if (msg.rssi_window_size_val) {
6534                 msg.config_rssi_window_size = true;
6535             } else {
6536                 printMsg("%s:Invalid rssi window size val \n", __FUNCTION__);
6537                 msg.config_rssi_window_size = false;
6538                 ret = WIFI_ERROR_INVALID_ARGS;
6539                 goto exit;
6540             }
6541         } else if (strcmp(param, "-config_cluster_attribute_val") == 0) {
6542             val = atoi(val_p);
6543             /*
6544              * If set to 1, the Discovery Engine will enclose the Cluster
6545              * Attribute only sent in Beacons in a Vendor Specific Attribute
6546              * and transmit in a Service Descriptor Frame.
6547              */
6548 
6549             switch(val) {
6550                 case FEATURE_SUPPORTED:
6551                     msg.config_cluster_attribute_val = FEATURE_SUPPORTED;
6552                     break;
6553                 default:
6554                     msg.config_cluster_attribute_val = FEATURE_NOT_SUPPORTED;
6555                     break;
6556             }
6557         } else if (strcmp(param, "-dwell_time") == 0) {
6558             msg.scan_params_val.dwell_time[0] = atoi(val_p);
6559             if (msg.scan_params_val.dwell_time[0]) {
6560                 msg.config_scan_params = true;
6561             } else {
6562                 msg.config_scan_params = false;
6563                 printMsg("%s:Invalid config_scan_params\n", __FUNCTION__);
6564                 ret = WIFI_ERROR_INVALID_ARGS;
6565                 goto exit;
6566             }
6567         }  else if (strcmp(param, "-scan_period") == 0) {
6568             msg.scan_params_val.scan_period[0] = atoi(val_p);
6569             if (msg.scan_params_val.scan_period[0]) {
6570                 msg.config_scan_params = true;
6571             } else {
6572                 msg.config_scan_params = false;
6573                 printMsg("%s:Invalid config_scan_params\n", __FUNCTION__);
6574                 ret = WIFI_ERROR_INVALID_ARGS;
6575                 goto exit;
6576             }
6577         } else if (strcmp(param, "-dwell_time_5g") == 0) {
6578             msg.scan_params_val.dwell_time[1] = atoi(val_p);
6579             if (msg.scan_params_val.dwell_time[1]) {
6580                 msg.config_scan_params = true;
6581             } else {
6582                 msg.config_scan_params = false;
6583                 printMsg("%s:Invalid config_scan_params for 5g\n", __FUNCTION__);
6584                 ret = WIFI_ERROR_INVALID_ARGS;
6585                 goto exit;
6586             }
6587         }  else if (strcmp(param, "-scan_period_5g") == 0) {
6588                 msg.scan_params_val.scan_period[1] = atoi(val_p);
6589             if (msg.scan_params_val.scan_period[1]) {
6590                 msg.config_scan_params = true;
6591             } else {
6592                 msg.config_scan_params = false;
6593                 printMsg("%s:Invalid config_scan_params for 5g\n", __FUNCTION__);
6594                 ret = WIFI_ERROR_INVALID_ARGS;
6595                 goto exit;
6596             }
6597         } else if (strcmp(param, "-random_factor") == 0) {
6598             msg.random_factor_force_val = atoi(val_p);
6599             if (msg.random_factor_force_val) {
6600                 msg.config_random_factor_force = true;
6601             } else {
6602                 printMsg("%s:Invalid random factor\n", __FUNCTION__);
6603                 msg.config_random_factor_force = false;
6604                 ret = WIFI_ERROR_INVALID_ARGS;
6605                 goto exit;
6606             }
6607         } else if (strcmp(param, "-hc_limit") == 0) {
6608             msg.hop_count_force_val = atoi(val_p);
6609             if (msg.hop_count_force_val) {
6610                 msg.config_hop_count_force = true;
6611             } else {
6612                 printMsg("%s:Invalid hop_count_force_val. Setting to Default\n", __FUNCTION__);
6613                 msg.config_hop_count_force = false;
6614                 ret = WIFI_ERROR_INVALID_ARGS;
6615                 goto exit;
6616             }
6617         } else if (strcmp(param, "-numchans") == 0) {
6618             numchans = atoi(val_p);
6619             if (numchans) {
6620                 msg.config_fam = true;
6621                 msg.fam_val.numchans = numchans;
6622             } else {
6623                 printMsg("%s:Invalid num chan\n", __FUNCTION__);
6624                 msg.config_fam = false;
6625                 ret = WIFI_ERROR_INVALID_ARGS;
6626                 goto exit;
6627             }
6628         } else if (strcmp(param, "-entry_control") == 0) {
6629             val = atoi(val_p);
6630             msg.config_fam = true;
6631             switch(val) {
6632             case NAN_DURATION_16MS:
6633                 msg.fam_val.famchan[numchans].entry_control = NAN_DURATION_16MS;
6634                 break;
6635             case NAN_DURATION_32MS:
6636                 msg.fam_val.famchan[numchans].entry_control = NAN_DURATION_32MS;
6637                 break;
6638             case NAN_DURATION_64MS:
6639                 msg.fam_val.famchan[numchans].entry_control = NAN_DURATION_64MS;
6640                 break;
6641             default:
6642                 printMsg("%s: Invalid entry_control\n", __FUNCTION__);
6643                 ret = WIFI_ERROR_INVALID_ARGS;
6644                 msg.config_fam = false;
6645                 break;
6646             }
6647         } else if (strcmp(param, "-class_val") == 0) {
6648             msg.fam_val.famchan[numchans].class_val = atoi(val_p);
6649             if (msg.fam_val.famchan[numchans].class_val) {
6650                 msg.config_fam = true;
6651             } else {
6652                 printMsg("%s:Invalid fam val\n", __FUNCTION__);
6653                 msg.config_fam = false;
6654                 ret = WIFI_ERROR_INVALID_ARGS;
6655                 goto exit;
6656             }
6657         } else if (strcmp(param, "-channel") == 0) {
6658             msg.fam_val.famchan[numchans].channel = atoi(val_p);
6659             if (msg.fam_val.famchan[numchans].channel) {
6660                 msg.config_fam = true;
6661             } else {
6662                 printMsg("%s:Invalid fam val\n", __FUNCTION__);
6663                 msg.config_fam = false;
6664                 ret = WIFI_ERROR_INVALID_ARGS;
6665                 goto exit;
6666             }
6667         } else if (strcmp(param, "-mapid") == 0) {
6668             msg.fam_val.famchan[numchans].mapid = atoi(val_p);
6669             if (msg.fam_val.famchan[numchans].mapid) {
6670                 msg.config_fam = true;
6671             } else {
6672                 printMsg("%s:Invalid fam val\n", __FUNCTION__);
6673                 msg.config_fam = false;
6674                 ret = WIFI_ERROR_INVALID_ARGS;
6675                 goto exit;
6676             }
6677         } else if (strcmp(param, "-avail_interval_bitmap") == 0) {
6678             msg.fam_val.famchan[numchans].avail_interval_bitmap = atoi(val_p);
6679             printMsg("avail_interval_bitmap = %d\n", msg.fam_val.famchan[numchans].avail_interval_bitmap);
6680             if (msg.fam_val.famchan[numchans].avail_interval_bitmap) {
6681                 msg.config_fam = true;
6682             } else {
6683                 printMsg("%s:Invalid fam val\n", __FUNCTION__);
6684                 msg.config_fam = false;
6685                 ret = WIFI_ERROR_INVALID_ARGS;
6686                 goto exit;
6687             }
6688         } else if (strcmp(param, "-awake_dw_2g") == 0) {
6689             msg.config_dw.dw_2dot4g_interval_val = atoi(val_p);
6690             if (msg.config_dw.dw_2dot4g_interval_val) {
6691                 msg.config_dw.config_2dot4g_dw_band = true;
6692             }
6693         } else if (strcmp(param, "-awake_dw_5g") == 0) {
6694             msg.config_dw.dw_5g_interval_val = atoi(val_p);
6695             if (msg.config_dw.dw_5g_interval_val) {
6696                 msg.config_dw.config_5g_dw_band = true;
6697             }
6698         } else if (strncmp(param, "-disc_ind_cfg", strlen("-disc_ind_cfg")) == 0) {
6699                 msg.discovery_indication_cfg = strtoul(val_p, &endptr, 0);
6700                 printMsg("%s:disc_ind_cfg value = %d.\n",
6701                     __FUNCTION__, msg.discovery_indication_cfg);
6702         } else if (strcmp(param, "-use_ndpe") == 0) {
6703             msg.use_ndpe_attr = atoi(val_p);
6704             msg.config_ndpe_attr = true;
6705             if ((msg.use_ndpe_attr != 1) && (msg.use_ndpe_attr != 0)) {
6706                 msg.config_ndpe_attr = false;
6707                 printMsg("%s:Invalid use_ndpe_attr value\n", __FUNCTION__);
6708                 ret = WIFI_ERROR_INVALID_ARGS;
6709                 goto exit;
6710             }
6711         } else if (strncmp(param, "-rand_mac", strlen("-rand_mac")) == 0) {
6712             msg.config_disc_mac_addr_randomization = true;
6713             msg.disc_mac_addr_rand_interval_sec = atoi(val_p);
6714         } else if (strcmp(param, "-disc_bcn_interval") == 0) {
6715                 msg.discovery_beacon_interval = atoi(val_p);
6716                 msg.config_discovery_beacon_int = true;
6717         } else if (strcmp(param, "-enable_ranging") == 0) {
6718             msg.enable_ranging = atoi(val_p);
6719             if (msg.enable_ranging) {
6720                 msg.config_enable_ranging = true;
6721             }
6722         } else if (strcmp(param, "-nss") == 0) {
6723             msg.nss = atoi(val_p);
6724             if (msg.nss) {
6725                 msg.config_nss = true;
6726             }
6727         } else if (strcmp(param, "-enable_dw_term") == 0) {
6728             msg.enable_dw_termination = atoi(val_p);
6729             if (msg.enable_dw_termination) {
6730                 msg.config_dw_early_termination = true;
6731             }
6732 #ifdef NAN_3_1_SUPPORT
6733         } else if (strcmp(param, "-instant_mode") == 0) {
6734             msg.enable_instant_mode = atoi(val_p);
6735             msg.config_enable_instant_mode = true;
6736         } else if (strcmp(param, "-instant_chan") == 0) {
6737             msg.instant_mode_channel = atoi(val_p);
6738             if (msg.instant_mode_channel) {
6739                 msg.config_instant_mode_channel = true;
6740             } else {
6741                 printMsg("%s:Invalid Instant channel \n", __FUNCTION__);
6742                 msg.config_instant_mode_channel = false;
6743                 ret = WIFI_ERROR_INVALID_ARGS;
6744                 goto exit;
6745             }
6746 #endif /* NAN_3_1_SUPPORT */
6747         } else {
6748             printMsg("%s:Unsupported Parameter for Nan Config\n", __FUNCTION__);
6749             ret = WIFI_ERROR_INVALID_ARGS;
6750             goto exit;
6751         }
6752     }
6753 
6754     nanCmdId = getNewCmdId();
6755     ret = nan_init_handlers();
6756     if (ret != WIFI_SUCCESS) {
6757         printMsg("Failed to initialize handlers %d\n", ret);
6758         goto exit;
6759     }
6760     ret = nan_config_request(nanCmdId, wlan0Handle, &msg);
6761 exit:
6762     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
6763     return;
6764 }
6765 
publishNan(int argc,char * argv[])6766 void publishNan(int argc, char *argv[]) {
6767     NanPublishRequest msg;
6768     wifi_error ret = WIFI_SUCCESS;
6769     char *param = NULL, *val_p = NULL, *endptr = NULL;
6770     u32 val = 0;
6771     u8 *match_rxtmp = NULL, *match_txtmp = NULL;
6772 
6773     /* skip utility */
6774     argv++;
6775     /* skip command */
6776     argv++;
6777     /* skip command */
6778     argv++;
6779 
6780     memset(&msg, 0, sizeof(msg));
6781     msg.publish_id = 0;
6782     msg.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
6783     msg.publish_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
6784     msg.tx_type = NAN_TX_TYPE_UNICAST;
6785     msg.sdea_params.ndp_type = NAN_DATA_PATH_UNICAST_MSG;
6786     msg.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_NONE;
6787     msg.period = 1;
6788 
6789     while ((param = *argv++) != NULL) {
6790         val_p = *argv++;
6791         if (!val_p || *val_p == '-') {
6792             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
6793             ret = WIFI_ERROR_NOT_SUPPORTED;
6794             goto exit;
6795         }
6796         if (strcmp(param, "-svc") == 0) {
6797             if (strlen((const char *)val_p) > NAN_MAX_SERVICE_NAME_LEN) {
6798                 printMsg("Invalid  service name\n");
6799                 ret = WIFI_ERROR_INVALID_ARGS;
6800                 goto exit;
6801             } else {
6802                 msg.service_name_len =
6803                 strlen((const char *)val_p);
6804                 if (!set_interface_params((char*)msg.service_name,
6805                     val_p, msg.service_name_len)) {
6806                     printMsg("Set service name successfull\n");
6807                 }
6808             }
6809         } else if (strcmp(param, "-info") == 0) {
6810             if (strlen((const char*)val_p) > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
6811                 printMsg("Invalid  service specific info\n");
6812                 ret = WIFI_ERROR_INVALID_ARGS;
6813                 goto exit;
6814             } else {
6815                 msg.service_specific_info_len =
6816                 strlen((const char*)val_p);
6817                 if (!set_interface_params((char*)msg.service_specific_info,
6818                     val_p, msg.service_specific_info_len)) {
6819                     printMsg("Set service specific info successfull\n");
6820                 }
6821             }
6822         } else if (strcmp(param, "-pub_count") == 0) {
6823             msg.publish_count = strtoul(val_p, &endptr, 0);
6824         } else if (strcmp(param, "-pub_id") == 0) {
6825             msg.publish_id = strtoul(val_p, &endptr, 0);
6826         } else if (strcmp(param, "-pub_type") == 0) {
6827             val = atoi(val_p);
6828             switch(val) {
6829                 case NAN_PUBLISH_TYPE_UNSOLICITED:
6830                     msg.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED;
6831                     break;
6832                 case NAN_PUBLISH_TYPE_SOLICITED:
6833                     msg.publish_type = NAN_PUBLISH_TYPE_SOLICITED;
6834                     break;
6835                 default:
6836                     msg.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
6837                     break;
6838             }
6839         } else if (strcmp(param, "-tx_type") == 0) {
6840             val = atoi(val_p);
6841             switch(val) {
6842                 case NAN_TX_TYPE_BROADCAST:
6843                     msg.tx_type = NAN_TX_TYPE_BROADCAST;
6844                     break;
6845                 default:
6846                     msg.tx_type = NAN_TX_TYPE_UNICAST;
6847                     break;
6848             }
6849         } else if (strcmp(param, "-ttl") == 0) {
6850             msg.ttl = strtoul(val_p, &endptr, 0);
6851         } else if (strcmp(param, "-svc_awake_dw") == 0) {
6852             msg.period = strtoul(val_p, &endptr, 0);
6853         } else if (strcmp(param, "-match_tx") == 0) {
6854             u8 m_len = strlen(val_p);
6855             if (!match_txtmp) {
6856                 match_txtmp = msg.tx_match_filter;
6857             }
6858             if (strcmp(val_p, "0") == 0) {
6859                 printMsg("wild card\n");
6860                 if (m_len < (NAN_MAX_MATCH_FILTER_LEN - msg.tx_match_filter_len)) {
6861                     *match_txtmp++ = 0;
6862                     msg.tx_match_filter_len++;
6863                 }
6864             } else {
6865             if (m_len < (NAN_MAX_MATCH_FILTER_LEN - msg.tx_match_filter_len)) {
6866                 *match_txtmp++ = strlen(val_p);
6867                 msg.tx_match_filter_len++;
6868                 strncpy((char *)match_txtmp, val_p, strlen(val_p));
6869                 match_txtmp += m_len;
6870                 msg.tx_match_filter_len += m_len;
6871             } else {
6872                 printMsg("Invalid match filter len\n");
6873                 ret = WIFI_ERROR_INVALID_ARGS;
6874                 goto exit;
6875                 }
6876             }
6877         } else if (strcmp(param, "-match_rx") == 0) {
6878             u8 m_len = strlen(val_p);
6879             if (!match_rxtmp) {
6880                 match_rxtmp = msg.rx_match_filter;
6881             }
6882             if (strcmp(val_p, "0") == 0) {
6883                 printMsg("wild card\n");
6884                 if (m_len < (NAN_MAX_MATCH_FILTER_LEN - msg.rx_match_filter_len)) {
6885                     *match_rxtmp++ = 0;
6886                     msg.rx_match_filter_len++;
6887                 }
6888             } else {
6889                 if (m_len < (NAN_MAX_MATCH_FILTER_LEN - msg.rx_match_filter_len)) {
6890                     *match_rxtmp++ = strlen(val_p);
6891                     msg.rx_match_filter_len++;
6892                     strncpy((char *)match_rxtmp, val_p, strlen(val_p));
6893                     match_rxtmp += m_len;
6894                     msg.rx_match_filter_len += m_len;
6895                 } else {
6896                     printMsg("Invalid match filter len\n");
6897                     ret = WIFI_ERROR_INVALID_ARGS;
6898                     goto exit;
6899                 }
6900             }
6901         } else if (strncmp(param, "-recv_flag", strlen("-recv_flag")) == 0) {
6902             msg.recv_indication_cfg = strtoul(val_p, &endptr, 0);
6903         } else if (strcmp(param, "-match_ind") == 0) {
6904             val = atoi(val_p);
6905             switch(val) {
6906                 case NAN_MATCH_ALG_MATCH_ONCE:
6907                     msg.publish_match_indicator = NAN_MATCH_ALG_MATCH_ONCE;
6908                     break;
6909                 case NAN_MATCH_ALG_MATCH_NEVER:
6910                     msg.publish_match_indicator = NAN_MATCH_ALG_MATCH_NEVER;
6911                     break;
6912                 default:
6913                     msg.publish_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
6914                     break;
6915             }
6916         } else if (strcmp(param, "-csid") == 0) {
6917             val = atoi(val_p);
6918             switch(val) {
6919                 case NAN_CIPHER_SUITE_SHARED_KEY_NONE:
6920                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_NONE;
6921                     break;
6922                 case NAN_CIPHER_SUITE_SHARED_KEY_128_MASK:
6923                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_128_MASK;
6924                     break;
6925                 case NAN_CIPHER_SUITE_SHARED_KEY_256_MASK:
6926                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_256_MASK;
6927                     break;
6928 #ifdef NAN_3_1_SUPPORT
6929                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK:
6930                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK;
6931                     break;
6932                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK:
6933                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK;
6934                     break;
6935 #endif /* NAN_3_1_SUPPORT */
6936                 default:
6937                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_NONE;
6938                     break;
6939             }
6940         } else if (strcmp(param, "-key_type") == 0) {
6941             val = atoi(val_p);
6942             switch(val) {
6943                 case NAN_SECURITY_KEY_INPUT_PMK:
6944                     msg.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
6945                     break;
6946                 case NAN_SECURITY_KEY_INPUT_PASSPHRASE:
6947                     msg.key_info.key_type = NAN_SECURITY_KEY_INPUT_PASSPHRASE;
6948                     break;
6949                 default:
6950                     printMsg("Invalid security key type\n");
6951                     ret = WIFI_ERROR_INVALID_ARGS;
6952                     goto exit;
6953             }
6954         } else if (strcmp(param, "-pmk") == 0) {
6955             if (strlen((const char*)val_p) > NAN_PMK_INFO_LEN) {
6956                 printMsg("Invalid PMK\n");
6957                 ret = WIFI_ERROR_INVALID_ARGS;
6958                 goto exit;
6959             } else {
6960                 msg.key_info.body.pmk_info.pmk_len=
6961                 strlen((const char*)val_p);
6962                 if (!set_interface_params((char*)msg.key_info.body.pmk_info.pmk,
6963                     val_p, msg.key_info.body.pmk_info.pmk_len)) {
6964                     printMsg("Set PMK successfull\n");
6965                 }
6966             }
6967         } else if (strcmp(param, "-passphrase") == 0) {
6968             if (strlen((const char*)val_p) < NAN_SECURITY_MIN_PASSPHRASE_LEN ||
6969                 strlen((const char*)val_p) > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
6970                 printMsg("passphrase must be between %d and %d characters long\n",
6971                 NAN_SECURITY_MIN_PASSPHRASE_LEN,
6972                 NAN_SECURITY_MAX_PASSPHRASE_LEN);
6973                 ret = WIFI_ERROR_INVALID_ARGS;
6974                 goto exit;
6975             } else {
6976                 msg.key_info.body.passphrase_info.passphrase_len =
6977                 (strlen((const char*)val_p));
6978                 if (!set_interface_params((char*)msg.key_info.body.passphrase_info.passphrase,
6979                     val_p, msg.key_info.body.passphrase_info.passphrase_len)) {
6980                     printMsg("Set passphrase successfull, len = %d\n", msg.key_info.body.passphrase_info.passphrase_len);
6981                 } else {
6982                     printMsg("Invalid passphrase\n");
6983                     ret = WIFI_ERROR_INVALID_ARGS;
6984                     goto exit;
6985                 }
6986             }
6987         } else if (strcmp(param, "-scid") == 0) {
6988             if (strlen((const char*)val_p) > NAN_MAX_SCID_BUF_LEN) {
6989                printMsg("Invalid SCID\n");
6990                ret = WIFI_ERROR_INVALID_ARGS;
6991                goto exit;
6992             } else {
6993                msg.scid_len=
6994                strlen((const char*)val_p);
6995                if (!set_interface_params((char*)msg.scid,
6996                   val_p, msg.scid_len)) {
6997                   printMsg("Set SCID successfull\n");
6998                }
6999             }
7000         } else if (strcmp(param, "-dp_type") == 0) {
7001             val = atoi(val_p);
7002             msg.sdea_params.config_nan_data_path = true;
7003             switch(val) {
7004                 case NAN_DATA_PATH_MULTICAST_MSG:
7005                     msg.sdea_params.ndp_type = NAN_DATA_PATH_MULTICAST_MSG;
7006                     break;
7007                 case NAN_DATA_PATH_UNICAST_MSG:
7008                     msg.sdea_params.ndp_type = NAN_DATA_PATH_UNICAST_MSG;
7009                     break;
7010                 default:
7011                     printMsg("Invalid datapath type\n");
7012                     msg.sdea_params.config_nan_data_path = false;
7013                     ret = WIFI_ERROR_INVALID_ARGS;
7014                     break;
7015             }
7016         } else if (strcmp(param, "-secure_dp") == 0) {
7017             val = atoi(val_p);
7018             switch(val) {
7019                 case NAN_DP_CONFIG_SECURITY:
7020                     msg.sdea_params.security_cfg = NAN_DP_CONFIG_SECURITY;
7021                     break;
7022                 default:
7023                     msg.sdea_params.security_cfg = NAN_DP_CONFIG_NO_SECURITY;
7024                     break;
7025             }
7026         } else if (strcmp(param, "-ranging") == 0) {
7027             val = atoi(val_p);
7028             switch(val) {
7029                 case NAN_RANGING_ENABLE:
7030                     msg.sdea_params.ranging_state = NAN_RANGING_ENABLE;
7031                     break;
7032                 default:
7033                     msg.sdea_params.ranging_state = NAN_RANGING_DISABLE;
7034                     break;
7035                 }
7036         } else if (strcmp(param, "-ranging_intvl") == 0) {
7037             msg.ranging_cfg.ranging_interval_msec = atoi(val_p);
7038         } else if (strcmp(param, "-ranging_ind") == 0) {
7039             msg.ranging_cfg.config_ranging_indications = atoi(val_p);
7040         } else if (strcmp(param, "-ingress") == 0) {
7041             msg.ranging_cfg.distance_ingress_mm = atoi(val_p);
7042         } else if (strcmp(param, "-egress") == 0) {
7043             msg.ranging_cfg.distance_egress_mm= atoi(val_p);
7044         } else if (strcmp(param, "-rssi_thresh_flag") == 0) {
7045             msg.rssi_threshold_flag = atoi(val_p);
7046         } else if (strcmp(param, "-sdea_info") == 0) {
7047             if (strlen((const char*)val_p) > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
7048                 printMsg("Invalid SDEA service specific info\n");
7049                 ret = WIFI_ERROR_INVALID_ARGS;
7050                 goto exit;
7051             } else {
7052                 msg.sdea_service_specific_info_len =
7053                    strlen((const char*)val_p);
7054                 if (!set_interface_params((char*)msg.sdea_service_specific_info,
7055                     val_p, msg.sdea_service_specific_info_len)) {
7056                         printMsg("Set SDEA service specific info successfull\n");
7057                 }
7058             }
7059         } else if (strcmp(param, "-auto_dp_accept") == 0) {
7060             val = atoi(val_p);
7061             switch(val) {
7062                 case NAN_SERVICE_ACCEPT_POLICY_ALL:
7063                 msg.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_ALL;
7064                 break;
7065                 default:
7066                 msg.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_NONE;
7067                 break;
7068             }
7069         } else {
7070            printMsg("%s:Unsupported Parameter for Nan Publish\n", __FUNCTION__);
7071            goto exit;
7072         }
7073     }
7074     if (!msg.service_name_len) {
7075         printMsg("service name is mandatory !!\n");
7076         goto exit;
7077     }
7078 
7079     nanCmdId = getNewCmdId();
7080     ret = nan_init_handlers();
7081     if (ret != WIFI_SUCCESS) {
7082         printMsg("Failed to initialize handlers %d\n", ret);
7083         goto exit;
7084     }
7085     ret = nan_publish_request(nanCmdId, wlan0Handle, &msg);
7086 exit:
7087     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
7088     return;
7089 }
7090 
subscribeNan(int argc,char * argv[])7091 void subscribeNan(int argc, char *argv[]) {
7092     NanSubscribeRequest msg;
7093     wifi_error ret = WIFI_SUCCESS;
7094     char *param = NULL, *val_p = NULL, *endptr = NULL;
7095     u8 num_mac_addr = 0;
7096     u32 val = 0;
7097     u8 *match_rxtmp = NULL, *match_txtmp = NULL;
7098 
7099     /* skip utility */
7100     argv++;
7101     /* skip command */
7102     argv++;
7103     /* skip command */
7104     argv++;
7105 
7106     memset(&msg, 0, sizeof(msg));
7107 
7108     /* set mandatory default values */
7109     msg.subscribe_id = 0;
7110     msg.subscribe_type = NAN_SUBSCRIBE_TYPE_PASSIVE;
7111     msg.useServiceResponseFilter = NAN_DO_NOT_USE_SRF;
7112     /*
7113      * Set NAN_MATCH_ALG_MATCH_ONCE as default param to avoid
7114      * flooding of discovery result events
7115      */
7116     msg.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_ONCE;
7117     msg.sdea_params.ndp_type = NAN_DATA_PATH_UNICAST_MSG;
7118     msg.rx_match_filter_len = 0;
7119     msg.tx_match_filter_len = 0;
7120     msg.period = 1;
7121 
7122     while ((param = *argv++) != NULL) {
7123         val_p = *argv++;
7124         if (!val_p || *val_p == '-') {
7125             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
7126             ret = WIFI_ERROR_NOT_SUPPORTED;
7127             goto exit;
7128         }
7129         if (strcmp(param, "-svc") == 0) {
7130             if (strlen((const char *)val_p) > NAN_MAX_SERVICE_NAME_LEN) {
7131                 printMsg("Invalid service name\n");
7132                 ret = WIFI_ERROR_INVALID_ARGS;
7133                 goto exit;
7134             } else {
7135                 msg.service_name_len =
7136                 strlen((const char *)val_p);
7137                 if (!set_interface_params((char*)msg.service_name,
7138                     val_p, msg.service_name_len)) {
7139                         printMsg("Set service name successfull\n");
7140                 }
7141             }
7142         } else if (strcmp(param, "-info") == 0) {
7143             if (strlen((const char*)val_p) > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
7144                 printMsg("Invalid  service specific info\n");
7145                 ret = WIFI_ERROR_INVALID_ARGS;
7146                 goto exit;
7147             } else {
7148                 msg.service_specific_info_len =
7149                 strlen((const char*)val_p);
7150                 if (!set_interface_params((char*)msg.service_specific_info,
7151                     val_p, msg.service_specific_info_len)) {
7152                     printMsg("Set service specific info successfull\n");
7153                 }
7154             }
7155         } else if (strcmp(param, "-sub_count") == 0) {
7156             msg.subscribe_count = strtoul(val_p, &endptr, 0);
7157         } else if (strcmp(param, "-pub_ssi") == 0) {
7158             val = atoi(val_p);
7159             /*
7160              * Flag which specifies if the Service Specific Info is needed in
7161              * the Publish message before creating the MatchIndication
7162              */
7163             /* 0= Not needed, 1= Required */
7164             switch(val) {
7165                 case NAN_SSI_REQUIRED_IN_MATCH_IND:
7166                     msg.ssiRequiredForMatchIndication = NAN_SSI_REQUIRED_IN_MATCH_IND;
7167                     break;
7168                 default:
7169                     msg.ssiRequiredForMatchIndication = NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
7170                     break;
7171             }
7172         } else if (strcmp(param, "-sub_id") == 0) {
7173             msg.subscribe_id = strtoul(val_p, &endptr, 0);
7174         } else if (strcmp(param, "-sub_type") == 0) {
7175             val = atoi(val_p);
7176             switch(val) {
7177                 case NAN_SUBSCRIBE_TYPE_ACTIVE:
7178                     msg.subscribe_type = NAN_SUBSCRIBE_TYPE_ACTIVE;
7179                     break;
7180                 default:
7181                     msg.subscribe_type = NAN_SUBSCRIBE_TYPE_PASSIVE;
7182                     break;
7183             }
7184         } else if (strcmp(param, "-ttl") == 0) {
7185             msg.ttl = strtoul(val_p, &endptr, 0);
7186         } else if (strcmp(param, "-svc_awake_dw") == 0) {
7187             msg.period = strtoul(val_p, &endptr, 0);
7188         } else if (strncmp(param, "-srf_use", strlen("-srf_use")) == 0) {
7189             val = atoi(val_p);
7190             /* 0=Do not send the Service Response Filter,1= send */
7191             switch(val) {
7192                 case NAN_USE_SRF:
7193                     msg.useServiceResponseFilter = NAN_USE_SRF;
7194                     break;
7195                 default:
7196                     msg.useServiceResponseFilter = NAN_DO_NOT_USE_SRF;
7197                     break;
7198             }
7199         } else if (strncmp(param, "-srf_include", strlen("-srf_include")) == 0) {
7200             val = strtoul(val_p, &endptr, 0);
7201             /* 0=Do not respond if in the Address Set, 1= Respond */
7202             switch(val) {
7203                 case NAN_SRF_INCLUDE_RESPOND:
7204                     msg.serviceResponseInclude = NAN_SRF_INCLUDE_RESPOND;
7205                     break;
7206                 default:
7207                     msg.serviceResponseInclude = NAN_SRF_INCLUDE_DO_NOT_RESPOND;
7208                     break;
7209             }
7210         } else if (strncmp(param, "-srf_type", strlen("-srf_type")) == 0) {
7211             val = atoi(val_p);
7212             /* 0 - Bloom Filter, 1 - MAC Addr */
7213             switch(val) {
7214                 case NAN_SRF_ATTR_PARTIAL_MAC_ADDR:
7215                     msg.serviceResponseFilter = NAN_SRF_ATTR_PARTIAL_MAC_ADDR;
7216                     break;
7217                 default:
7218                     msg.serviceResponseFilter = NAN_SRF_ATTR_BLOOM_FILTER;
7219                     break;
7220             }
7221         } else if (strcmp(param, "-mac_list") == 0) {
7222             if (num_mac_addr < NAN_MAX_SUBSCRIBE_MAX_ADDRESS) {
7223                 if (!ether_atoe(val_p, msg.intf_addr[num_mac_addr])) {
7224                     printMsg("bad mac addr !!\n");
7225                     ret = WIFI_ERROR_INVALID_ARGS;
7226                     goto exit;
7227                 }
7228                 msg.num_intf_addr_present = ++num_mac_addr;
7229             } else {
7230                 printMsg("max limit reached, %d!!!\n", num_mac_addr);
7231                 ret = WIFI_ERROR_INVALID_ARGS;
7232                 goto exit;
7233             }
7234             if (msg.num_intf_addr_present) {
7235                 msg.useServiceResponseFilter = NAN_USE_SRF;
7236                 msg.serviceResponseFilter = NAN_SRF_ATTR_PARTIAL_MAC_ADDR;
7237             }
7238         } else if (strcmp(param, "-match_ind") == 0) {
7239             val = atoi(val_p);
7240             switch(val) {
7241                 case NAN_MATCH_ALG_MATCH_ONCE:
7242                     msg.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_ONCE;
7243                     break;
7244                 case NAN_MATCH_ALG_MATCH_NEVER:
7245                     msg.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_NEVER;
7246                     break;
7247                 default:
7248                     msg.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_CONTINUOUS;
7249                     break;
7250             }
7251         } else if (strcmp(param, "-match_tx") == 0) {
7252             u8 m_len = strlen(val_p);
7253             if (!match_txtmp) {
7254                 match_txtmp = msg.tx_match_filter;
7255             }
7256             if (strcmp(val_p, "0") == 0) {
7257                 printMsg("wild card\n");
7258                 if (m_len < (NAN_MAX_MATCH_FILTER_LEN - msg.tx_match_filter_len)) {
7259                     *match_txtmp++ = 0;
7260                     msg.tx_match_filter_len++;
7261                 }
7262             } else {
7263                 if (m_len < (NAN_MAX_MATCH_FILTER_LEN - msg.tx_match_filter_len)) {
7264                     *match_txtmp++ = strlen(val_p);
7265                     msg.tx_match_filter_len++;
7266                     strncpy((char *)match_txtmp, val_p, strlen(val_p));
7267                     match_txtmp += m_len;
7268                     msg.tx_match_filter_len += m_len;
7269                 } else {
7270                     printMsg("Invalid match filter len\n");
7271                     ret = WIFI_ERROR_INVALID_ARGS;
7272                     goto exit;
7273                 }
7274             }
7275         } else if (strcmp(param, "-match_rx") == 0) {
7276             u8 m_len = strlen(val_p);
7277             if (!match_rxtmp) {
7278                 match_rxtmp = msg.rx_match_filter;
7279             }
7280             if (strcmp(val_p, "0") == 0) {
7281                 printMsg("wild card\n");
7282                 if (m_len < (NAN_MAX_MATCH_FILTER_LEN - msg.rx_match_filter_len)) {
7283                     *match_rxtmp++ = 0;
7284                     msg.rx_match_filter_len++;
7285                 }
7286             } else {
7287                 if (m_len < (NAN_MAX_MATCH_FILTER_LEN - msg.rx_match_filter_len)) {
7288                     *match_rxtmp++ = strlen(val_p);
7289                     msg.rx_match_filter_len++;
7290                     strncpy((char *)match_rxtmp, val_p, strlen(val_p));
7291                     match_rxtmp += m_len;
7292                     msg.rx_match_filter_len += m_len;
7293                 } else {
7294                     printMsg("Invalid match filter len\n");
7295                     ret = WIFI_ERROR_INVALID_ARGS;
7296                     goto exit;
7297                 }
7298             }
7299         } else if (strncmp(param, "-recv_flag", strlen("-recv_flag")) == 0) {
7300             msg.recv_indication_cfg = strtoul(val_p, &endptr, 0);
7301         } else if (strcmp(param, "-csid") == 0) {
7302             val = atoi(val_p);
7303             switch(val) {
7304                 case NAN_CIPHER_SUITE_SHARED_KEY_NONE:
7305                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_NONE;
7306                     break;
7307                 case NAN_CIPHER_SUITE_SHARED_KEY_128_MASK:
7308                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_128_MASK;
7309                     break;
7310                 case NAN_CIPHER_SUITE_SHARED_KEY_256_MASK:
7311                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_256_MASK;
7312                     break;
7313 #ifdef NAN_3_1_SUPPORT
7314                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK:
7315                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK;
7316                     break;
7317                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK:
7318                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK;
7319                     break;
7320 #endif /* NAN_3_1_SUPPORT */
7321                 default:
7322                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_NONE;
7323                     break;
7324             }
7325         } else if (strcmp(param, "-key_type") == 0) {
7326             val = atoi(val_p);
7327             switch(val) {
7328                 case NAN_SECURITY_KEY_INPUT_PMK:
7329                     msg.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
7330                     break;
7331                 case NAN_SECURITY_KEY_INPUT_PASSPHRASE:
7332                     msg.key_info.key_type = NAN_SECURITY_KEY_INPUT_PASSPHRASE;
7333                     break;
7334                 default:
7335                     printMsg("Invalid security key type\n");
7336                     ret = WIFI_ERROR_INVALID_ARGS;
7337                     goto exit;
7338             }
7339         } else if (strcmp(param, "-pmk") == 0) {
7340             if (strlen((const char*)val_p) > NAN_PMK_INFO_LEN) {
7341                 printMsg("Invalid PMK\n");
7342                 ret = WIFI_ERROR_INVALID_ARGS;
7343                 goto exit;
7344             } else {
7345                 msg.key_info.body.pmk_info.pmk_len=
7346                 strlen((const char*)val_p);
7347                 if (!set_interface_params((char*)msg.key_info.body.pmk_info.pmk,
7348                     val_p, msg.key_info.body.pmk_info.pmk_len)) {
7349                     printMsg("Set PMK successfull\n");
7350                 }
7351             }
7352         } else if (strcmp(param, "-passphrase") == 0) {
7353             if (strlen((const char*)val_p) < NAN_SECURITY_MIN_PASSPHRASE_LEN ||
7354                 strlen((const char*)val_p) > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
7355                     printMsg("passphrase must be between %d and %d characters long\n",
7356                     NAN_SECURITY_MIN_PASSPHRASE_LEN,
7357                     NAN_SECURITY_MAX_PASSPHRASE_LEN);
7358                     ret = WIFI_ERROR_INVALID_ARGS;
7359                     goto exit;
7360             } else {
7361                 msg.key_info.body.passphrase_info.passphrase_len =
7362                 (strlen((const char*)val_p));
7363                 if (!set_interface_params((char*)msg.key_info.body.passphrase_info.passphrase,
7364                     val_p, msg.key_info.body.passphrase_info.passphrase_len)) {
7365                     printMsg("Set passphrase successfull, len = %d\n", msg.key_info.body.passphrase_info.passphrase_len);
7366                 } else {
7367                     printMsg("Invalid passphrase\n");
7368                     ret = WIFI_ERROR_INVALID_ARGS;
7369                     goto exit;
7370                }
7371             }
7372         } else if (strcmp(param, "-scid") == 0) {
7373             if (strlen((const char*)val_p) > NAN_MAX_SCID_BUF_LEN) {
7374                 printMsg("Invalid SCID\n");
7375                 ret = WIFI_ERROR_INVALID_ARGS;
7376                 goto exit;
7377             } else {
7378                 msg.scid_len=
7379                 strlen((const char*)val_p);
7380                 if (!set_interface_params((char*)msg.scid,
7381                     val_p, msg.scid_len)) {
7382                     printMsg("Set SCID successfull\n");
7383                 }
7384             }
7385         } else if (strcmp(param, "-dp_type") == 0) {
7386             val = atoi(val_p);
7387             msg.sdea_params.config_nan_data_path = true;
7388             switch(val) {
7389                 case NAN_DATA_PATH_MULTICAST_MSG:
7390                     msg.sdea_params.ndp_type = NAN_DATA_PATH_MULTICAST_MSG;
7391                     break;
7392                 case NAN_DATA_PATH_UNICAST_MSG:
7393                     msg.sdea_params.ndp_type = NAN_DATA_PATH_UNICAST_MSG;
7394                     break;
7395                 default:
7396                     printMsg("Invalid datapath type\n");
7397                     msg.sdea_params.config_nan_data_path = false;
7398                     ret = WIFI_ERROR_INVALID_ARGS;
7399                     break;
7400             }
7401         } else if (strcmp(param, "-secure_dp") == 0) {
7402             val = atoi(val_p);
7403             switch(val) {
7404                 case NAN_DP_CONFIG_SECURITY:
7405                     msg.sdea_params.security_cfg = NAN_DP_CONFIG_SECURITY;
7406                     break;
7407                 default:
7408                     msg.sdea_params.security_cfg = NAN_DP_CONFIG_NO_SECURITY;
7409                     break;
7410             }
7411         } else if (strcmp(param, "-ranging") == 0) {
7412             val = atoi(val_p);
7413             switch(val) {
7414                 case NAN_RANGING_ENABLE:
7415                     msg.sdea_params.ranging_state = NAN_RANGING_ENABLE;
7416                     break;
7417                 default:
7418                     msg.sdea_params.ranging_state = NAN_RANGING_DISABLE;
7419                     break;
7420                 }
7421         } else if (strcmp(param, "-ranging_intvl") == 0) {
7422             msg.ranging_cfg.ranging_interval_msec = atoi(val_p);
7423         } else if (strcmp(param, "-ranging_ind") == 0) {
7424             msg.ranging_cfg.config_ranging_indications = atoi(val_p);
7425         } else if (strcmp(param, "-ingress") == 0) {
7426             msg.ranging_cfg.distance_ingress_mm = atoi(val_p);
7427         } else if (strcmp(param, "-egress") == 0) {
7428             msg.ranging_cfg.distance_egress_mm= atoi(val_p);
7429         } else if (strcmp(param, "-rssi_thresh_flag") == 0) {
7430             msg.rssi_threshold_flag = atoi(val_p);
7431         } else if (strcmp(param, "-sdea_info") == 0) {
7432             if (strlen((const char*)val_p) > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
7433                 printMsg("Invalid SDEA service specific info\n");
7434                 ret = WIFI_ERROR_INVALID_ARGS;
7435                 goto exit;
7436             } else {
7437                 msg.sdea_service_specific_info_len = strlen((const char*)val_p);
7438                 if (!set_interface_params((char*)msg.sdea_service_specific_info,
7439                     val_p, msg.sdea_service_specific_info_len)) {
7440                     printMsg("Set SDEA service specific info successfull\n");
7441                 }
7442             }
7443         } else {
7444             printMsg("%s:Unsupported Parameter for Nan Subscribe\n", __FUNCTION__);
7445             goto exit;
7446         }
7447     }
7448     if (!msg.service_name_len) {
7449         printMsg("service name is mandatory !!\n");
7450         goto exit;
7451     }
7452 
7453     nanCmdId = getNewCmdId();
7454     ret = nan_init_handlers();
7455     if (ret != WIFI_SUCCESS) {
7456         printMsg("Failed to initialize handlers %d\n", ret);
7457         goto exit;
7458     }
7459     ret = nan_subscribe_request(nanCmdId, wlan0Handle, &msg);
7460 exit:
7461     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
7462     return;
7463 }
7464 
cancelPublishNan(char * argv[])7465 void cancelPublishNan(char *argv[]) {
7466     NanPublishCancelRequest msg ;
7467     wifi_error ret = WIFI_SUCCESS;
7468     u16 pub_id;
7469     pub_id = atoi(argv[3]);
7470     if (pub_id) {
7471         msg.publish_id = pub_id;
7472     } else {
7473         printMsg("\nInvalid argument \n");
7474         ret = WIFI_ERROR_INVALID_ARGS;
7475         goto exit;
7476     }
7477     nanCmdId = getNewCmdId();
7478     ret = nan_init_handlers();
7479     if (ret != WIFI_SUCCESS) {
7480         printMsg("Failed to initialize handlers %d\n", ret);
7481         goto exit;
7482     }
7483     ret = nan_publish_cancel_request(nanCmdId, wlan0Handle, &msg);
7484 exit:
7485     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
7486     return;
7487 }
7488 
7489 
cancelSubscribeNan(char * argv[])7490 void cancelSubscribeNan(char *argv[]) {
7491     NanSubscribeCancelRequest msg ;
7492     wifi_error ret = WIFI_SUCCESS;
7493     u16 sub_id;
7494     sub_id = atoi(argv[3]);
7495     if (sub_id) {
7496         msg.subscribe_id = sub_id;
7497     } else {
7498         printMsg("\nInvalid argument \n");
7499         ret = WIFI_ERROR_INVALID_ARGS;
7500         goto exit;
7501     }
7502     nanCmdId = getNewCmdId();
7503     ret = nan_init_handlers();
7504     if (ret != WIFI_SUCCESS) {
7505         printMsg("Failed to initialize handlers %d\n", ret);
7506         goto exit;
7507     }
7508     ret = nan_subscribe_cancel_request(nanCmdId, wlan0Handle, &msg);
7509 #ifdef NAN_BLOCK_FOR_EVENT
7510     memset(&info, 0, sizeof(info));
7511     getEventFromCache(info);
7512     printMsg("retrieved event %d : %s\n", info.type, info.buf);
7513 #endif
7514 exit:
7515     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
7516     return;
7517 }
7518 
transmitNan(int argc,char * argv[])7519 void transmitNan(int argc, char *argv[]) {
7520     NanTransmitFollowupRequest msg;
7521     wifi_error ret = WIFI_SUCCESS;
7522     char *param = NULL, *val_p = NULL, *endptr = NULL;
7523     u16 src_id = 0;
7524     u32 dest_id = 0;
7525     u8 *mac_addr = NULL;
7526 
7527     /* skip utility */
7528     argv++;
7529     /* skip command */
7530     argv++;
7531     /* skip command */
7532     argv++;
7533 
7534     memset(&msg, 0, sizeof(msg));
7535     while ((param = *argv++) != NULL) {
7536         val_p = *argv++;
7537         if (!val_p || *val_p == '-') {
7538             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
7539             ret = WIFI_ERROR_NOT_SUPPORTED;
7540             goto exit;
7541         }
7542         if (strcmp(param, "-src_id") == 0) {
7543             msg.publish_subscribe_id = atoi(val_p);
7544             src_id = msg.publish_subscribe_id;
7545         } else if (strcmp(param, "-dest_id") == 0) {
7546             msg.requestor_instance_id = atoi(val_p);
7547             dest_id = msg.requestor_instance_id;
7548         } else if (strcmp(param, "-peer_addr") == 0) {
7549             if (!ether_atoe(val_p, msg.addr)) {
7550                 printMsg("bad peer mac addr !!\n");
7551                 ret = WIFI_ERROR_INVALID_ARGS;
7552                 goto exit;
7553             }
7554             mac_addr = msg.addr;
7555         } else if (strcmp(param, "-info") == 0) {
7556             if (strlen((const char*)val_p) > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
7557                 printMsg("Invalid  service specific info\n");
7558                 ret = WIFI_ERROR_INVALID_ARGS;
7559                 goto exit;
7560             } else {
7561                 msg.service_specific_info_len =
7562                 strlen((const char*)val_p);
7563                 if (!set_interface_params((char*)msg.service_specific_info,
7564                     val_p, msg.service_specific_info_len)) {
7565                     printMsg("Set service specific info successfull\n");
7566                 }
7567             }
7568         } else if (strncmp(param, "-recv_flag", strlen("-recv_flag")) == 0) {
7569             msg.recv_indication_cfg = strtoul(val_p, &endptr, 0);
7570         } else if (strcmp(param, "-sdea_info") == 0) {
7571             if (strlen((const char*)val_p) > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
7572                 printMsg("Invalid SDEA service specific info\n");
7573                 ret = WIFI_ERROR_INVALID_ARGS;
7574                 goto exit;
7575             } else {
7576                 msg.sdea_service_specific_info_len =
7577                 strlen((const char*)val_p);
7578                 if (!set_interface_params((char*)msg.sdea_service_specific_info,
7579                     val_p, msg.sdea_service_specific_info_len)) {
7580                     printMsg("Set SDEA service specific info successfull\n");
7581                 }
7582             }
7583         } else {
7584             printMsg("%s:Unsupported Parameter for nan transmit followup\n", __FUNCTION__);
7585             goto exit;
7586         }
7587     }
7588 
7589     if (!src_id) {
7590         printMsg("Source Instance Id is mandatory !!\n");
7591         goto exit;
7592     }
7593     if (!dest_id) {
7594         printMsg("Destination Instance Id is mandatory !!\n");
7595         goto exit;
7596     }
7597     if (!mac_addr) {
7598         printMsg("Peer MAC Address is mandatory !!\n");
7599         goto exit;
7600     }
7601     nanCmdId = getNewCmdId();
7602     ret = nan_init_handlers();
7603     if (ret != WIFI_SUCCESS) {
7604         printMsg("Failed to initialize handlers %d\n", ret);
7605         goto exit;
7606     }
7607     ret = nan_transmit_followup_request(nanCmdId, wlan0Handle, &msg);
7608 exit:
7609     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
7610     return;
7611 }
7612 
getNanCapabilities(void)7613 void getNanCapabilities(void) {
7614     nanCmdId = getNewCmdId();
7615     wifi_error ret = nan_init_handlers();
7616     if (ret != WIFI_SUCCESS) {
7617         printMsg("Failed to initialize handlers %d\n", ret);
7618         return;
7619     }
7620     nan_get_capabilities(nanCmdId, wlan0Handle);
7621 }
7622 
nanDataPathIfaceCreate(char * argv[])7623 void nanDataPathIfaceCreate(char *argv[]) {
7624     wifi_error ret = WIFI_SUCCESS;
7625     char *param = NULL, *val_p = NULL;
7626     /* skip utility */
7627     argv++;
7628     /* skip command */
7629     argv++;
7630     /* skip command */
7631     argv++;
7632     /* Interface name */
7633     char ndp_iface[IFNAMSIZ+1];
7634 
7635     while ((param = *argv++) != NULL) {
7636         val_p = *argv++;
7637         if (!val_p || *val_p == '-') {
7638             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
7639             ret = WIFI_ERROR_NOT_SUPPORTED;
7640             goto exit;
7641         }
7642         if (strcmp(param, "-iface") == 0) {
7643             if (!set_interface_params(ndp_iface, val_p, (IFNAMSIZ - 1))) {
7644                 printMsg("set interface name successfull\n");
7645             } else {
7646                 printMsg("Invalid  Iface name\n");
7647                 ret = WIFI_ERROR_INVALID_ARGS;
7648                 goto exit;
7649             }
7650         } else {
7651             printMsg("Unsupported Parameter for ndp iface create\n");
7652             goto exit;
7653         }
7654     }
7655 
7656     nanCmdId = getNewCmdId();
7657     ret = nan_init_handlers();
7658     if (ret != WIFI_SUCCESS) {
7659         printMsg("Failed to initialize handlers %d\n", ret);
7660         goto exit;
7661     }
7662     ret = nan_data_interface_create(nanCmdId, wlan0Handle, ndp_iface);
7663 exit:
7664     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
7665     return;
7666 }
7667 
nanDataPathIfaceDelete(char * argv[])7668 void nanDataPathIfaceDelete(char *argv[]) {
7669     wifi_error ret = WIFI_SUCCESS;
7670     char *param = NULL, *val_p = NULL;
7671     /* skip utility */
7672     argv++;
7673     /* skip command */
7674     argv++;
7675     /* skip command */
7676     argv++;
7677     /* Interface name */
7678     char ndp_iface[IFNAMSIZ+1];
7679 
7680     while ((param = *argv++) != NULL) {
7681         val_p = *argv++;
7682         if (!val_p || *val_p == '-') {
7683             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
7684             ret = WIFI_ERROR_NOT_SUPPORTED;
7685             goto exit;
7686         }
7687         if (strcmp(param, "-iface") == 0) {
7688             if (!set_interface_params(ndp_iface, val_p, (IFNAMSIZ - 1))) {
7689                 printMsg("clear interface name successfull\n");
7690             } else {
7691                 printMsg("Invalid  Iface name\n");
7692                 ret = WIFI_ERROR_INVALID_ARGS;
7693                 goto exit;
7694             }
7695         } else {
7696             printMsg("Unsupported Parameter for ndp iface delete\n");
7697             goto exit;
7698         }
7699     }
7700 
7701     nanCmdId = getNewCmdId();
7702     ret = nan_init_handlers();
7703     if (ret != WIFI_SUCCESS) {
7704         printMsg("Failed to initialize handlers %d\n", ret);
7705         goto exit;
7706     }
7707     ret = nan_data_interface_delete(nanCmdId, wlan0Handle, ndp_iface);
7708 exit:
7709     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
7710     return;
7711 }
7712 
7713 
nanDataInitRequest(int argc,char * argv[])7714 void nanDataInitRequest(int argc, char *argv[]) {
7715     NanDataPathInitiatorRequest msg;
7716     wifi_error ret = WIFI_SUCCESS;
7717     char *param = NULL, *val_p = NULL;
7718     u32 val = 0;
7719     /* skip utility */
7720     argv++;
7721     /* skip command */
7722     argv++;
7723     /* skip command */
7724     argv++;
7725 
7726     memset(&msg, 0, sizeof(msg));
7727     msg.ndp_cfg.security_cfg = NAN_DP_CONFIG_NO_SECURITY;
7728     msg.ndp_cfg.qos_cfg = NAN_DP_CONFIG_NO_QOS;
7729 
7730     while ((param = *argv++) != NULL) {
7731         val_p = *argv++;
7732         if (!val_p || *val_p == '-') {
7733             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
7734             ret = WIFI_ERROR_NOT_SUPPORTED;
7735             goto exit;
7736         }
7737         if (strcmp(param, "-pub_id") == 0) {
7738             msg.requestor_instance_id = atoi(val_p);
7739         } else if (strcmp(param, "-chan_req_type") == 0) {
7740             val = atoi(val_p);
7741             switch(val) {
7742                 case NAN_DP_CHANNEL_NOT_REQUESTED:
7743                     msg.channel_request_type = NAN_DP_CHANNEL_NOT_REQUESTED ;
7744                     break;
7745                 case NAN_DP_REQUEST_CHANNEL_SETUP:
7746                     msg.channel_request_type = NAN_DP_REQUEST_CHANNEL_SETUP;
7747                     break;
7748                 case NAN_DP_FORCE_CHANNEL_SETUP:
7749                     msg.channel_request_type = NAN_DP_FORCE_CHANNEL_SETUP;
7750                     break;
7751                 default:
7752                     msg.channel_request_type = NAN_DP_CHANNEL_NOT_REQUESTED;
7753                     break;
7754             }
7755         } else if (strcmp(param, "-chan") == 0) {
7756             msg.channel = atoi(val_p);
7757         } else if (strcmp(param, "-disc_mac") == 0) {
7758             if (!ether_atoe(val_p, msg.peer_disc_mac_addr)) {
7759                 printMsg("bad Discovery Mac address !!\n");
7760                 ret = WIFI_ERROR_INVALID_ARGS;
7761                 goto exit;
7762             }
7763         } else if (strcmp(param, "-iface") == 0) {
7764             if (!set_interface_params(msg.ndp_iface, val_p, (IFNAMSIZ - 1))) {
7765                 printMsg("Set Iface name successfull\n");
7766             } else {
7767                 printMsg("Invalid  Iface name\n");
7768                 ret = WIFI_ERROR_INVALID_ARGS;
7769                 goto exit;
7770             }
7771         } else if (strcmp(param, "-sec") == 0) {
7772             val = atoi(val_p);
7773             switch(val) {
7774                 case NAN_DP_CONFIG_SECURITY:
7775                     msg.ndp_cfg.security_cfg = NAN_DP_CONFIG_SECURITY;
7776                     break;
7777                 default:
7778                     msg.ndp_cfg.security_cfg = NAN_DP_CONFIG_NO_SECURITY;
7779                     break;
7780             }
7781         } else if (strcmp(param, "-qos") == 0) {
7782             val = atoi(val_p);
7783             switch(val) {
7784                 case NAN_DP_CONFIG_QOS:
7785                     msg.ndp_cfg.qos_cfg = NAN_DP_CONFIG_QOS;
7786                     break;
7787                 default:
7788                     msg.ndp_cfg.qos_cfg = NAN_DP_CONFIG_NO_QOS;
7789                     break;
7790             }
7791         } else if (strcmp(param, "-info") == 0) {
7792             if (strlen((const char*)val_p) > NAN_DP_MAX_APP_INFO_LEN) {
7793                 printMsg("Invalid app info\n");
7794                 ret = WIFI_ERROR_INVALID_ARGS;
7795                 goto exit;
7796             } else {
7797                 msg.app_info.ndp_app_info_len =
7798                 strlen((const char*)val_p);
7799                 if (!set_interface_params((char*)msg.app_info.ndp_app_info,
7800                     val_p, msg.app_info.ndp_app_info_len)) {
7801                     printMsg("Set app info successfull\n");
7802                 }
7803             }
7804         } else if (strcmp(param, "-csid") == 0) {
7805             val = atoi(val_p);
7806             switch(val) {
7807                 case NAN_CIPHER_SUITE_SHARED_KEY_NONE:
7808                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_NONE;
7809                     break;
7810                 case NAN_CIPHER_SUITE_SHARED_KEY_128_MASK:
7811                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_128_MASK;
7812                     break;
7813                 case NAN_CIPHER_SUITE_SHARED_KEY_256_MASK:
7814                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_256_MASK;
7815                     break;
7816 #ifdef NAN_3_1_SUPPORT
7817                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK:
7818                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK;
7819                     break;
7820                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK:
7821                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK;
7822                     break;
7823 #endif /* NAN_3_1_SUPPORT */
7824                 default:
7825                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_NONE;
7826                     break;
7827             }
7828         } else if (strcmp(param, "-key_type") == 0) {
7829             val = atoi(val_p);
7830             switch(val) {
7831                 case NAN_SECURITY_KEY_INPUT_PMK:
7832                     msg.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
7833                     break;
7834                 case NAN_SECURITY_KEY_INPUT_PASSPHRASE:
7835                     msg.key_info.key_type = NAN_SECURITY_KEY_INPUT_PASSPHRASE;
7836                     break;
7837                 default:
7838                     printMsg("Invalid security key type\n");
7839                     ret = WIFI_ERROR_INVALID_ARGS;
7840                     goto exit;
7841             }
7842         } else if (strcmp(param, "-pmk") == 0) {
7843             if (strlen((const char*)val_p) > NAN_PMK_INFO_LEN) {
7844                 printMsg("Invalid PMK\n");
7845                 ret = WIFI_ERROR_INVALID_ARGS;
7846                 goto exit;
7847             } else {
7848                 msg.key_info.body.pmk_info.pmk_len=
7849                 strlen((const char*)val_p);
7850                 if (!set_interface_params((char*)msg.key_info.body.pmk_info.pmk,
7851                 val_p, msg.key_info.body.pmk_info.pmk_len)) {
7852                 printMsg("Set PMK successfull\n");
7853                 }
7854             }
7855         } else if (strcmp(param, "-passphrase") == 0) {
7856             if (strlen((const char*)val_p) < NAN_SECURITY_MIN_PASSPHRASE_LEN ||
7857             strlen((const char*)val_p) > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
7858                 printMsg("passphrase must be between %d and %d characters long\n",
7859                 NAN_SECURITY_MIN_PASSPHRASE_LEN,
7860                 NAN_SECURITY_MAX_PASSPHRASE_LEN);
7861                 ret = WIFI_ERROR_INVALID_ARGS;
7862                 goto exit;
7863             } else {
7864                 msg.key_info.body.passphrase_info.passphrase_len =
7865                 (strlen((const char*)val_p));
7866                 if (!set_interface_params((char*)msg.key_info.body.passphrase_info.passphrase,
7867                     val_p, msg.key_info.body.passphrase_info.passphrase_len)) {
7868                     printMsg("Set passphrase successfull, len = %d\n", msg.key_info.body.passphrase_info.passphrase_len);
7869                 } else {
7870                     printMsg("Invalid passphrase\n");
7871                     ret = WIFI_ERROR_INVALID_ARGS;
7872                     goto exit;
7873                 }
7874             }
7875 #ifdef NAN_3_1_SUPPORT
7876         } else if (strcmp(param, "-scid") == 0) {
7877             if (strlen((const char*)val_p) > NAN_MAX_SCID_BUF_LEN) {
7878                 printMsg("Invalid SCID\n");
7879                 ret = WIFI_ERROR_INVALID_ARGS;
7880                 goto exit;
7881             } else {
7882                 msg.scid_len=
7883                 strlen((const char*)val_p);
7884                 if (!set_interface_params((char*)msg.scid,
7885                     val_p, msg.scid_len)) {
7886                     printMsg("Set SCID successfull\n");
7887                 }
7888             }
7889 #endif /* NAN_3_1_SUPPORT */
7890         } else if (strcmp(param, "-svc") == 0) {
7891             if (strlen((const char *)val_p) > NAN_MAX_SERVICE_NAME_LEN) {
7892                 printMsg("Invalid service name\n");
7893                 ret = WIFI_ERROR_INVALID_ARGS;
7894                 goto exit;
7895             } else {
7896                 msg.service_name_len =
7897                 strlen((const char *)val_p);
7898                 if (!set_interface_params((char*)msg.service_name,
7899                     val_p, msg.service_name_len)) {
7900                     printMsg("Set service name successfull\n");
7901                 }
7902             }
7903         } else {
7904             printMsg("%s:Unsupported Parameter for Nan Data Path Request\n", __FUNCTION__);
7905             goto exit;
7906         }
7907     }
7908 
7909     nanCmdId = getNewCmdId();
7910     ret = nan_init_handlers();
7911     if (ret != WIFI_SUCCESS) {
7912         printMsg("Failed to initialize handlers %d\n", ret);
7913         goto exit;
7914     }
7915     ret = nan_data_request_initiator(nanCmdId, wlan0Handle, &msg);
7916 exit:
7917     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
7918     return;
7919 }
7920 
nanDataIndResponse(int argc,char * argv[])7921 void nanDataIndResponse(int argc, char *argv[]) {
7922     NanDataPathIndicationResponse msg;
7923     wifi_error ret = WIFI_SUCCESS;
7924     char *param = NULL, *val_p = NULL;
7925     u32 val = 0;
7926     /* skip utility */
7927     argv++;
7928     /* skip command */
7929     argv++;
7930     /* skip command */
7931     argv++;
7932 
7933     memset(&msg, 0, sizeof(msg));
7934     msg.ndp_cfg.security_cfg = NAN_DP_CONFIG_NO_SECURITY;
7935     msg.ndp_cfg.qos_cfg = NAN_DP_CONFIG_NO_QOS;
7936     while ((param = *argv++) != NULL) {
7937         val_p = *argv++;
7938         if (!val_p || *val_p == '-') {
7939             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
7940             ret = WIFI_ERROR_NOT_SUPPORTED;
7941             goto exit;
7942         }
7943         if (strcmp(param, "-ndp_id") == 0) {
7944             msg.ndp_instance_id = atoi(val_p);
7945         } else if (strcmp(param, "-iface") == 0) {
7946             if (!set_interface_params(msg.ndp_iface, val_p, (IFNAMSIZ - 1))) {
7947                 printMsg("Set Iface name successfull\n");
7948             } else {
7949                 printMsg("Invalid  Iface name\n");
7950                 ret = WIFI_ERROR_INVALID_ARGS;
7951                 goto exit;
7952             }
7953         } else if (strcmp(param, "-sec") == 0) {
7954             val = atoi(val_p);
7955             switch(val) {
7956                 case NAN_DP_CONFIG_SECURITY:
7957                     msg.ndp_cfg.security_cfg = NAN_DP_CONFIG_SECURITY;
7958                     break;
7959                 default:
7960                     msg.ndp_cfg.security_cfg = NAN_DP_CONFIG_NO_SECURITY;
7961                     break;
7962             }
7963         } else if (strcmp(param, "-qos") == 0) {
7964             val = atoi(val_p);
7965             switch(val) {
7966                 case NAN_DP_CONFIG_QOS:
7967                     msg.ndp_cfg.qos_cfg = NAN_DP_CONFIG_QOS;
7968                     break;
7969                 default:
7970                     msg.ndp_cfg.qos_cfg = NAN_DP_CONFIG_NO_QOS;
7971                     break;
7972             }
7973         } else if (strcmp(param, "-info") == 0) {
7974             if ((u16)strlen((const char*)val_p) > NAN_DP_MAX_APP_INFO_LEN) {
7975                 printMsg("Invalid app info\n");
7976                 ret = WIFI_ERROR_INVALID_ARGS;
7977                 goto exit;
7978             } else {
7979                 msg.app_info.ndp_app_info_len =
7980                     (u16)strlen((const char*)val_p);
7981                 if (!set_interface_params((char*)msg.app_info.ndp_app_info,
7982                     val_p, msg.app_info.ndp_app_info_len)) {
7983                     printMsg("Set app info successfull\n");
7984                 }
7985             }
7986         } else if (strcmp(param, "-resp_code") == 0) {
7987             val = atoi(val_p);
7988             switch(val) {
7989                 case NAN_DP_REQUEST_REJECT:
7990                     msg.rsp_code = NAN_DP_REQUEST_REJECT;
7991                     break;
7992                 case NAN_DP_REQUEST_ACCEPT:
7993                     msg.rsp_code = NAN_DP_REQUEST_ACCEPT;
7994                     break;
7995                 default:
7996                     printMsg("Invalid response code\n");
7997                     ret = WIFI_ERROR_INVALID_ARGS;
7998                     goto exit;
7999             }
8000         } else if (strcmp(param, "-csid") == 0) {
8001             val = atoi(val_p);
8002             switch(val) {
8003                 case NAN_CIPHER_SUITE_SHARED_KEY_NONE:
8004                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_NONE;
8005                     break;
8006                 case NAN_CIPHER_SUITE_SHARED_KEY_128_MASK:
8007                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_128_MASK;
8008                     break;
8009                 case NAN_CIPHER_SUITE_SHARED_KEY_256_MASK:
8010                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_256_MASK;
8011                     break;
8012 #ifdef NAN_3_1_SUPPORT
8013                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK:
8014                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK;
8015                     break;
8016                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK:
8017                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK;
8018                     break;
8019 #endif /* NAN_3_1_SUPPORT */
8020                 default:
8021                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_NONE;
8022                     break;
8023             }
8024         } else if (strcmp(param, "-key_type") == 0) {
8025             val = atoi(val_p);
8026             switch(val) {
8027                 case NAN_SECURITY_KEY_INPUT_PMK:
8028                     msg.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
8029                     break;
8030                 case NAN_SECURITY_KEY_INPUT_PASSPHRASE:
8031                     msg.key_info.key_type = NAN_SECURITY_KEY_INPUT_PASSPHRASE;
8032                     break;
8033                 default:
8034                     printMsg("Invalid security key type\n");
8035                     ret = WIFI_ERROR_INVALID_ARGS;
8036                     goto exit;
8037             }
8038         } else if (strcmp(param, "-pmk") == 0) {
8039             if (strlen((const char*)val_p) > NAN_PMK_INFO_LEN) {
8040                 printMsg("Invalid PMK\n");
8041                 ret = WIFI_ERROR_INVALID_ARGS;
8042                 goto exit;
8043             } else {
8044                 msg.key_info.body.pmk_info.pmk_len =
8045                     strlen((const char*)val_p);
8046                 if (!set_interface_params((char*)msg.key_info.body.pmk_info.pmk,
8047                     val_p, msg.key_info.body.pmk_info.pmk_len)) {
8048                     printMsg("Set PMK successfull\n");
8049                 }
8050             }
8051         } else if (strcmp(param, "-passphrase") == 0) {
8052             if (strlen((const char*)val_p) < NAN_SECURITY_MIN_PASSPHRASE_LEN ||
8053                 strlen((const char*)val_p) > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
8054                 printMsg("passphrase must be between %d and %d characters long\n",
8055                     NAN_SECURITY_MIN_PASSPHRASE_LEN,
8056                     NAN_SECURITY_MAX_PASSPHRASE_LEN);
8057                 ret = WIFI_ERROR_INVALID_ARGS;
8058                 goto exit;
8059             } else {
8060                 msg.key_info.body.passphrase_info.passphrase_len =
8061                     (strlen((const char*)val_p));
8062                 if (!set_interface_params((char*)msg.key_info.body.passphrase_info.passphrase,
8063                     val_p, msg.key_info.body.passphrase_info.passphrase_len)) {
8064                     printMsg("Set passphrase successfull, len = %d\n", msg.key_info.body.passphrase_info.passphrase_len);
8065                 } else {
8066                     printMsg("Invalid passphrase\n");
8067                     ret = WIFI_ERROR_INVALID_ARGS;
8068                     goto exit;
8069                 }
8070             }
8071 #ifdef NAN_3_1_SUPPORT
8072         } else if (strcmp(param, "-scid") == 0) {
8073             if (strlen((const char*)val_p) > NAN_MAX_SCID_BUF_LEN) {
8074                 printMsg("Invalid SCID\n");
8075                 ret = WIFI_ERROR_INVALID_ARGS;
8076                 goto exit;
8077             } else {
8078                 msg.scid_len= strlen((const char*)val_p);
8079                 if (!set_interface_params((char*)msg.scid, val_p, msg.scid_len)) {
8080                     printMsg("Set SCID successfull\n");
8081                 }
8082             }
8083 #endif /* NAN_3_1_SUPPORT */
8084         } else if (strcmp(param, "-svc") == 0) {
8085             if (strlen((const char *)val_p) > NAN_MAX_SERVICE_NAME_LEN) {
8086                 printMsg("Invalid service name\n");
8087                 ret = WIFI_ERROR_INVALID_ARGS;
8088                 goto exit;
8089             } else {
8090                 msg.service_name_len =
8091                 strlen((const char *)val_p);
8092                 if (!set_interface_params((char*)msg.service_name,
8093                     val_p, msg.service_name_len)) {
8094                     printMsg("Set service name successfull\n");
8095                 }
8096             }
8097         } else {
8098             printMsg("%s:Unsupported Parameter for Nan Data Path Request\n", __FUNCTION__);
8099             goto exit;
8100         }
8101     }
8102     nanCmdId = getNewCmdId();
8103     ret = nan_init_handlers();
8104     if (ret != WIFI_SUCCESS) {
8105         printMsg("Failed to initialize handlers %d\n", ret);
8106         goto exit;
8107     }
8108     ret = nan_data_indication_response(nanCmdId, wlan0Handle, &msg);
8109 exit:
8110     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
8111     return;
8112 }
8113 
nanDataPathEnd(int argc,char * argv[])8114 void nanDataPathEnd(int argc, char *argv[]) {
8115     NanDataPathEndRequest *msg;
8116     wifi_error ret = WIFI_SUCCESS;
8117     char *param = NULL, *val_p = NULL, *endptr = NULL;
8118     u8 count = 0, i = 0;
8119     NanDataPathId ndp_id = 0;
8120     /* skip utility */
8121     argv++;
8122     /* skip command */
8123     argv++;
8124     /* skip command */
8125     argv++;
8126 
8127     msg = (NanDataPathEndRequest *)malloc(NAN_MAX_NDP_COUNT_SIZE + sizeof(u8));
8128     if (!msg) {
8129         printMsg("Failed to alloc for end request\n");
8130         ret = WIFI_ERROR_OUT_OF_MEMORY;
8131         goto exit;
8132     }
8133     memset(msg, 0, NAN_MAX_NDP_COUNT_SIZE + sizeof(u8));
8134 
8135     while ((param = *argv++) != NULL) {
8136         val_p = *argv++;
8137         if (!val_p || *val_p == '-') {
8138             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
8139             ret = WIFI_ERROR_NOT_SUPPORTED;
8140             goto exit;
8141         }
8142         if (strcmp(param, "-inst_count") == 0) {
8143             count = atoi(val_p);
8144             if (!count || count > 1) {
8145                 printMsg("%s:Invalid inst_count value.\n", __FUNCTION__);
8146                 ret = WIFI_ERROR_INVALID_ARGS;
8147                 goto exit;
8148             }
8149             msg->num_ndp_instances = count;
8150         } else if (strcmp(param, "-inst_id") == 0) {
8151             if (!msg->num_ndp_instances || (i > msg->num_ndp_instances)) {
8152                 printMsg("num of ndp instances need to be minimum 1\n");
8153                 goto exit;
8154             }
8155             ndp_id = strtoul(val_p, &endptr, 0);
8156             msg->ndp_instance_id[i++] = ndp_id;
8157         } else {
8158             printMsg("%s:Unsupported Parameter for Nan Data Path End Request\n", __FUNCTION__);
8159             goto exit;
8160         }
8161     }
8162 
8163     nanCmdId = getNewCmdId();
8164     ret = nan_init_handlers();
8165     if (ret != WIFI_SUCCESS) {
8166         printMsg("Failed to initialize handlers %d\n", ret);
8167         goto exit;
8168     }
8169     ret = nan_data_end(nanCmdId, wlan0Handle, msg);
8170 exit:
8171     if (msg) {
8172         free(msg);
8173     }
8174     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
8175     return;
8176 }
8177 
VirtualIfaceAdd(char * argv[])8178 void VirtualIfaceAdd(char *argv[]) {
8179     wifi_error ret = WIFI_SUCCESS;
8180     char *param = NULL, *val_p = NULL;
8181     /* skip utility */
8182     argv++;
8183     /* skip command */
8184     argv++;
8185     /* Interface name */
8186     char iface_name[IFNAMSIZ+1];
8187     wifi_interface_type iface_type;
8188 
8189     while ((param = *argv++) != NULL) {
8190     val_p = *argv++;
8191     if (!val_p || *val_p == '-') {
8192         printMsg("%s: Need value following %s\n", __FUNCTION__, param);
8193         ret = WIFI_ERROR_NOT_SUPPORTED;
8194         goto exit;
8195     }
8196     if (strcmp(param, "-name") == 0) {
8197         if (!set_interface_params(iface_name, val_p, (IFNAMSIZ - 1))) {
8198                 printMsg("set interface name successfull\n");
8199             } else {
8200                 printMsg("Invalid Iface name\n");
8201                 ret = WIFI_ERROR_INVALID_ARGS;
8202                 goto exit;
8203             }
8204         } else if (strcmp(param, "-type") == 0) {
8205             iface_type = (wifi_interface_type)atoi(val_p);
8206         } else {
8207             printMsg("Unsupported Parameter for virtual iface delete\n");
8208             goto exit;
8209         }
8210     }
8211 
8212     ret = hal_fn.wifi_virtual_interface_create(halHandle, iface_name, iface_type);
8213     if (ret == WIFI_ERROR_NONE) {
8214         printMsg("Successful to add virtual iface\n");
8215     } else {
8216         printMsg("Failed to add virtual iface, result = %d\n", ret);
8217     }
8218 
8219 exit:
8220     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
8221     return;
8222 }
8223 
VirtualIfaceDelete(char * argv[])8224 void VirtualIfaceDelete(char *argv[]) {
8225     wifi_error ret = WIFI_SUCCESS;
8226     char *param = NULL, *val_p = NULL;
8227     /* skip utility */
8228     argv++;
8229     /* skip command */
8230     argv++;
8231     /* Interface name */
8232     char iface_name[IFNAMSIZ+1];
8233 
8234     while ((param = *argv++) != NULL) {
8235         val_p = *argv++;
8236         if (!val_p || *val_p == '-') {
8237             printMsg("%s: Need value following %s\n", __FUNCTION__, param);
8238             ret = WIFI_ERROR_NOT_SUPPORTED;
8239             goto exit;
8240         }
8241         if (strcmp(param, "-name") == 0) {
8242             if (!set_interface_params(iface_name, val_p, (IFNAMSIZ - 1))) {
8243                 printMsg("set interface name successfull\n");
8244             } else {
8245                 printMsg("Invalid  face name\n");
8246                 ret = WIFI_ERROR_INVALID_ARGS;
8247                 goto exit;
8248             }
8249         } else {
8250             printMsg("Unsupported Parameter for virtual iface delete\n");
8251             goto exit;
8252         }
8253     }
8254 
8255     ret = hal_fn.wifi_virtual_interface_delete(halHandle, iface_name);
8256     if (ret == WIFI_ERROR_NONE) {
8257         printMsg("Successful to delete virtual iface\n");
8258     } else {
8259         printMsg("Failed to delete virtual iface, result = %d\n", ret);
8260     }
8261 exit:
8262     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
8263     return;
8264 }
8265 
8266 static void
MultiStaSetPrimaryConnection(char * argv[])8267 MultiStaSetPrimaryConnection(char *argv[]) {
8268     wifi_error ret = WIFI_SUCCESS;
8269     char *param = NULL;
8270     /* skip utility */
8271     argv++;
8272     /* skip command */
8273     argv++;
8274     /* Interface name */
8275     char iface_name[IFNAMSIZ+1];
8276     wifi_interface_handle ifHandle = NULL;
8277 
8278     while ((param = *argv++) != NULL) {
8279         if (!set_interface_params(iface_name, param, (IFNAMSIZ - 1))) {
8280             printMsg("set interface name successfull\n");
8281         } else {
8282             printMsg("Invalid  iface name\n");
8283             ret = WIFI_ERROR_INVALID_ARGS;
8284             goto exit;
8285         }
8286     }
8287 
8288     ifHandle = wifi_get_iface_handle(halHandle, iface_name);
8289     if (ifHandle == NULL) {
8290         printMsg("Invalid  iface handle for the requested interface\n");
8291         ret = WIFI_ERROR_INVALID_ARGS;
8292         goto exit;
8293     } else {
8294         ret = hal_fn.wifi_multi_sta_set_primary_connection(halHandle, ifHandle);
8295         if (ret == WIFI_ERROR_NONE) {
8296             printMsg("Successfully set as primary connection\n");
8297         }
8298     }
8299 exit:
8300     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
8301     return;
8302 }
8303 
8304 static void
MultiStaSetUsecase(char * argv[])8305 MultiStaSetUsecase(char *argv[]) {
8306     wifi_error ret = WIFI_SUCCESS;
8307     uint use_case;
8308     wifi_multi_sta_use_case mMultiStaUsecase;
8309 
8310     /* skip utility */
8311     argv++;
8312     /* skip command */
8313     argv++;
8314 
8315     use_case = (uint)atoi(*argv);
8316     if (use_case >= WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY &&
8317         use_case <= WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED) {
8318         mMultiStaUsecase = (wifi_multi_sta_use_case)use_case;
8319     } else {
8320         printMsg("Invalid  multi_sta usecase\n");
8321         ret = WIFI_ERROR_INVALID_ARGS;
8322         goto exit;
8323     }
8324 
8325     ret = hal_fn.wifi_multi_sta_set_use_case(halHandle, mMultiStaUsecase);
8326     if (ret == WIFI_ERROR_NONE) {
8327         printMsg("Successful to set multista usecase\n");
8328     } else {
8329         printMsg("Failed to set multista usecase, result = %d\n", ret);
8330     }
8331 exit:
8332     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
8333     return;
8334 }
8335 
8336 static void
SetLatencyMode(char * argv[])8337 SetLatencyMode(char *argv[]) {
8338     wifi_error ret = WIFI_SUCCESS;
8339     char *param = NULL;
8340     /* skip utility */
8341     argv++;
8342     /* skip command */
8343     argv++;
8344     /* Interface name */
8345     char iface_name[IFNAMSIZ+1];
8346     wifi_interface_handle ifHandle = NULL;
8347 
8348     param = *argv++;
8349     if (param != NULL) {
8350         if (!set_interface_params(iface_name, param, (IFNAMSIZ - 1))) {
8351            printMsg("set interface name successfull %s\n", iface_name);
8352         } else {
8353             printMsg("Invalid  iface name\n");
8354             ret = WIFI_ERROR_INVALID_ARGS;
8355             goto exit;
8356         }
8357     }
8358 
8359     ifHandle = wifi_get_iface_handle(halHandle, iface_name);
8360     if (ifHandle == NULL) {
8361         printMsg("Invalid  iface handle for the requested interface\n");
8362         ret = WIFI_ERROR_INVALID_ARGS;
8363         goto exit;
8364     } else {
8365         /* Read the requested latency mode */
8366         wifi_latency_mode latency_mode = (wifi_latency_mode)(atoi)(*argv);
8367         ret = hal_fn.wifi_set_latency_mode(ifHandle, latency_mode);
8368         if (ret == WIFI_ERROR_NONE) {
8369             printMsg("Successfully set latency mode\n");
8370         }
8371     }
8372 exit:
8373     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
8374     return;
8375 
8376 }
8377 
8378 static void
SetVoipMode(char * argv[])8379 SetVoipMode(char *argv[]) {
8380     wifi_error ret = WIFI_SUCCESS;
8381     char *param = NULL;
8382     /* skip utility */
8383     argv++;
8384     /* skip command */
8385     argv++;
8386     /* Interface name */
8387     char iface_name[IFNAMSIZ+1];
8388     wifi_interface_handle ifHandle = NULL;
8389 
8390     param = *argv++;
8391     if (param != NULL) {
8392         if (!set_interface_params(iface_name, param, (IFNAMSIZ - 1))) {
8393             printMsg("set interface name successfull\n");
8394         } else {
8395             printMsg("Invalid  iface name\n");
8396             ret = WIFI_ERROR_INVALID_ARGS;
8397             goto exit;
8398         }
8399     }
8400 
8401     ifHandle = wifi_get_iface_handle(halHandle, iface_name);
8402     if (ifHandle == NULL) {
8403         printMsg("Invalid  iface handle for the requested interface\n");
8404         ret = WIFI_ERROR_INVALID_ARGS;
8405         goto exit;
8406     } else {
8407         /* Read the requested voip mode */
8408         wifi_voip_mode mode = (wifi_voip_mode)(atoi)(*argv);
8409         ret = hal_fn.wifi_set_voip_mode(ifHandle, mode);
8410         if (ret == WIFI_ERROR_NONE) {
8411             printMsg("Successfully set voip mode\n");
8412         }
8413     }
8414 exit:
8415     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
8416     return;
8417 }
8418 
main(int argc,char * argv[])8419 int main(int argc, char *argv[]) {
8420     pthread_mutex_init(&printMutex, NULL);
8421 
8422     set_hautil_mode(true);
8423     if (init() != 0) {
8424         printMsg("could not initiate HAL");
8425         return WIFI_ERROR_UNKNOWN;
8426     } else {
8427         ALOGD("successfully initialized HAL; wlan0 = %p\n", wlan0Handle);
8428     }
8429 
8430     sem_init(&event_thread_mutex,0,0);
8431 
8432     pthread_cond_init(&eventCacheCondition, NULL);
8433     pthread_mutex_init(&eventCacheMutex, NULL);
8434 
8435     pthread_t tidEvent;
8436     pthread_create(&tidEvent, NULL, &eventThreadFunc, NULL);
8437     sem_wait(&event_thread_mutex);
8438 
8439     if (argc < 2) {
8440         printUsage();
8441         goto cleanup;
8442     } else if (argv[1][0] != '-') {
8443         printUsage();
8444         goto cleanup;
8445     } else if ((strcmp(argv[1], "-nan") == 0) && (argc < 3)) {
8446         printUsage();
8447         goto cleanup;
8448     }
8449     memset(mac_oui, 0, 3);
8450     if (strcmp(argv[1], "-nan") == 0) {
8451         if ((strcmp(argv[2], "-enable") == 0)) {
8452             enableNan(argv);
8453         } else if ((strcmp(argv[2], "-disable") == 0)) {
8454             disableNan();
8455         } else if ((strcmp(argv[2], "-config") == 0)) {
8456             configNan(argv);
8457         } else if ((strcmp(argv[2], "-publish") == 0)) {
8458             if (argc < 4) {
8459                 printMsg(" -nan [-publish] [-svc <svc_name>] [-info <svc info>\n"
8460                     "    [-pub_type <0/1/2>] [-pub_count <val>] [-rssi_thresh_flag <0/1>]\n"
8461                     "    [-tx_type <0/1>] [-ttl <val>] [-svc_awake_dw <val>]\n"
8462                     "    [-match_rx <0/ascii str>] [-match_tx <0/ascii str>]] [-match_ind <1/2>]\n"
8463                     "    [-csid <cipher suite type 0/1/2/4/8>] [-key_type <1 or 2>] [-pmk <PMK value>]\n"
8464                     "    [-passphrase <Passphrase value, len must not be less than 8 or greater than 63>]\n"
8465                     "    [-scid <scid value>] [-dp_type <0-Unicast, 1-multicast>]\n"
8466                     "    [-secure_dp <0-No security, 1-Security>] -ranging <0-disable, 1-enable>)\n"
8467                     "    [-ranging_intvl [intrvl in ms betw two ranging measurements] -ranging_ind \n"
8468                     "    [ BIT0 - Continuous Ranging event notification, BIT1 - Ingress distance is <=, BIT2 - Egress distance is >=.]\n"
8469                     "    [-ingress [Ingress distance in centimeters] \n"
8470                     "    [ -egress [Egress distance in centimeters] \n"
8471                     "    [-auto_dp_accept [0 - User response required to accept dp, 1 - User response not required to accept dp] \n"
8472                     "    [-recv_flag <0 to 15>]");
8473                 printMsg("\n *Set/Enable corresponding bits to disable any indications that follow a publish"
8474                     "\n *BIT0 - Disable publish termination indication."
8475                     "\n *BIT1 - Disable match expired indication."
8476                     "\n *BIT2 - Disable followUp indication received (OTA)");
8477                 goto cleanup;
8478             }
8479             publishNan(argc, argv);
8480         } else if ((strcmp(argv[2], "-subscribe") == 0)) {
8481             if (argc < 3) {
8482                 printMsg(" -nan [-subscribe] [-svc <svc_name>] [-info <svc info>\n"
8483                     "    [-sub_type <0/1>] [-sub_count <val>] [-pub_ssi <0/1>]\n"
8484                     "    [-ttl <val>] [-svc_awake_dw <val>] [-match_ind <1/2>]\n"
8485                     "    [-match_rx <0/ascii str>] [-match_tx <0/ascii str>]\n"
8486                     "    [-mac_list <addr>] [-srf_include <0/1>] [-rssi_thresh_flag <0/1>]]\n"
8487                     "    [-csid <cipher suite type 0/1/2/4/8>] [-key_type <1 or 2>]  [-pmk <PMK value>]\n"
8488                     "    [-passphrase <Passphrase value, len must not be less than 8 or greater than 63>]\n"
8489                     "    [-scid <scid value>] [-dp_type <0-Unicast, 1-multicast>]\n"
8490                     "    [-secure_dp <0-No security, 1-Security>] -ranging <0-disable, 1-enable>)\n"
8491                     "    [-ranging_intvl [intrvl in ms betw two ranging measurements] -ranging_ind \n"
8492                     "    [BIT0 - Continuous Ranging event notification, BIT1 - Ingress distance is <=, BIT2 - Egress distance is >=.]\n"
8493                     "    [-ingress [Ingress distance in centimeters] \n"
8494                     "    [ -egress [Egress distance in centimeters] \n"
8495                     "    [-recv_flag <0 to 7>]");
8496                 printMsg("\n *Set/Enable corresponding bits to disable any indications that follow a publish"
8497                     "\n *BIT0 - Disable publish termination indication."
8498                     "\n *BIT1 - Disable match expired indication."
8499                     "\n *BIT2 - Disable followUp indication received (OTA)");
8500                 goto cleanup;
8501             }
8502             subscribeNan(argc, argv);
8503         } else if ((strcmp(argv[2], "-cancel_pub") == 0)) {
8504             if(argc < 3) {
8505                 printMsg(" -nan [-cancel_pub] [<publish id>]\n");
8506                 goto cleanup;
8507             }
8508             cancelPublishNan(argv);
8509         } else if ((strcmp(argv[2], "-cancel_sub") == 0)) {
8510             if(argc < 3) {
8511                 printMsg(" -nan [-cancel_sub] [<sublish id>]\n");
8512                 goto cleanup;
8513             }
8514             cancelSubscribeNan(argv);
8515         } else if ((strcmp(argv[2], "-transmit") == 0)) {
8516             if(argc < 5) {
8517                 printMsg(" -nan [-transmit] [-src_id <instance id>] [-dest_id <instance id>]\n"
8518                     "    [-peer_addr <mac addr>] [-info <svc info>]\n");
8519                 printMsg("\n Mandatory fields are not present\n");
8520                 goto cleanup;
8521             }
8522             transmitNan(argc,argv);
8523         } else if ((strcmp(argv[2], "-get_capabilities") == 0)) {
8524             getNanCapabilities();
8525         } else if ((strcmp(argv[2], "-create") == 0)) {
8526             if(argc < 3) {
8527                 printMsg("\n Mandatory fields are not present\n");
8528                 printMsg(" -nan [-create] [-iface_name <iface name>]\n");
8529                 goto cleanup;
8530             }
8531             nanDataPathIfaceCreate(argv);
8532         } else if ((strcmp(argv[2], "-delete") == 0)) {
8533             if(argc < 3) {
8534                 printMsg("\n Mandatory fields are not present\n");
8535                 printMsg(" -nan [-delete] [-iface_name <iface name>]\n");
8536                 goto cleanup;
8537             }
8538             nanDataPathIfaceDelete(argv);
8539         } else if ((strcmp(argv[2], "-init") == 0)) {
8540             if(argc < 7) {
8541                 printMsg("\n Mandatory fields are not present\n");
8542                 printMsg(" -nan [-init] [-pub_id <pub id>] [-disc_mac <discovery mac addr>]\n"
8543                     "    [-chan <channel in mhz>] [-iface <iface>] [-sec <security>]\n"
8544                     "    [-qos <qos>] [-info <seq of values in the frame body>]\n"
8545                     "    [-csid <cipher suite type 0/1/2/4/8>]\n"
8546                     "    [-scid <scid value>] [-svc <svc_name>]\n");
8547                 goto cleanup;
8548             }
8549             nanDataInitRequest(argc, argv);
8550         } else if ((strcmp(argv[2], "-resp") == 0)) {
8551             if(argc < 3) {
8552                 printMsg("\n Mandatory fields are not present\n");
8553                 printMsg(" -nan [-resp] [-ndp_id <NDP id>] [-iface <NDP iface name>]\n"
8554                     "    [-resp_code <accept = 0, accept = 1>] [-qos <qos>]\n"
8555                     "    [-info <seq of values in the frame body>]\n"
8556                     "    [-csid <cipher suite type 0/1/2/4/8>]\n"
8557                     "    [-scid <scid value>] [-svc <svc_name>] \n");
8558                 goto cleanup;
8559             }
8560             nanDataIndResponse(argc, argv);
8561         } else if ((strcmp(argv[2], "-end") == 0)) {
8562             if(argc < 3) {
8563                 printMsg("\n Mandatory fields are not present\n");
8564                 printMsg(" -nan [-end] [-inst_count <count>] [-inst_id <NDP id>\n");
8565                 goto cleanup;
8566             }
8567             nanDataPathEnd(argc, argv);
8568         } else if ((strcmp(argv[2], "-event_chk") == 0)) {
8569             nanEventCheck();
8570         } else if ((strcmp(argv[2], "-ver") == 0)) {
8571             nanVersion();
8572         } else if ((strcmp(argv[2], "-exit") == 0)) {
8573             return WIFI_SUCCESS;
8574         } else {
8575             printMsg("\n Unknown command\n");
8576             printUsage();
8577             return WIFI_SUCCESS;
8578         }
8579     } else if (strcmp(argv[1], "-s") == 0) {
8580         readTestOptions(argc, argv);
8581         setPnoMacOui();
8582         testScan();
8583     } else if(strcmp(argv[1], "-swc") == 0){
8584         readTestOptions(argc, argv);
8585         setPnoMacOui();
8586         trackSignificantChange();
8587     } else if (strcmp(argv[1], "-ss") == 0) {
8588         // Stop scan so clear the OUI too
8589         setPnoMacOui();
8590         testStopScan();
8591     } else if ((strcmp(argv[1], "-h") == 0)  ||
8592             (strcmp(argv[1], "-hotlist_bssids") == 0)) {
8593         readTestOptions(argc, argv);
8594         setPnoMacOui();
8595         testHotlistAPs();
8596     } else if (strcmp(argv[1], "-stats") == 0) {
8597         getLinkStats();
8598     } else if (strcmp(argv[1], "-rtt") == 0) {
8599         readRTTOptions(argc, ++argv);
8600         testRTT();
8601     } else if (strcmp(argv[1], "-cancel_rtt") == 0) {
8602         cancelRTT();
8603     } else if (strcmp(argv[1], "-get_capa_rtt") == 0) {
8604         getRTTCapability();
8605     } else if ((strcmp(argv[1], "-get_ch_list") == 0)) {
8606         readTestOptions(argc, argv);
8607         getChannelList();
8608     } else if ((strcmp(argv[1], "-get_responder_info") == 0)) {
8609         getRttResponderInfo();
8610     } else if ((strcmp(argv[1], "-enable_resp") == 0)) {
8611         RttEnableResponder();
8612     } else if ((strcmp(argv[1], "-cancel_resp") == 0)) {
8613        cancelRttResponder();
8614     } else if ((strcmp(argv[1], "-get_feature_set") == 0)) {
8615         getFeatureSet();
8616     } else if ((strcmp(argv[1], "-get_feature_matrix") == 0)) {
8617         getFeatureSetMatrix();
8618     } else if ((strcmp(argv[1], "-get_wake_stats") == 0)) {
8619         getWakeStats();
8620     } else if ((strcmp(argv[1], "-scan_mac_oui") == 0)) {
8621         readTestOptions(argc, argv);
8622         setPnoMacOui();
8623         testScan();
8624     } else if (strcmp(argv[1], "-nodfs") == 0) {
8625         u32 nodfs = 0;
8626         if (argc > 2)
8627             nodfs = (u32)atoi(argv[2]);
8628         hal_fn.wifi_set_nodfs_flag(wlan0Handle, nodfs);
8629     } else if ((strcmp(argv[1], "-ePNO") == 0) || (strcmp(argv[1], "-ePNOCfg") == 0)) {
8630         memset(&epno_cfg, 0, sizeof(epno_cfg));
8631         epno_cfg.min5GHz_rssi =  -45;
8632         epno_cfg.min24GHz_rssi =  -50;
8633         epno_cfg.initial_score_max  =  110;
8634         epno_cfg.num_networks = -1;
8635         readTestOptions(argc, argv);
8636         epno_cfg.num_networks++;
8637         setBlacklist(false);
8638         testPNO(false, (strcmp(argv[1], "-ePNO") == 0));
8639         if (strcmp(argv[1], "-ePNOCfg") == 0) {
8640             printMsg("Cannot close, will cleanup cfg, ctrl+c to exit\n");
8641             while (1);
8642         }
8643     } else if (strcmp(argv[1], "-ePNOClear") == 0) {
8644         testPNO(true, false);
8645         setBlacklist(true);
8646     } else if (strcmp(argv[1], "-country") == 0) {
8647         char *country_code = nullptr;
8648         if (argc > 2) {
8649             country_code = argv[2];
8650         } else {
8651             printMsg("Country code not provided\n");
8652             goto cleanup;
8653         }
8654         hal_fn.wifi_set_country_code(wlan0Handle, country_code);
8655     } else if ((strcmp(argv[1], "-logger") == 0)) {
8656         readLoggerOptions(argc, ++argv);
8657         runLogger();
8658     } else if (strcmp(argv[1], "-help") == 0) {
8659         printUsage();
8660     } else if ((strcmp(argv[1], "-blacklist_bssids") == 0) ||
8661         (strcmp(argv[1], "-whitelist_ssids") == 0)) {
8662         readTestOptions(argc, argv);
8663         if (set_roaming_configuration) {
8664             setRoamingConfiguration();
8665             set_roaming_configuration = false;
8666         } else {
8667             setBlacklist(((num_blacklist_bssids == -1) ? true: false));
8668         }
8669     } else if ((strcmp(argv[1], "-get_roaming_capabilities") == 0)) {
8670         getRoamingCapabilities();
8671     } else if ((strcmp(argv[1], "-set_fw_roaming_state") == 0)) {
8672         fw_roaming_state_t roamState = (fw_roaming_state_t)(atoi)(argv[2]);
8673         setFWRoamingState(roamState);
8674     } else if (strcmp(argv[1], "-rssi_monitor") == 0) {
8675         readTestOptions(argc, argv);
8676         testRssiMonitor();
8677     } else if (strcmp(argv[1], "-mkeep_alive") == 0) {
8678         readKeepAliveOptions(argc, ++argv);
8679     } else if ((strcmp(argv[1], "-nd_offload") == 0) && (argc > 2)) {
8680         u8 enable = (u8)(atoi)(argv[2]);
8681         hal_fn.wifi_configure_nd_offload(wlan0Handle, enable);
8682     } else if ((strcmp(argv[1], "-apf") == 0)) {
8683         testApfOptions(argc, ++argv);
8684     } else if ((strcmp(argv[1], "-sar") == 0)) {
8685         testSarOptions(argc-1, ++argv);
8686     } else if ((strcmp(argv[1], "-latency") == 0)) {
8687         testLatencyModeOptions(argc-1, ++argv);
8688     } else if ((strcmp(argv[1], "-thermal") == 0)) {
8689         testThermalMitigationOptions(argc-1, ++argv);
8690     } else if ((strcmp(argv[1], "-dscp") == 0)) {
8691         testDscpOptions(argc, ++argv);
8692     } else if ((strcmp(argv[1], "-ch_avoid") == 0)) {
8693         testChannelAvoidanceOptions(argc, ++argv);
8694     } else if ((strcmp(argv[1], "-usable_ch") == 0)) {
8695         testUsableChannelOptions(argc, ++argv);
8696     } else if ((strcmp(argv[1], "-ifadd") == 0)) {
8697         if (argc < 3) {
8698             printMsg("\n Mandatory fields are not present\n");
8699             printMsg(" [-ifadd] [-name <virtual iface name should be wlanX, swlanX, awareX, p2pX>"
8700                 " -type 0/1/2/3]\n");
8701             printMsg(" 0 for STA, 1 for AP, 2 for P2P, 3 for NAN\n");
8702             goto cleanup;
8703         }
8704         VirtualIfaceAdd(argv);
8705     } else if ((strcmp(argv[1], "-ifdel") == 0)) {
8706         if(argc < 3) {
8707             printMsg("\n Mandatory fields are not present\n");
8708             printMsg("[-ifdel] [-name <virtual iface name>]\n");
8709             goto cleanup;
8710         }
8711         VirtualIfaceDelete(argv);
8712     } else if ((strcmp(argv[1], "-latency_mode") == 0) && (argc > 2)) {
8713         SetLatencyMode(argv);
8714     } else if ((strcmp(argv[1], "-multista_pri_connection") == 0)) {
8715         if(argc < 3) {
8716             printMsg("\n Mandatory fields are not present\n");
8717             printMsg("[-multista_pri_connection] [iface name>]\n");
8718             goto cleanup;
8719         }
8720         MultiStaSetPrimaryConnection(argv);
8721     } else if ((strcmp(argv[1], "-multista_usecase") == 0)) {
8722         if(argc < 3) {
8723             printMsg("\n Mandatory fields are not present\n");
8724             printMsg("[-multista_usecase] [multista usecase 0/1]\n");
8725             goto cleanup;
8726         }
8727         MultiStaSetUsecase(argv);
8728     } else if ((strcmp(argv[1], "-voip_mode") == 0) && (argc > 2)) {
8729         SetVoipMode(argv);
8730     } else if (strcmp(argv[1], "-twt") == 0) {
8731         if ((strcmp(argv[2], "-setup") == 0)) {
8732             setupTwtRequest(argv);
8733         } else if ((strcmp(argv[2], "-teardown") == 0)) {
8734             TeardownTwt(argv);
8735         } else if ((strcmp(argv[2], "-info_frame") == 0)) {
8736             InfoFrameTwt(argv);
8737         } else if ((strcmp(argv[2], "-get_stats") == 0)) {
8738             GetTwtStats(argv);
8739         } else if ((strcmp(argv[2], "-clear_stats") == 0)) {
8740             ClearTwtStats(argv);
8741         } else if ((strcmp(argv[2], "-event_chk") == 0)) {
8742             twtEventCheck();
8743         } else {
8744             printMsg("\n Unknown command\n");
8745             printTwtUsage();
8746             return WIFI_SUCCESS;
8747         }
8748     } else if (strcmp(argv[1], "-get_capa_twt") == 0) {
8749         getTWTCapability();
8750     } else if ((strcmp(argv[1], "-dtim_multiplier") == 0) && (argc > 2)) {
8751         int dtim_multiplier = (atoi)(argv[2]);
8752         hal_fn.wifi_set_dtim_config(wlan0Handle, dtim_multiplier);
8753     } else if (strcmp(argv[1], "-on_ssr") == 0) {
8754         hal_fn.wifi_trigger_subsystem_restart(halHandle);
8755     } else if ((strcmp(argv[1], "-getSupportedRadioMatrix") == 0)) {
8756         getSupportedRadioMatrix();
8757     } else if ((strcmp(argv[1], "-tx_pwr_cap") == 0)) {
8758         testTxPowerLimitOptions(argc, ++argv);
8759     } else if (strcmp(argv[1], "-chre_nan_rtt") == 0) {
8760         if ((strcmp(argv[2], "-enable") == 0)) {
8761             //enable CHRE NAN RTT
8762             enableChreNanRtt();
8763         } else if ((strcmp(argv[2], "-disable") == 0)) {
8764             //disable CHRE NAN RTT
8765             disableChreNanRtt();
8766         } else {
8767             printMsg("\n Unknown command\n");
8768             printChreNanRttUsage();
8769         }
8770     } else if (strcmp(argv[1], "-chre") == 0) {
8771         if ((strcmp(argv[2], "-register") == 0)) {
8772             //register CHRE callback
8773             registerChreCallback();
8774         } else {
8775             printMsg("\n Unknown command\n");
8776             printChreNanRttUsage();
8777         }
8778     } else if (strcmp(argv[1], "-get_cached_scan_results") == 0) {
8779         getWifiCachedScanResults();
8780     } else if (strcmp(argv[1], "-set_channel_mask") == 0) {
8781         u32 channel_mask = 0;
8782         if (argc > 2) {
8783             channel_mask = (u32)atoi(argv[2]);
8784         }
8785         hal_fn.wifi_enable_sta_channel_for_peer_network(halHandle, channel_mask);
8786     } else {
8787         printUsage();
8788     }
8789 
8790 cleanup:
8791     cleanup();
8792     return WIFI_SUCCESS;
8793 }
8794