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