1 /*
2  * Copyright 2022, Cypress Semiconductor Corporation (an Infineon company)
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 /**
19  * @file WHD utilities
20  *
21  * Utilities to help do specialized (not general purpose) WHD specific things
22  */
23 #include "whd_debug.h"
24 #include "whd_utils.h"
25 #include "whd_chip_constants.h"
26 #include "whd_endian.h"
27 #include "whd_int.h"
28 #include "whd_wlioctl.h"
29 
30 #define UNSIGNED_CHAR_TO_CHAR(uch) ( (uch)& 0x7f )
31 
32 #define RSPEC_KBPS_MASK (0x7f)
33 #define RSPEC_500KBPS(rate) ( (rate)&  RSPEC_KBPS_MASK )
34 #define RSPEC_TO_KBPS(rate) (RSPEC_500KBPS( (rate) ) * (unsigned int)500)
35 
36 #define OTP_WORD_SIZE 16    /* Word size in bits */
37 #define WPA_OUI_TYPE1                     "\x00\x50\xF2\x01"   /** WPA OUI */
38 
39 /******************************************************
40 *             Static Variables
41 ******************************************************/
42 whd_tlv8_data_t *whd_tlv_find_tlv8(const uint8_t *message, uint32_t message_length, uint8_t type);
43 
whd_tlv_find_tlv8(const uint8_t * message,uint32_t message_length,uint8_t type)44 whd_tlv8_data_t *whd_tlv_find_tlv8(const uint8_t *message, uint32_t message_length, uint8_t type)
45 {
46     while (message_length != 0)
47     {
48         uint8_t current_tlv_type   = message[0];
49         uint16_t current_tlv_length = (uint16_t)(message[1] + 2);
50 
51         /* Check if we've overrun the buffer */
52         if (current_tlv_length > message_length)
53         {
54             return NULL;
55         }
56 
57         /* Check if we've found the type we are looking for */
58         if (current_tlv_type == type)
59         {
60             return (whd_tlv8_data_t *)message;
61         }
62 
63         /* Skip current TLV */
64         message        += current_tlv_length;
65         message_length -= current_tlv_length;
66     }
67     return 0;
68 }
69 
whd_parse_tlvs(const whd_tlv8_header_t * tlv_buf,uint32_t buflen,dot11_ie_id_t key)70 whd_tlv8_header_t *whd_parse_tlvs(const whd_tlv8_header_t *tlv_buf, uint32_t buflen,
71                                   dot11_ie_id_t key)
72 {
73     return (whd_tlv8_header_t *)whd_tlv_find_tlv8( (const uint8_t *)tlv_buf, buflen, key );
74 }
75 
whd_is_wpa_ie(vendor_specific_ie_header_t * wpaie,whd_tlv8_header_t ** tlvs,uint32_t * tlvs_len)76 whd_bool_t whd_is_wpa_ie(vendor_specific_ie_header_t *wpaie, whd_tlv8_header_t **tlvs, uint32_t *tlvs_len)
77 {
78     whd_tlv8_header_t *prev_tlvs = *tlvs;
79     whd_tlv8_header_t *new_tlvs = *tlvs;
80     vendor_specific_ie_header_t *ie = wpaie;
81 
82     /* If the contents match the WPA_OUI and type=1 */
83     if ( (ie->tlv_header.length >= (uint8_t)VENDOR_SPECIFIC_IE_MINIMUM_LENGTH) &&
84          (memcmp(ie->oui, WPA_OUI_TYPE1, sizeof(ie->oui) ) == 0) )
85     {
86         /* Found the WPA IE */
87         return WHD_TRUE;
88     }
89 
90     /* calculate the next ie address */
91     new_tlvs = (whd_tlv8_header_t *)( ( (uint8_t *)ie ) + ie->tlv_header.length + sizeof(whd_tlv8_header_t) );
92 
93     /* check the rest of length of buffer */
94     if (*tlvs_len < (uint32_t)( ( (uint8_t *)new_tlvs ) - ( (uint8_t *)prev_tlvs ) ) )
95     {
96         /* set rest of length to zero to avoid buffer overflow */
97         *tlvs_len = 0;
98     }
99     else
100     {
101         /* point to the next ie */
102         *tlvs = new_tlvs;
103 
104         /* tlvs now points to the beginning of next IE pointer, and *ie points to one or more TLV further
105          * down from the *prev_tlvs. So the tlvs_len need to be adjusted by prev_tlvs instead of *ie */
106         *tlvs_len -= (uint32_t)( ( (uint8_t *)*tlvs ) - ( (uint8_t *)prev_tlvs ) );
107     }
108 
109     return WHD_FALSE;
110 }
111 
whd_parse_dot11_tlvs(const whd_tlv8_header_t * tlv_buf,uint32_t buflen,dot11_ie_id_t key)112 whd_tlv8_header_t *whd_parse_dot11_tlvs(const whd_tlv8_header_t *tlv_buf, uint32_t buflen, dot11_ie_id_t key)
113 {
114     return (whd_tlv8_header_t *)whd_tlv_find_tlv8( (const uint8_t *)tlv_buf, buflen, key );
115 }
116 
117 #ifdef WPRINT_ENABLE_WHD_DEBUG
whd_ssid_to_string(uint8_t * value,uint8_t length,char * ssid_buf,uint8_t ssid_buf_len)118 char *whd_ssid_to_string(uint8_t *value, uint8_t length, char *ssid_buf, uint8_t ssid_buf_len)
119 {
120     memset(ssid_buf, 0, ssid_buf_len);
121 
122     if (ssid_buf_len > 0)
123     {
124         memcpy(ssid_buf, value, ssid_buf_len < length ? ssid_buf_len : length);
125     }
126 
127     return ssid_buf;
128 }
129 
130 /* When adding new events, update this switch statement to print correct string */
131 #define CASE_RETURN_STRING(value) case value: \
132         return # value;
133 
134 #define CASE_RETURN(value) case value: \
135         break;
136 
whd_event_to_string(whd_event_num_t value)137 const char *whd_event_to_string(whd_event_num_t value)
138 {
139     switch (value)
140     {
141         CASE_RETURN_STRING(WLC_E_ULP)
142         CASE_RETURN(WLC_E_BT_WIFI_HANDOVER_REQ)
143         CASE_RETURN(WLC_E_SPW_TXINHIBIT)
144         CASE_RETURN(WLC_E_FBT_AUTH_REQ_IND)
145         CASE_RETURN(WLC_E_RSSI_LQM)
146         CASE_RETURN(WLC_E_PFN_GSCAN_FULL_RESULT)
147         CASE_RETURN(WLC_E_PFN_SWC)
148         CASE_RETURN(WLC_E_AUTHORIZED)
149         CASE_RETURN(WLC_E_PROBREQ_MSG_RX)
150         CASE_RETURN(WLC_E_RMC_EVENT)
151         CASE_RETURN(WLC_E_DPSTA_INTF_IND)
152         CASE_RETURN_STRING(WLC_E_NONE)
153         CASE_RETURN_STRING(WLC_E_SET_SSID)
154         CASE_RETURN(WLC_E_PFN_BEST_BATCHING)
155         CASE_RETURN(WLC_E_JOIN)
156         CASE_RETURN(WLC_E_START)
157         CASE_RETURN_STRING(WLC_E_AUTH)
158         CASE_RETURN(WLC_E_AUTH_IND)
159         CASE_RETURN(WLC_E_DEAUTH)
160         CASE_RETURN_STRING(WLC_E_DEAUTH_IND)
161         CASE_RETURN(WLC_E_ASSOC)
162         CASE_RETURN(WLC_E_ASSOC_IND)
163         CASE_RETURN(WLC_E_REASSOC)
164         CASE_RETURN(WLC_E_REASSOC_IND)
165         CASE_RETURN(WLC_E_DISASSOC)
166         CASE_RETURN_STRING(WLC_E_DISASSOC_IND)
167         CASE_RETURN(WLC_E_ROAM)
168         CASE_RETURN(WLC_E_ROAM_PREP)
169         CASE_RETURN(WLC_E_ROAM_START)
170         CASE_RETURN(WLC_E_QUIET_START)
171         CASE_RETURN(WLC_E_QUIET_END)
172         CASE_RETURN(WLC_E_BEACON_RX)
173         CASE_RETURN_STRING(WLC_E_LINK)
174         CASE_RETURN_STRING(WLC_E_RRM)
175         CASE_RETURN(WLC_E_MIC_ERROR)
176         CASE_RETURN(WLC_E_NDIS_LINK)
177         CASE_RETURN(WLC_E_TXFAIL)
178         CASE_RETURN(WLC_E_PMKID_CACHE)
179         CASE_RETURN(WLC_E_RETROGRADE_TSF)
180         CASE_RETURN(WLC_E_PRUNE)
181         CASE_RETURN(WLC_E_AUTOAUTH)
182         CASE_RETURN(WLC_E_EAPOL_MSG)
183         CASE_RETURN(WLC_E_SCAN_COMPLETE)
184         CASE_RETURN(WLC_E_ADDTS_IND)
185         CASE_RETURN(WLC_E_DELTS_IND)
186         CASE_RETURN(WLC_E_BCNSENT_IND)
187         CASE_RETURN(WLC_E_BCNRX_MSG)
188         CASE_RETURN(WLC_E_BCNLOST_MSG)
189         CASE_RETURN_STRING(WLC_E_PFN_NET_FOUND)
190         CASE_RETURN(WLC_E_PFN_NET_LOST)
191         CASE_RETURN(WLC_E_RESET_COMPLETE)
192         CASE_RETURN(WLC_E_JOIN_START)
193         CASE_RETURN(WLC_E_ASSOC_START)
194         CASE_RETURN(WLC_E_IBSS_ASSOC)
195         CASE_RETURN(WLC_E_RADIO)
196         CASE_RETURN(WLC_E_PSM_WATCHDOG)
197         CASE_RETURN(WLC_E_CCX_ASSOC_START)
198         CASE_RETURN(WLC_E_CCX_ASSOC_ABORT)
199         CASE_RETURN(WLC_E_PROBREQ_MSG)
200         CASE_RETURN(WLC_E_SCAN_CONFIRM_IND)
201         CASE_RETURN_STRING(WLC_E_PSK_SUP)
202         CASE_RETURN(WLC_E_COUNTRY_CODE_CHANGED)
203         CASE_RETURN(WLC_E_EXCEEDED_MEDIUM_TIME)
204         CASE_RETURN(WLC_E_ICV_ERROR)
205         CASE_RETURN(WLC_E_UNICAST_DECODE_ERROR)
206         CASE_RETURN(WLC_E_MULTICAST_DECODE_ERROR)
207         CASE_RETURN(WLC_E_TRACE)
208         CASE_RETURN(WLC_E_BTA_HCI_EVENT)
209         CASE_RETURN(WLC_E_IF)
210         CASE_RETURN(WLC_E_P2P_DISC_LISTEN_COMPLETE)
211         CASE_RETURN(WLC_E_RSSI)
212         CASE_RETURN_STRING(WLC_E_PFN_SCAN_COMPLETE)
213         CASE_RETURN(WLC_E_EXTLOG_MSG)
214         CASE_RETURN(WLC_E_ACTION_FRAME)
215         CASE_RETURN(WLC_E_ACTION_FRAME_COMPLETE)
216         CASE_RETURN(WLC_E_PRE_ASSOC_IND)
217         CASE_RETURN(WLC_E_PRE_REASSOC_IND)
218         CASE_RETURN(WLC_E_CHANNEL_ADOPTED)
219         CASE_RETURN(WLC_E_AP_STARTED)
220         CASE_RETURN(WLC_E_DFS_AP_STOP)
221         CASE_RETURN(WLC_E_DFS_AP_RESUME)
222         CASE_RETURN(WLC_E_WAI_STA_EVENT)
223         CASE_RETURN(WLC_E_WAI_MSG)
224         CASE_RETURN_STRING(WLC_E_ESCAN_RESULT)
225         CASE_RETURN(WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE)
226         CASE_RETURN(WLC_E_PROBRESP_MSG)
227         CASE_RETURN(WLC_E_P2P_PROBREQ_MSG)
228         CASE_RETURN(WLC_E_DCS_REQUEST)
229         CASE_RETURN(WLC_E_FIFO_CREDIT_MAP)
230         CASE_RETURN(WLC_E_ACTION_FRAME_RX)
231         CASE_RETURN(WLC_E_WAKE_EVENT)
232         CASE_RETURN(WLC_E_RM_COMPLETE)
233         CASE_RETURN(WLC_E_HTSFSYNC)
234         CASE_RETURN(WLC_E_OVERLAY_REQ)
235         CASE_RETURN_STRING(WLC_E_CSA_COMPLETE_IND)
236         CASE_RETURN(WLC_E_EXCESS_PM_WAKE_EVENT)
237         CASE_RETURN(WLC_E_PFN_SCAN_NONE)
238         CASE_RETURN(WLC_E_PFN_SCAN_ALLGONE)
239         CASE_RETURN(WLC_E_GTK_PLUMBED)
240         CASE_RETURN(WLC_E_ASSOC_IND_NDIS)
241         CASE_RETURN(WLC_E_REASSOC_IND_NDIS)
242         CASE_RETURN(WLC_E_ASSOC_REQ_IE)
243         CASE_RETURN(WLC_E_ASSOC_RESP_IE)
244         CASE_RETURN(WLC_E_ASSOC_RECREATED)
245         CASE_RETURN(WLC_E_ACTION_FRAME_RX_NDIS)
246         CASE_RETURN(WLC_E_AUTH_REQ)
247         CASE_RETURN(WLC_E_TDLS_PEER_EVENT)
248         CASE_RETURN(WLC_E_SPEEDY_RECREATE_FAIL)
249         CASE_RETURN(WLC_E_NATIVE)
250         CASE_RETURN(WLC_E_PKTDELAY_IND)
251         CASE_RETURN(WLC_E_AWDL_AW)
252         CASE_RETURN(WLC_E_AWDL_ROLE)
253         CASE_RETURN(WLC_E_AWDL_EVENT)
254         CASE_RETURN(WLC_E_NIC_AF_TXS)
255         CASE_RETURN(WLC_E_NAN)
256         CASE_RETURN(WLC_E_BEACON_FRAME_RX)
257         CASE_RETURN(WLC_E_SERVICE_FOUND)
258         CASE_RETURN(WLC_E_GAS_FRAGMENT_RX)
259         CASE_RETURN(WLC_E_GAS_COMPLETE)
260         CASE_RETURN(WLC_E_P2PO_ADD_DEVICE)
261         CASE_RETURN(WLC_E_P2PO_DEL_DEVICE)
262         CASE_RETURN(WLC_E_WNM_STA_SLEEP)
263         CASE_RETURN(WLC_E_TXFAIL_THRESH)
264         CASE_RETURN(WLC_E_PROXD)
265         CASE_RETURN(WLC_E_IBSS_COALESCE)
266         CASE_RETURN(WLC_E_AWDL_RX_PRB_RESP)
267         CASE_RETURN(WLC_E_AWDL_RX_ACT_FRAME)
268         CASE_RETURN(WLC_E_AWDL_WOWL_NULLPKT)
269         CASE_RETURN(WLC_E_AWDL_PHYCAL_STATUS)
270         CASE_RETURN(WLC_E_AWDL_OOB_AF_STATUS)
271         CASE_RETURN(WLC_E_AWDL_SCAN_STATUS)
272         CASE_RETURN(WLC_E_AWDL_AW_START)
273         CASE_RETURN(WLC_E_AWDL_AW_END)
274         CASE_RETURN(WLC_E_AWDL_AW_EXT)
275         CASE_RETURN(WLC_E_AWDL_PEER_CACHE_CONTROL)
276         CASE_RETURN(WLC_E_CSA_START_IND)
277         CASE_RETURN(WLC_E_CSA_DONE_IND)
278         CASE_RETURN(WLC_E_CSA_FAILURE_IND)
279         CASE_RETURN(WLC_E_CCA_CHAN_QUAL)
280         CASE_RETURN(WLC_E_BSSID)
281         CASE_RETURN(WLC_E_TX_STAT_ERROR)
282         CASE_RETURN(WLC_E_BCMC_CREDIT_SUPPORT)
283         CASE_RETURN(WLC_E_PSTA_PRIMARY_INTF_IND)
284         case WLC_E_LAST:
285         default:
286             return "Unknown";
287 
288             break;
289     }
290 
291     return "Unknown";
292 }
293 
whd_status_to_string(whd_event_status_t status)294 const char *whd_status_to_string(whd_event_status_t status)
295 {
296     switch (status)
297     {
298         CASE_RETURN_STRING(WLC_E_STATUS_SUCCESS)
299         CASE_RETURN_STRING(WLC_E_STATUS_FAIL)
300         CASE_RETURN_STRING(WLC_E_STATUS_TIMEOUT)
301         CASE_RETURN_STRING(WLC_E_STATUS_NO_NETWORKS)
302         CASE_RETURN_STRING(WLC_E_STATUS_ABORT)
303         CASE_RETURN_STRING(WLC_E_STATUS_NO_ACK)
304         CASE_RETURN_STRING(WLC_E_STATUS_UNSOLICITED)
305         CASE_RETURN_STRING(WLC_E_STATUS_ATTEMPT)
306         CASE_RETURN_STRING(WLC_E_STATUS_PARTIAL)
307         CASE_RETURN_STRING(WLC_E_STATUS_NEWSCAN)
308         CASE_RETURN_STRING(WLC_E_STATUS_NEWASSOC)
309         CASE_RETURN_STRING(WLC_E_STATUS_11HQUIET)
310         CASE_RETURN_STRING(WLC_E_STATUS_SUPPRESS)
311         CASE_RETURN_STRING(WLC_E_STATUS_NOCHANS)
312         CASE_RETURN_STRING(WLC_E_STATUS_CCXFASTRM)
313         CASE_RETURN_STRING(WLC_E_STATUS_CS_ABORT)
314         CASE_RETURN_STRING(WLC_SUP_DISCONNECTED)
315         CASE_RETURN_STRING(WLC_SUP_CONNECTING)
316         CASE_RETURN_STRING(WLC_SUP_IDREQUIRED)
317         CASE_RETURN_STRING(WLC_SUP_AUTHENTICATING)
318         CASE_RETURN_STRING(WLC_SUP_AUTHENTICATED)
319         CASE_RETURN_STRING(WLC_SUP_KEYXCHANGE)
320         CASE_RETURN_STRING(WLC_SUP_KEYED)
321         CASE_RETURN_STRING(WLC_SUP_TIMEOUT)
322         CASE_RETURN_STRING(WLC_SUP_LAST_BASIC_STATE)
323         CASE_RETURN_STRING(WLC_SUP_KEYXCHANGE_PREP_M4)
324         CASE_RETURN_STRING(WLC_SUP_KEYXCHANGE_WAIT_G1)
325         CASE_RETURN_STRING(WLC_SUP_KEYXCHANGE_PREP_G2)
326         CASE_RETURN_STRING(WLC_DOT11_SC_SUCCESS)
327         CASE_RETURN_STRING(WLC_DOT11_SC_FAILURE)
328         CASE_RETURN_STRING(WLC_DOT11_SC_CAP_MISMATCH)
329         CASE_RETURN_STRING(WLC_DOT11_SC_REASSOC_FAIL)
330         CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_FAIL)
331         CASE_RETURN_STRING(WLC_DOT11_SC_AUTH_MISMATCH)
332         CASE_RETURN_STRING(WLC_DOT11_SC_AUTH_SEQ)
333         CASE_RETURN_STRING(WLC_DOT11_SC_AUTH_CHALLENGE_FAIL)
334         CASE_RETURN_STRING(WLC_DOT11_SC_AUTH_TIMEOUT)
335         CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_BUSY_FAIL)
336         CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_RATE_MISMATCH)
337         CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_SHORT_REQUIRED)
338         CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_PBCC_REQUIRED)
339         CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_AGILITY_REQUIRED)
340         CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_SPECTRUM_REQUIRED)
341         CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_BAD_POWER_CAP)
342         CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_BAD_SUP_CHANNELS)
343         CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_SHORTSLOT_REQUIRED)
344         CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_ERPBCC_REQUIRED)
345         CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_DSSOFDM_REQUIRED)
346         CASE_RETURN_STRING(WLC_DOT11_SC_DECLINED)
347         CASE_RETURN_STRING(WLC_DOT11_SC_INVALID_PARAMS)
348         CASE_RETURN_STRING(WLC_DOT11_SC_INVALID_AKMP)
349         CASE_RETURN_STRING(WLC_DOT11_SC_INVALID_MDID)
350         CASE_RETURN_STRING(WLC_DOT11_SC_INVALID_FTIE)
351         case WLC_E_STATUS_FORCE_32_BIT:
352         default:
353             break;
354     }
355     return "Unknown";
356 }
357 
whd_reason_to_string(whd_event_reason_t reason)358 const char *whd_reason_to_string(whd_event_reason_t reason)
359 {
360     switch (reason)
361     {
362         CASE_RETURN_STRING(WLC_E_REASON_INITIAL_ASSOC)
363         CASE_RETURN_STRING(WLC_E_REASON_LOW_RSSI)
364         CASE_RETURN_STRING(WLC_E_REASON_DEAUTH)
365         CASE_RETURN_STRING(WLC_E_REASON_DISASSOC)
366         CASE_RETURN_STRING(WLC_E_REASON_BCNS_LOST)
367         CASE_RETURN_STRING(WLC_E_REASON_FAST_ROAM_FAILED)
368         CASE_RETURN_STRING(WLC_E_REASON_DIRECTED_ROAM)
369         CASE_RETURN_STRING(WLC_E_REASON_TSPEC_REJECTED)
370         CASE_RETURN_STRING(WLC_E_REASON_BETTER_AP)
371         CASE_RETURN_STRING(WLC_E_PRUNE_ENCR_MISMATCH)
372         CASE_RETURN_STRING(WLC_E_PRUNE_BCAST_BSSID)
373         CASE_RETURN_STRING(WLC_E_PRUNE_MAC_DENY)
374         CASE_RETURN_STRING(WLC_E_PRUNE_MAC_NA)
375         CASE_RETURN_STRING(WLC_E_PRUNE_REG_PASSV)
376         CASE_RETURN_STRING(WLC_E_PRUNE_SPCT_MGMT)
377         CASE_RETURN_STRING(WLC_E_PRUNE_RADAR)
378         CASE_RETURN_STRING(WLC_E_RSN_MISMATCH)
379         CASE_RETURN_STRING(WLC_E_PRUNE_NO_COMMON_RATES)
380         CASE_RETURN_STRING(WLC_E_PRUNE_BASIC_RATES)
381         CASE_RETURN_STRING(WLC_E_PRUNE_CCXFAST_PREVAP)
382         CASE_RETURN_STRING(WLC_E_PRUNE_CIPHER_NA)
383         CASE_RETURN_STRING(WLC_E_PRUNE_KNOWN_STA)
384         CASE_RETURN_STRING(WLC_E_PRUNE_CCXFAST_DROAM)
385         CASE_RETURN_STRING(WLC_E_PRUNE_WDS_PEER)
386         CASE_RETURN_STRING(WLC_E_PRUNE_QBSS_LOAD)
387         CASE_RETURN_STRING(WLC_E_PRUNE_HOME_AP)
388         CASE_RETURN_STRING(WLC_E_PRUNE_AP_BLOCKED)
389         CASE_RETURN_STRING(WLC_E_PRUNE_NO_DIAG_SUPPORT)
390         CASE_RETURN_STRING(WLC_E_SUP_OTHER)
391         CASE_RETURN_STRING(WLC_E_SUP_DECRYPT_KEY_DATA)
392         CASE_RETURN_STRING(WLC_E_SUP_BAD_UCAST_WEP128)
393         CASE_RETURN_STRING(WLC_E_SUP_BAD_UCAST_WEP40)
394         CASE_RETURN_STRING(WLC_E_SUP_UNSUP_KEY_LEN)
395         CASE_RETURN_STRING(WLC_E_SUP_PW_KEY_CIPHER)
396         CASE_RETURN_STRING(WLC_E_SUP_MSG3_TOO_MANY_IE)
397         CASE_RETURN_STRING(WLC_E_SUP_MSG3_IE_MISMATCH)
398         CASE_RETURN_STRING(WLC_E_SUP_NO_INSTALL_FLAG)
399         CASE_RETURN_STRING(WLC_E_SUP_MSG3_NO_GTK)
400         CASE_RETURN_STRING(WLC_E_SUP_GRP_KEY_CIPHER)
401         CASE_RETURN_STRING(WLC_E_SUP_GRP_MSG1_NO_GTK)
402         CASE_RETURN_STRING(WLC_E_SUP_GTK_DECRYPT_FAIL)
403         CASE_RETURN_STRING(WLC_E_SUP_SEND_FAIL)
404         CASE_RETURN_STRING(WLC_E_SUP_DEAUTH)
405         CASE_RETURN_STRING(WLC_E_SUP_WPA_PSK_TMO)
406         CASE_RETURN_STRING(DOT11_RC_RESERVED)
407         CASE_RETURN_STRING(DOT11_RC_UNSPECIFIED)
408         CASE_RETURN_STRING(DOT11_RC_AUTH_INVAL)
409         CASE_RETURN_STRING(DOT11_RC_DEAUTH_LEAVING)
410         CASE_RETURN_STRING(DOT11_RC_INACTIVITY)
411         CASE_RETURN_STRING(DOT11_RC_BUSY)
412         CASE_RETURN_STRING(DOT11_RC_INVAL_CLASS_2)
413         CASE_RETURN_STRING(DOT11_RC_INVAL_CLASS_3)
414         CASE_RETURN_STRING(DOT11_RC_DISASSOC_LEAVING)
415         CASE_RETURN_STRING(DOT11_RC_NOT_AUTH)
416         CASE_RETURN_STRING(DOT11_RC_BAD_PC)
417         CASE_RETURN_STRING(DOT11_RC_BAD_CHANNELS)
418         CASE_RETURN_STRING(DOT11_RC_UNSPECIFIED_QOS)
419         CASE_RETURN_STRING(DOT11_RC_INSUFFCIENT_BW)
420         CASE_RETURN_STRING(DOT11_RC_EXCESSIVE_FRAMES)
421         CASE_RETURN_STRING(DOT11_RC_TX_OUTSIDE_TXOP)
422         CASE_RETURN_STRING(DOT11_RC_LEAVING_QBSS)
423         CASE_RETURN_STRING(DOT11_RC_BAD_MECHANISM)
424         CASE_RETURN_STRING(DOT11_RC_SETUP_NEEDED)
425         CASE_RETURN_STRING(DOT11_RC_TIMEOUT)
426         CASE_RETURN_STRING(WLC_E_NAN_EVENT_STATUS_CHG)
427         CASE_RETURN_STRING(WLC_E_NAN_EVENT_MERGE)
428         CASE_RETURN_STRING(WLC_E_NAN_EVENT_STOP)
429         CASE_RETURN_STRING(WLC_E_NAN_EVENT_P2P)
430         CASE_RETURN_STRING(WLC_E_NAN_EVENT_WINDOW_BEGIN_P2P)
431         CASE_RETURN_STRING(WLC_E_NAN_EVENT_WINDOW_BEGIN_MESH)
432         CASE_RETURN_STRING(WLC_E_NAN_EVENT_WINDOW_BEGIN_IBSS)
433         CASE_RETURN_STRING(WLC_E_NAN_EVENT_WINDOW_BEGIN_RANGING)
434         CASE_RETURN_STRING(WLC_E_NAN_EVENT_POST_DISC)
435         CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_IF_ADD)
436         CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_PEER_ADD)
437         CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_IND)
438         CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_CONF)
439         CASE_RETURN_STRING(WLC_E_NAN_EVENT_SDF_RX)
440         CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_END)
441         CASE_RETURN_STRING(WLC_E_NAN_EVENT_BCN_RX)
442         case DOT11_RC_MAX:
443         case WLC_E_REASON_FORCE_32_BIT:
444         default:
445             break;
446     }
447 
448     return "Unknown";
449 }
450 
whd_ether_ntoa(const uint8_t * ea,char * buf,uint8_t buf_len)451 char *whd_ether_ntoa(const uint8_t *ea, char *buf, uint8_t buf_len)
452 {
453     const char hex[] =
454     {
455         '0', '1', '2', '3', '4', '5', '6', '7',
456         '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
457     };
458     char *output = buf;
459     const uint8_t *octet = ea;
460 
461     if (buf_len < WHD_ETHER_ADDR_STR_LEN)
462     {
463         if (buf_len > 0)
464         {
465             /* buffer too short */
466             buf[0] = '\0';
467         }
468         return buf;
469     }
470 
471     for (; octet != &ea[WHD_ETHER_ADDR_LEN]; octet++)
472     {
473         *output++ = hex[(*octet >> 4) & 0xf];
474         *output++ = hex[*octet & 0xf];
475         *output++ = ':';
476     }
477 
478     *(output - 1) = '\0';
479 
480     return buf;
481 }
482 
whd_ioctl_to_string(uint32_t ioctl)483 const char *whd_ioctl_to_string(uint32_t ioctl)
484 {
485     switch (ioctl)
486     {
487         CASE_RETURN_STRING(WLC_GET_MAGIC)
488         CASE_RETURN_STRING(WLC_GET_VERSION)
489         CASE_RETURN_STRING(WLC_UP)
490         CASE_RETURN_STRING(WLC_DOWN)
491         CASE_RETURN_STRING(WLC_GET_LOOP)
492         CASE_RETURN_STRING(WLC_SET_LOOP)
493         CASE_RETURN_STRING(WLC_DUMP)
494         CASE_RETURN_STRING(WLC_GET_MSGLEVEL)
495         CASE_RETURN_STRING(WLC_SET_MSGLEVEL)
496         CASE_RETURN_STRING(WLC_GET_PROMISC)
497         CASE_RETURN_STRING(WLC_SET_PROMISC)
498         CASE_RETURN_STRING(WLC_GET_RATE)
499         CASE_RETURN_STRING(WLC_GET_INSTANCE)
500         CASE_RETURN_STRING(WLC_GET_INFRA)
501         CASE_RETURN_STRING(WLC_SET_INFRA)
502         CASE_RETURN_STRING(WLC_GET_AUTH)
503         CASE_RETURN_STRING(WLC_SET_AUTH)
504         CASE_RETURN_STRING(WLC_GET_BSSID)
505         CASE_RETURN_STRING(WLC_SET_BSSID)
506         CASE_RETURN_STRING(WLC_GET_SSID)
507         CASE_RETURN_STRING(WLC_SET_SSID)
508         CASE_RETURN_STRING(WLC_RESTART)
509         CASE_RETURN_STRING(WLC_GET_CHANNEL)
510         CASE_RETURN_STRING(WLC_SET_CHANNEL)
511         CASE_RETURN_STRING(WLC_GET_SRL)
512         CASE_RETURN_STRING(WLC_SET_SRL)
513         CASE_RETURN_STRING(WLC_GET_LRL)
514         CASE_RETURN_STRING(WLC_SET_LRL)
515         CASE_RETURN_STRING(WLC_GET_PLCPHDR)
516         CASE_RETURN_STRING(WLC_SET_PLCPHDR)
517         CASE_RETURN_STRING(WLC_GET_RADIO)
518         CASE_RETURN_STRING(WLC_SET_RADIO)
519         CASE_RETURN_STRING(WLC_GET_PHYTYPE)
520         CASE_RETURN_STRING(WLC_DUMP_RATE)
521         CASE_RETURN_STRING(WLC_SET_RATE_PARAMS)
522         CASE_RETURN_STRING(WLC_GET_KEY)
523         CASE_RETURN_STRING(WLC_SET_KEY)
524         CASE_RETURN_STRING(WLC_GET_REGULATORY)
525         CASE_RETURN_STRING(WLC_SET_REGULATORY)
526         CASE_RETURN_STRING(WLC_GET_PASSIVE_SCAN)
527         CASE_RETURN_STRING(WLC_SET_PASSIVE_SCAN)
528         CASE_RETURN_STRING(WLC_SCAN)
529         CASE_RETURN_STRING(WLC_SCAN_RESULTS)
530         CASE_RETURN_STRING(WLC_DISASSOC)
531         CASE_RETURN_STRING(WLC_REASSOC)
532         CASE_RETURN_STRING(WLC_GET_ROAM_TRIGGER)
533         CASE_RETURN_STRING(WLC_SET_ROAM_TRIGGER)
534         CASE_RETURN_STRING(WLC_GET_ROAM_DELTA)
535         CASE_RETURN_STRING(WLC_SET_ROAM_DELTA)
536         CASE_RETURN_STRING(WLC_GET_ROAM_SCAN_PERIOD)
537         CASE_RETURN_STRING(WLC_SET_ROAM_SCAN_PERIOD)
538         CASE_RETURN_STRING(WLC_EVM)
539         CASE_RETURN_STRING(WLC_GET_TXANT)
540         CASE_RETURN_STRING(WLC_SET_TXANT)
541         CASE_RETURN_STRING(WLC_GET_ANTDIV)
542         CASE_RETURN_STRING(WLC_SET_ANTDIV)
543         CASE_RETURN_STRING(WLC_GET_CLOSED)
544         CASE_RETURN_STRING(WLC_SET_CLOSED)
545         CASE_RETURN_STRING(WLC_GET_MACLIST)
546         CASE_RETURN_STRING(WLC_SET_MACLIST)
547         CASE_RETURN_STRING(WLC_GET_RATESET)
548         CASE_RETURN_STRING(WLC_SET_RATESET)
549         CASE_RETURN_STRING(WLC_LONGTRAIN)
550         CASE_RETURN_STRING(WLC_GET_BCNPRD)
551         CASE_RETURN_STRING(WLC_SET_BCNPRD)
552         CASE_RETURN_STRING(WLC_GET_DTIMPRD)
553         CASE_RETURN_STRING(WLC_SET_DTIMPRD)
554         CASE_RETURN_STRING(WLC_GET_SROM)
555         CASE_RETURN_STRING(WLC_SET_SROM)
556         CASE_RETURN_STRING(WLC_GET_WEP_RESTRICT)
557         CASE_RETURN_STRING(WLC_SET_WEP_RESTRICT)
558         CASE_RETURN_STRING(WLC_GET_COUNTRY)
559         CASE_RETURN_STRING(WLC_SET_COUNTRY)
560         CASE_RETURN_STRING(WLC_GET_PM)
561         CASE_RETURN_STRING(WLC_SET_PM)
562         CASE_RETURN_STRING(WLC_GET_WAKE)
563         CASE_RETURN_STRING(WLC_SET_WAKE)
564         CASE_RETURN_STRING(WLC_GET_FORCELINK)
565         CASE_RETURN_STRING(WLC_SET_FORCELINK)
566         CASE_RETURN_STRING(WLC_FREQ_ACCURACY)
567         CASE_RETURN_STRING(WLC_CARRIER_SUPPRESS)
568         CASE_RETURN_STRING(WLC_GET_PHYREG)
569         CASE_RETURN_STRING(WLC_SET_PHYREG)
570         CASE_RETURN_STRING(WLC_GET_RADIOREG)
571         CASE_RETURN_STRING(WLC_SET_RADIOREG)
572         CASE_RETURN_STRING(WLC_GET_REVINFO)
573         CASE_RETURN_STRING(WLC_GET_UCANTDIV)
574         CASE_RETURN_STRING(WLC_SET_UCANTDIV)
575         CASE_RETURN_STRING(WLC_R_REG)
576         CASE_RETURN_STRING(WLC_W_REG)
577         CASE_RETURN_STRING(WLC_GET_MACMODE)
578         CASE_RETURN_STRING(WLC_SET_MACMODE)
579         CASE_RETURN_STRING(WLC_GET_MONITOR)
580         CASE_RETURN_STRING(WLC_SET_MONITOR)
581         CASE_RETURN_STRING(WLC_GET_GMODE)
582         CASE_RETURN_STRING(WLC_SET_GMODE)
583         CASE_RETURN_STRING(WLC_GET_LEGACY_ERP)
584         CASE_RETURN_STRING(WLC_SET_LEGACY_ERP)
585         CASE_RETURN_STRING(WLC_GET_RX_ANT)
586         CASE_RETURN_STRING(WLC_GET_CURR_RATESET)
587         CASE_RETURN_STRING(WLC_GET_SCANSUPPRESS)
588         CASE_RETURN_STRING(WLC_SET_SCANSUPPRESS)
589         CASE_RETURN_STRING(WLC_GET_AP)
590         CASE_RETURN_STRING(WLC_SET_AP)
591         CASE_RETURN_STRING(WLC_GET_EAP_RESTRICT)
592         CASE_RETURN_STRING(WLC_SET_EAP_RESTRICT)
593         CASE_RETURN_STRING(WLC_SCB_AUTHORIZE)
594         CASE_RETURN_STRING(WLC_SCB_DEAUTHORIZE)
595         CASE_RETURN_STRING(WLC_GET_WDSLIST)
596         CASE_RETURN_STRING(WLC_SET_WDSLIST)
597         CASE_RETURN_STRING(WLC_GET_ATIM)
598         CASE_RETURN_STRING(WLC_SET_ATIM)
599         CASE_RETURN_STRING(WLC_GET_RSSI)
600         CASE_RETURN_STRING(WLC_GET_PHYANTDIV)
601         CASE_RETURN_STRING(WLC_SET_PHYANTDIV)
602         CASE_RETURN_STRING(WLC_AP_RX_ONLY)
603         CASE_RETURN_STRING(WLC_GET_TX_PATH_PWR)
604         CASE_RETURN_STRING(WLC_SET_TX_PATH_PWR)
605         CASE_RETURN_STRING(WLC_GET_WSEC)
606         CASE_RETURN_STRING(WLC_SET_WSEC)
607         CASE_RETURN_STRING(WLC_GET_PHY_NOISE)
608         CASE_RETURN_STRING(WLC_GET_BSS_INFO)
609         CASE_RETURN_STRING(WLC_GET_PKTCNTS)
610         CASE_RETURN_STRING(WLC_GET_LAZYWDS)
611         CASE_RETURN_STRING(WLC_SET_LAZYWDS)
612         CASE_RETURN_STRING(WLC_GET_BANDLIST)
613         CASE_RETURN_STRING(WLC_GET_BAND)
614         CASE_RETURN_STRING(WLC_SET_BAND)
615         CASE_RETURN_STRING(WLC_SCB_DEAUTHENTICATE)
616         CASE_RETURN_STRING(WLC_GET_SHORTSLOT)
617         CASE_RETURN_STRING(WLC_GET_SHORTSLOT_OVERRIDE)
618         CASE_RETURN_STRING(WLC_SET_SHORTSLOT_OVERRIDE)
619         CASE_RETURN_STRING(WLC_GET_SHORTSLOT_RESTRICT)
620         CASE_RETURN_STRING(WLC_SET_SHORTSLOT_RESTRICT)
621         CASE_RETURN_STRING(WLC_GET_GMODE_PROTECTION)
622         CASE_RETURN_STRING(WLC_GET_GMODE_PROTECTION_OVERRIDE)
623         CASE_RETURN_STRING(WLC_SET_GMODE_PROTECTION_OVERRIDE)
624         CASE_RETURN_STRING(WLC_UPGRADE)
625         CASE_RETURN_STRING(WLC_GET_IGNORE_BCNS)
626         CASE_RETURN_STRING(WLC_SET_IGNORE_BCNS)
627         CASE_RETURN_STRING(WLC_GET_SCB_TIMEOUT)
628         CASE_RETURN_STRING(WLC_SET_SCB_TIMEOUT)
629         CASE_RETURN_STRING(WLC_GET_ASSOCLIST)
630         CASE_RETURN_STRING(WLC_GET_CLK)
631         CASE_RETURN_STRING(WLC_SET_CLK)
632         CASE_RETURN_STRING(WLC_GET_UP)
633         CASE_RETURN_STRING(WLC_OUT)
634         CASE_RETURN_STRING(WLC_GET_WPA_AUTH)
635         CASE_RETURN_STRING(WLC_SET_WPA_AUTH)
636         CASE_RETURN_STRING(WLC_GET_UCFLAGS)
637         CASE_RETURN_STRING(WLC_SET_UCFLAGS)
638         CASE_RETURN_STRING(WLC_GET_PWRIDX)
639         CASE_RETURN_STRING(WLC_SET_PWRIDX)
640         CASE_RETURN_STRING(WLC_GET_TSSI)
641         CASE_RETURN_STRING(WLC_GET_SUP_RATESET_OVERRIDE)
642         CASE_RETURN_STRING(WLC_SET_SUP_RATESET_OVERRIDE)
643         CASE_RETURN_STRING(WLC_GET_PROTECTION_CONTROL)
644         CASE_RETURN_STRING(WLC_SET_PROTECTION_CONTROL)
645         CASE_RETURN_STRING(WLC_GET_PHYLIST)
646         CASE_RETURN_STRING(WLC_ENCRYPT_STRENGTH)
647         CASE_RETURN_STRING(WLC_DECRYPT_STATUS)
648         CASE_RETURN_STRING(WLC_GET_KEY_SEQ)
649         CASE_RETURN_STRING(WLC_GET_SCAN_CHANNEL_TIME)
650         CASE_RETURN_STRING(WLC_SET_SCAN_CHANNEL_TIME)
651         CASE_RETURN_STRING(WLC_GET_SCAN_UNASSOC_TIME)
652         CASE_RETURN_STRING(WLC_SET_SCAN_UNASSOC_TIME)
653         CASE_RETURN_STRING(WLC_GET_SCAN_HOME_TIME)
654         CASE_RETURN_STRING(WLC_SET_SCAN_HOME_TIME)
655         CASE_RETURN_STRING(WLC_GET_SCAN_NPROBES)
656         CASE_RETURN_STRING(WLC_SET_SCAN_NPROBES)
657         CASE_RETURN_STRING(WLC_GET_PRB_RESP_TIMEOUT)
658         CASE_RETURN_STRING(WLC_SET_PRB_RESP_TIMEOUT)
659         CASE_RETURN_STRING(WLC_GET_ATTEN)
660         CASE_RETURN_STRING(WLC_SET_ATTEN)
661         CASE_RETURN_STRING(WLC_GET_SHMEM)
662         CASE_RETURN_STRING(WLC_SET_SHMEM)
663         CASE_RETURN_STRING(WLC_SET_WSEC_TEST)
664         CASE_RETURN_STRING(WLC_SCB_DEAUTHENTICATE_FOR_REASON)
665         CASE_RETURN_STRING(WLC_TKIP_COUNTERMEASURES)
666         CASE_RETURN_STRING(WLC_GET_PIOMODE)
667         CASE_RETURN_STRING(WLC_SET_PIOMODE)
668         CASE_RETURN_STRING(WLC_SET_ASSOC_PREFER)
669         CASE_RETURN_STRING(WLC_GET_ASSOC_PREFER)
670         CASE_RETURN_STRING(WLC_SET_ROAM_PREFER)
671         CASE_RETURN_STRING(WLC_GET_ROAM_PREFER)
672         CASE_RETURN_STRING(WLC_SET_LED)
673         CASE_RETURN_STRING(WLC_GET_LED)
674         CASE_RETURN_STRING(WLC_GET_INTERFERENCE_MODE)
675         CASE_RETURN_STRING(WLC_SET_INTERFERENCE_MODE)
676         CASE_RETURN_STRING(WLC_GET_CHANNEL_QA)
677         CASE_RETURN_STRING(WLC_START_CHANNEL_QA)
678         CASE_RETURN_STRING(WLC_GET_CHANNEL_SEL)
679         CASE_RETURN_STRING(WLC_START_CHANNEL_SEL)
680         CASE_RETURN_STRING(WLC_GET_VALID_CHANNELS)
681         CASE_RETURN_STRING(WLC_GET_FAKEFRAG)
682         CASE_RETURN_STRING(WLC_SET_FAKEFRAG)
683         CASE_RETURN_STRING(WLC_GET_PWROUT_PERCENTAGE)
684         CASE_RETURN_STRING(WLC_SET_PWROUT_PERCENTAGE)
685         CASE_RETURN_STRING(WLC_SET_BAD_FRAME_PREEMPT)
686         CASE_RETURN_STRING(WLC_GET_BAD_FRAME_PREEMPT)
687         CASE_RETURN_STRING(WLC_SET_LEAP_LIST)
688         CASE_RETURN_STRING(WLC_GET_LEAP_LIST)
689         CASE_RETURN_STRING(WLC_GET_CWMIN)
690         CASE_RETURN_STRING(WLC_SET_CWMIN)
691         CASE_RETURN_STRING(WLC_GET_CWMAX)
692         CASE_RETURN_STRING(WLC_SET_CWMAX)
693         CASE_RETURN_STRING(WLC_GET_WET)
694         CASE_RETURN_STRING(WLC_SET_WET)
695         CASE_RETURN_STRING(WLC_GET_KEY_PRIMARY)
696         CASE_RETURN_STRING(WLC_SET_KEY_PRIMARY)
697         CASE_RETURN_STRING(WLC_GET_ACI_ARGS)
698         CASE_RETURN_STRING(WLC_SET_ACI_ARGS)
699         CASE_RETURN_STRING(WLC_UNSET_CALLBACK)
700         CASE_RETURN_STRING(WLC_SET_CALLBACK)
701         CASE_RETURN_STRING(WLC_GET_RADAR)
702         CASE_RETURN_STRING(WLC_SET_RADAR)
703         CASE_RETURN_STRING(WLC_SET_SPECT_MANAGMENT)
704         CASE_RETURN_STRING(WLC_GET_SPECT_MANAGMENT)
705         CASE_RETURN_STRING(WLC_WDS_GET_REMOTE_HWADDR)
706         CASE_RETURN_STRING(WLC_WDS_GET_WPA_SUP)
707         CASE_RETURN_STRING(WLC_SET_CS_SCAN_TIMER)
708         CASE_RETURN_STRING(WLC_GET_CS_SCAN_TIMER)
709         CASE_RETURN_STRING(WLC_MEASURE_REQUEST)
710         CASE_RETURN_STRING(WLC_INIT)
711         CASE_RETURN_STRING(WLC_SEND_QUIET)
712         CASE_RETURN_STRING(WLC_KEEPALIVE)
713         CASE_RETURN_STRING(WLC_SEND_PWR_CONSTRAINT)
714         CASE_RETURN_STRING(WLC_UPGRADE_STATUS)
715         CASE_RETURN_STRING(WLC_GET_SCAN_PASSIVE_TIME)
716         CASE_RETURN_STRING(WLC_SET_SCAN_PASSIVE_TIME)
717         CASE_RETURN_STRING(WLC_LEGACY_LINK_BEHAVIOR)
718         CASE_RETURN_STRING(WLC_GET_CHANNELS_IN_COUNTRY)
719         CASE_RETURN_STRING(WLC_GET_COUNTRY_LIST)
720         CASE_RETURN_STRING(WLC_GET_VAR)
721         CASE_RETURN_STRING(WLC_SET_VAR)
722         CASE_RETURN_STRING(WLC_NVRAM_GET)
723         CASE_RETURN_STRING(WLC_NVRAM_SET)
724         CASE_RETURN_STRING(WLC_NVRAM_DUMP)
725         CASE_RETURN_STRING(WLC_REBOOT)
726         CASE_RETURN_STRING(WLC_SET_WSEC_PMK)
727         CASE_RETURN_STRING(WLC_GET_AUTH_MODE)
728         CASE_RETURN_STRING(WLC_SET_AUTH_MODE)
729         CASE_RETURN_STRING(WLC_GET_WAKEENTRY)
730         CASE_RETURN_STRING(WLC_SET_WAKEENTRY)
731         CASE_RETURN_STRING(WLC_NDCONFIG_ITEM)
732         CASE_RETURN_STRING(WLC_NVOTPW)
733         CASE_RETURN_STRING(WLC_OTPW)
734         CASE_RETURN_STRING(WLC_IOV_BLOCK_GET)
735         CASE_RETURN_STRING(WLC_IOV_MODULES_GET)
736         CASE_RETURN_STRING(WLC_SOFT_RESET)
737         CASE_RETURN_STRING(WLC_GET_ALLOW_MODE)
738         CASE_RETURN_STRING(WLC_SET_ALLOW_MODE)
739         CASE_RETURN_STRING(WLC_GET_DESIRED_BSSID)
740         CASE_RETURN_STRING(WLC_SET_DESIRED_BSSID)
741         CASE_RETURN_STRING(WLC_DISASSOC_MYAP)
742         CASE_RETURN_STRING(WLC_GET_NBANDS)
743         CASE_RETURN_STRING(WLC_GET_BANDSTATES)
744         CASE_RETURN_STRING(WLC_GET_WLC_BSS_INFO)
745         CASE_RETURN_STRING(WLC_GET_ASSOC_INFO)
746         CASE_RETURN_STRING(WLC_GET_OID_PHY)
747         CASE_RETURN_STRING(WLC_SET_OID_PHY)
748         CASE_RETURN_STRING(WLC_SET_ASSOC_TIME)
749         CASE_RETURN_STRING(WLC_GET_DESIRED_SSID)
750         CASE_RETURN_STRING(WLC_GET_CHANSPEC)
751         CASE_RETURN_STRING(WLC_GET_ASSOC_STATE)
752         CASE_RETURN_STRING(WLC_SET_PHY_STATE)
753         CASE_RETURN_STRING(WLC_GET_SCAN_PENDING)
754         CASE_RETURN_STRING(WLC_GET_SCANREQ_PENDING)
755         CASE_RETURN_STRING(WLC_GET_PREV_ROAM_REASON)
756         CASE_RETURN_STRING(WLC_SET_PREV_ROAM_REASON)
757         CASE_RETURN_STRING(WLC_GET_BANDSTATES_PI)
758         CASE_RETURN_STRING(WLC_GET_PHY_STATE)
759         CASE_RETURN_STRING(WLC_GET_BSS_WPA_RSN)
760         CASE_RETURN_STRING(WLC_GET_BSS_WPA2_RSN)
761         CASE_RETURN_STRING(WLC_GET_BSS_BCN_TS)
762         CASE_RETURN_STRING(WLC_GET_INT_DISASSOC)
763         CASE_RETURN_STRING(WLC_SET_NUM_PEERS)
764         CASE_RETURN_STRING(WLC_GET_NUM_BSS)
765         CASE_RETURN_STRING(WLC_GET_WSEC_PMK)
766         CASE_RETURN_STRING(WLC_GET_RANDOM_BYTES)
767         CASE_RETURN_STRING(WLC_LAST)
768         default:
769             return "Unknown Command";
770     }
771 }
772 
773 #endif /* WPRINT_ENABLE_WHD_DEBUG */
774 
whd_convert_security_type_to_string(whd_security_t security,char * out_str,uint16_t out_str_len)775 void whd_convert_security_type_to_string(whd_security_t security, char *out_str, uint16_t out_str_len)
776 {
777     if (security == WHD_SECURITY_OPEN)
778     {
779         strncat(out_str, " Open", out_str_len);
780     }
781     if (security & WEP_ENABLED)
782     {
783         strncat(out_str, " WEP", out_str_len);
784     }
785     if (security & WPA3_SECURITY)
786     {
787         strncat(out_str, " WPA3", out_str_len);
788     }
789     if (security & WPA2_SECURITY)
790     {
791         strncat(out_str, " WPA2", out_str_len);
792     }
793     if (security & WPA_SECURITY)
794     {
795         strncat(out_str, " WPA", out_str_len);
796     }
797     if (security & AES_ENABLED)
798     {
799         strncat(out_str, " AES", out_str_len);
800     }
801     if (security & TKIP_ENABLED)
802     {
803         strncat(out_str, " TKIP", out_str_len);
804     }
805     if (security & SHARED_ENABLED)
806     {
807         strncat(out_str, " SHARED", out_str_len);
808     }
809     if (security & ENTERPRISE_ENABLED)
810     {
811         strncat(out_str, " Enterprise", out_str_len);
812     }
813     if (security & WPS_ENABLED)
814     {
815         strncat(out_str, " WPS", out_str_len);
816     }
817     if (security & FBT_ENABLED)
818     {
819         strncat(out_str, " FBT", out_str_len);
820     }
821     if (security & IBSS_ENABLED)
822     {
823         strncat(out_str, " IBSS", out_str_len);
824     }
825     if (security == WHD_SECURITY_UNKNOWN)
826     {
827         strncat(out_str, " Unknown", out_str_len);
828     }
829     if (!(security & ENTERPRISE_ENABLED) && (security != WHD_SECURITY_OPEN) &&
830         (security != WHD_SECURITY_UNKNOWN) )
831     {
832         strncat(out_str, " PSK", out_str_len);
833     }
834 }
835 
836 /*!
837  ******************************************************************************
838  * Prints partial details of a scan result on a single line
839  *
840  * @param[in] record  A pointer to the whd_scan_result_t record
841  *
842  */
843 
whd_print_scan_result(whd_scan_result_t * record)844 void whd_print_scan_result(whd_scan_result_t *record)
845 {
846     const char *str = NULL;
847     char sec_type_string[40] = { 0 };
848 
849     switch (record->bss_type)
850     {
851         case WHD_BSS_TYPE_ADHOC:
852             str = "Adhoc";
853             break;
854 
855         case WHD_BSS_TYPE_INFRASTRUCTURE:
856             str = "Infra";
857             break;
858 
859         case WHD_BSS_TYPE_ANY:
860             str = "Any";
861             break;
862 
863         case WHD_BSS_TYPE_MESH:
864         case WHD_BSS_TYPE_UNKNOWN:
865             str = "Unknown";
866             break;
867 
868         default:
869             str = "?";
870             break;
871     }
872 
873     UNUSED_PARAMETER(str);
874     WPRINT_MACRO( ("%5s ", str) );
875     WPRINT_MACRO( ("%02X:%02X:%02X:%02X:%02X:%02X ", record->BSSID.octet[0], record->BSSID.octet[1],
876                    record->BSSID.octet[2], record->BSSID.octet[3], record->BSSID.octet[4],
877                    record->BSSID.octet[5]) );
878 
879     if (record->flags & WHD_SCAN_RESULT_FLAG_RSSI_OFF_CHANNEL)
880     {
881         WPRINT_MACRO( ("OFF ") );
882     }
883     else
884     {
885         WPRINT_MACRO( ("%d ", record->signal_strength) );
886     }
887 
888     if (record->max_data_rate < 100000)
889     {
890         WPRINT_MACRO( (" %.1f ", (double)(record->max_data_rate / 1000.0) ) );
891     }
892     else
893     {
894         WPRINT_MACRO( ("%.1f ", (double)(record->max_data_rate / 1000.0) ) );
895     }
896     WPRINT_MACRO( (" %3d  ", record->channel) );
897 
898     whd_convert_security_type_to_string(record->security, sec_type_string, (sizeof(sec_type_string) - 1) );
899 
900     WPRINT_MACRO( ("%-20s ", sec_type_string) );
901     WPRINT_MACRO( (" %-32s ", record->SSID.value) );
902 
903     if (record->ccode[0] != '\0')
904     {
905         WPRINT_MACRO( ("%c%c    ", record->ccode[0], record->ccode[1]) );
906     }
907     else
908     {
909         WPRINT_MACRO( ("      ") );
910     }
911 
912     if (record->flags & WHD_SCAN_RESULT_FLAG_BEACON)
913     {
914         WPRINT_MACRO( (" %-15s", " BEACON") );
915     }
916     else
917     {
918         WPRINT_MACRO( (" %-15s", " PROBE ") );
919     }
920     WPRINT_MACRO( ("\n") );
921 }
922 
whd_hexdump(uint8_t * data,uint32_t data_len)923 void whd_hexdump(uint8_t *data, uint32_t data_len)
924 {
925     uint32_t i;
926     uint8_t buff[17] = {0};
927 
928     UNUSED_PARAMETER(buff);
929     for (i = 0; i < data_len; i++)
930     {
931         if ( (i % 16) == 0 )
932         {
933             if (i != 0)
934             {
935                 WPRINT_MACRO( ("  %s\n", buff) );
936             }
937             WPRINT_MACRO( ("%04" PRIx32 " ", i) );
938         }
939         WPRINT_MACRO( (" %02x", data[i]) );
940 
941         if ( (data[i] < 0x20) || (data[i] > 0x7e) )
942         {
943             buff[i % 16] = '.';
944         }
945         else
946         {
947             buff[i % 16] = data[i];
948         }
949         buff[(i % 16) + 1] = '\0';
950     }
951     while ( (i % 16) != 0 )
952     {
953         WPRINT_MACRO( ("   ") );
954         i++;
955     }
956     WPRINT_MACRO( ("  %s\n", buff) );
957 }
958 
whd_ioctl_info_to_string(uint32_t cmd,char * ioctl_str,uint16_t ioctl_str_len)959 void whd_ioctl_info_to_string(uint32_t cmd, char *ioctl_str, uint16_t ioctl_str_len)
960 {
961     if (cmd == 2)
962     {
963         strncpy(ioctl_str, "WLC_UP", ioctl_str_len);
964     }
965     else if (cmd == 20)
966     {
967         strncpy(ioctl_str, "WLC_SET_INFRA", ioctl_str_len);
968     }
969     else if (cmd == 22)
970     {
971         strncpy(ioctl_str, "WLC_SET_AUTH", ioctl_str_len);
972     }
973     else if (cmd == 26)
974     {
975         strncpy(ioctl_str, "WLC_SET_SSID", ioctl_str_len);
976     }
977     else if (cmd == 52)
978     {
979         strncpy(ioctl_str, "WLC_DISASSOC", ioctl_str_len);
980     }
981     else if (cmd == 55)
982     {
983         strncpy(ioctl_str, "WLC_SET_ROAM_TRIGGER", ioctl_str_len);
984     }
985     else if (cmd == 57)
986     {
987         strncpy(ioctl_str, "WLC_SET_ROAM_DELTA", ioctl_str_len);
988     }
989     else if (cmd == 59)
990     {
991         strncpy(ioctl_str, "WLC_SET_ROAM_SCAN_PERIOD", ioctl_str_len);
992     }
993     else if (cmd == 110)
994     {
995         strncpy(ioctl_str, "WLC_SET_GMODE", ioctl_str_len);
996     }
997     else if (cmd == 116)
998     {
999         strncpy(ioctl_str, "WLC_SET_SCANSUPPRESS", ioctl_str_len);
1000     }
1001     else if (cmd == 134)
1002     {
1003         strncpy(ioctl_str, "WLC_SET_WSEC", ioctl_str_len);
1004     }
1005     else if (cmd == 165)
1006     {
1007         strncpy(ioctl_str, "WLC_SET_WPA_AUTH", ioctl_str_len);
1008     }
1009     else if (cmd == 268)
1010     {
1011         strncpy(ioctl_str, "WLC_SET_WSEC_PMK", ioctl_str_len);
1012     }
1013     ioctl_str[ioctl_str_len] = '\0';
1014 }
1015 
whd_event_info_to_string(uint32_t cmd,uint16_t flag,uint32_t reason,char * ioctl_str,uint16_t ioctl_str_len)1016 void whd_event_info_to_string(uint32_t cmd, uint16_t flag, uint32_t reason, char *ioctl_str, uint16_t ioctl_str_len)
1017 {
1018     if (cmd == 0)
1019     {
1020         strncpy(ioctl_str, "WLC_E_SET_SSID", ioctl_str_len);
1021     }
1022     else if (cmd == 3)
1023     {
1024         strncpy(ioctl_str, "WLC_E_AUTH    ", ioctl_str_len);
1025     }
1026     else if (cmd == 16)
1027     {
1028         strncpy(ioctl_str, "WLC_E_LINK    ", ioctl_str_len);
1029     }
1030     else if (cmd == 46)
1031     {
1032         strncpy(ioctl_str, "WLC_E_PSK_SUP ", ioctl_str_len);
1033     }
1034     else if (cmd == 54)
1035     {
1036         strncpy(ioctl_str, "WLC_E_IF      ", ioctl_str_len);
1037     }
1038     else if (cmd == 69)
1039     {
1040         strncpy(ioctl_str, "WLC_E_ESCAN_RESULT", ioctl_str_len);
1041     }
1042 
1043     if (flag == 0)
1044     {
1045         strncat(ioctl_str, "  WLC_E_STATUS_SUCCESS",  ioctl_str_len);
1046     }
1047     if (flag == 8)
1048     {
1049         strncat(ioctl_str, "  WLC_E_STATUS_PARTIAL",  ioctl_str_len);
1050     }
1051     else if (flag == 262)
1052     {
1053         strncat(ioctl_str, "  WLC_SUP_KEYED       ",  ioctl_str_len);
1054     }
1055 
1056     if (reason == 0)
1057     {
1058         strncat(ioctl_str, "    WLC_E_REASON_INITIAL_ASSOC",  ioctl_str_len);
1059     }
1060     else if (reason == 512)
1061     {
1062         strncat(ioctl_str, "    WLC_E_SUP_OTHER",  ioctl_str_len);
1063     }
1064     ioctl_str[ioctl_str_len] = '\0';
1065 }
1066 
whd_str_to_ip(const char * ip4addr,size_t len,void * dest)1067 bool whd_str_to_ip(const char *ip4addr, size_t len, void *dest)
1068 {
1069     uint8_t *addr = dest;
1070 
1071     if (len > 16)   // Too long, not possible
1072     {
1073         return false;
1074     }
1075 
1076     uint8_t stringLength = 0, byteCount = 0;
1077 
1078     //Iterate over each component of the IP. The exit condition is in the middle of the loop
1079     while (true)
1080     {
1081 
1082         //No valid character (IPv4 addresses don't have implicit 0, that is x.y..z being read as x.y.0.z)
1083         if ( (stringLength == len) || (ip4addr[stringLength] < '0') || (ip4addr[stringLength] > '9') )
1084         {
1085             return false;
1086         }
1087 
1088         //For each component, we convert it to the raw value
1089         uint16_t byte = 0;
1090         while (stringLength < len && ip4addr[stringLength] >= '0' && ip4addr[stringLength] <= '9')
1091         {
1092             byte *= 10;
1093             byte += ip4addr[stringLength++] - '0';
1094 
1095             //We go over the maximum value for an IPv4 component
1096             if (byte > 0xff)
1097             {
1098                 return false;
1099             }
1100         }
1101 
1102         //Append the component
1103         addr[byteCount++] = (uint8_t)byte;
1104 
1105         //If we're at the end, we leave the loop. It's the only way to reach the `true` output
1106         if (byteCount == 4)
1107         {
1108             break;
1109         }
1110 
1111         //If the next character is invalid, we return false
1112         if ( (stringLength == len) || (ip4addr[stringLength++] != '.') )
1113         {
1114             return false;
1115         }
1116     }
1117 
1118     return stringLength == len || ip4addr[stringLength] == '\0';
1119 }
1120 
whd_ipv4_itoa(char * string,uint8_t byte)1121 static void whd_ipv4_itoa(char *string, uint8_t byte)
1122 {
1123     char *baseString = string;
1124 
1125     //Write the digits to the buffer from the least significant to the most
1126     //  This is the incorrect order but we will swap later
1127     do
1128     {
1129         *string++ = '0' + byte % 10;
1130         byte /= 10;
1131     } while (byte);
1132 
1133     //We put the final \0, then go back one step on the last digit for the swap
1134     *string-- = '\0';
1135 
1136     //We now swap the digits
1137     while (baseString < string)
1138     {
1139         uint8_t tmp = *string;
1140         *string-- = *baseString;
1141         *baseString++ = tmp;
1142     }
1143 }
1144 
whd_ip4_to_string(const void * ip4addr,char * p)1145 uint8_t whd_ip4_to_string(const void *ip4addr, char *p)
1146 {
1147     uint8_t outputPos = 0;
1148     const uint8_t *byteArray = ip4addr;
1149 
1150     for (uint8_t component = 0; component < 4; ++component)
1151     {
1152         //Convert the byte to string
1153         whd_ipv4_itoa(&p[outputPos], byteArray[component]);
1154 
1155         //Move outputPos to the end of the string
1156         while (p[outputPos] != '\0')
1157         {
1158             outputPos += 1;
1159         }
1160 
1161         //Append a dot if this is not the last digit
1162         if (component < 3)
1163         {
1164             p[outputPos++] = '.';
1165         }
1166     }
1167     // Return length of generated string, excluding the terminating null character
1168     return outputPos;
1169 }
1170