1e5b75505Sopenharmony_ci/* 2e5b75505Sopenharmony_ci * Common driver-related functions 3e5b75505Sopenharmony_ci * Copyright (c) 2003-2017, Jouni Malinen <j@w1.fi> 4e5b75505Sopenharmony_ci * 5e5b75505Sopenharmony_ci * This software may be distributed under the terms of the BSD license. 6e5b75505Sopenharmony_ci * See README for more details. 7e5b75505Sopenharmony_ci */ 8e5b75505Sopenharmony_ci 9e5b75505Sopenharmony_ci#include "includes.h" 10e5b75505Sopenharmony_ci#include "utils/common.h" 11e5b75505Sopenharmony_ci#include "driver.h" 12e5b75505Sopenharmony_ci 13e5b75505Sopenharmony_civoid wpa_scan_results_free(struct wpa_scan_results *res) 14e5b75505Sopenharmony_ci{ 15e5b75505Sopenharmony_ci size_t i; 16e5b75505Sopenharmony_ci 17e5b75505Sopenharmony_ci if (res == NULL) 18e5b75505Sopenharmony_ci return; 19e5b75505Sopenharmony_ci 20e5b75505Sopenharmony_ci for (i = 0; i < res->num; i++) 21e5b75505Sopenharmony_ci os_free(res->res[i]); 22e5b75505Sopenharmony_ci os_free(res->res); 23e5b75505Sopenharmony_ci os_free(res); 24e5b75505Sopenharmony_ci} 25e5b75505Sopenharmony_ci 26e5b75505Sopenharmony_ci 27e5b75505Sopenharmony_ciconst char * event_to_string(enum wpa_event_type event) 28e5b75505Sopenharmony_ci{ 29e5b75505Sopenharmony_ci#define E2S(n) case EVENT_ ## n: return #n 30e5b75505Sopenharmony_ci switch (event) { 31e5b75505Sopenharmony_ci E2S(ASSOC); 32e5b75505Sopenharmony_ci E2S(DISASSOC); 33e5b75505Sopenharmony_ci E2S(MICHAEL_MIC_FAILURE); 34e5b75505Sopenharmony_ci E2S(SCAN_RESULTS); 35e5b75505Sopenharmony_ci E2S(ASSOCINFO); 36e5b75505Sopenharmony_ci E2S(INTERFACE_STATUS); 37e5b75505Sopenharmony_ci E2S(PMKID_CANDIDATE); 38e5b75505Sopenharmony_ci E2S(TDLS); 39e5b75505Sopenharmony_ci E2S(FT_RESPONSE); 40e5b75505Sopenharmony_ci E2S(IBSS_RSN_START); 41e5b75505Sopenharmony_ci E2S(AUTH); 42e5b75505Sopenharmony_ci E2S(DEAUTH); 43e5b75505Sopenharmony_ci E2S(ASSOC_REJECT); 44e5b75505Sopenharmony_ci E2S(AUTH_TIMED_OUT); 45e5b75505Sopenharmony_ci E2S(ASSOC_TIMED_OUT); 46e5b75505Sopenharmony_ci E2S(WPS_BUTTON_PUSHED); 47e5b75505Sopenharmony_ci E2S(TX_STATUS); 48e5b75505Sopenharmony_ci E2S(RX_FROM_UNKNOWN); 49e5b75505Sopenharmony_ci E2S(RX_MGMT); 50e5b75505Sopenharmony_ci E2S(REMAIN_ON_CHANNEL); 51e5b75505Sopenharmony_ci E2S(CANCEL_REMAIN_ON_CHANNEL); 52e5b75505Sopenharmony_ci E2S(RX_PROBE_REQ); 53e5b75505Sopenharmony_ci E2S(NEW_STA); 54e5b75505Sopenharmony_ci E2S(EAPOL_RX); 55e5b75505Sopenharmony_ci E2S(SIGNAL_CHANGE); 56e5b75505Sopenharmony_ci E2S(INTERFACE_ENABLED); 57e5b75505Sopenharmony_ci E2S(INTERFACE_DISABLED); 58e5b75505Sopenharmony_ci E2S(CHANNEL_LIST_CHANGED); 59e5b75505Sopenharmony_ci E2S(INTERFACE_UNAVAILABLE); 60e5b75505Sopenharmony_ci E2S(BEST_CHANNEL); 61e5b75505Sopenharmony_ci E2S(UNPROT_DEAUTH); 62e5b75505Sopenharmony_ci E2S(UNPROT_DISASSOC); 63e5b75505Sopenharmony_ci E2S(STATION_LOW_ACK); 64e5b75505Sopenharmony_ci E2S(IBSS_PEER_LOST); 65e5b75505Sopenharmony_ci E2S(DRIVER_GTK_REKEY); 66e5b75505Sopenharmony_ci E2S(SCHED_SCAN_STOPPED); 67e5b75505Sopenharmony_ci E2S(DRIVER_CLIENT_POLL_OK); 68e5b75505Sopenharmony_ci E2S(EAPOL_TX_STATUS); 69e5b75505Sopenharmony_ci E2S(CH_SWITCH); 70e5b75505Sopenharmony_ci E2S(CH_SWITCH_STARTED); 71e5b75505Sopenharmony_ci E2S(WNM); 72e5b75505Sopenharmony_ci E2S(CONNECT_FAILED_REASON); 73e5b75505Sopenharmony_ci E2S(DFS_RADAR_DETECTED); 74e5b75505Sopenharmony_ci E2S(DFS_CAC_FINISHED); 75e5b75505Sopenharmony_ci E2S(DFS_CAC_ABORTED); 76e5b75505Sopenharmony_ci E2S(DFS_NOP_FINISHED); 77e5b75505Sopenharmony_ci E2S(SURVEY); 78e5b75505Sopenharmony_ci E2S(SCAN_STARTED); 79e5b75505Sopenharmony_ci E2S(AVOID_FREQUENCIES); 80e5b75505Sopenharmony_ci E2S(NEW_PEER_CANDIDATE); 81e5b75505Sopenharmony_ci E2S(ACS_CHANNEL_SELECTED); 82e5b75505Sopenharmony_ci E2S(DFS_CAC_STARTED); 83e5b75505Sopenharmony_ci E2S(P2P_LO_STOP); 84e5b75505Sopenharmony_ci E2S(BEACON_LOSS); 85e5b75505Sopenharmony_ci E2S(DFS_PRE_CAC_EXPIRED); 86e5b75505Sopenharmony_ci E2S(EXTERNAL_AUTH); 87e5b75505Sopenharmony_ci E2S(PORT_AUTHORIZED); 88e5b75505Sopenharmony_ci E2S(STATION_OPMODE_CHANGED); 89e5b75505Sopenharmony_ci E2S(INTERFACE_MAC_CHANGED); 90e5b75505Sopenharmony_ci E2S(WDS_STA_INTERFACE_STATUS); 91e5b75505Sopenharmony_ci E2S(UPDATE_DH); 92e5b75505Sopenharmony_ci } 93e5b75505Sopenharmony_ci 94e5b75505Sopenharmony_ci return "UNKNOWN"; 95e5b75505Sopenharmony_ci#undef E2S 96e5b75505Sopenharmony_ci} 97e5b75505Sopenharmony_ci 98e5b75505Sopenharmony_ci 99e5b75505Sopenharmony_ciconst char * channel_width_to_string(enum chan_width width) 100e5b75505Sopenharmony_ci{ 101e5b75505Sopenharmony_ci switch (width) { 102e5b75505Sopenharmony_ci case CHAN_WIDTH_20_NOHT: 103e5b75505Sopenharmony_ci return "20 MHz (no HT)"; 104e5b75505Sopenharmony_ci case CHAN_WIDTH_20: 105e5b75505Sopenharmony_ci return "20 MHz"; 106e5b75505Sopenharmony_ci case CHAN_WIDTH_40: 107e5b75505Sopenharmony_ci return "40 MHz"; 108e5b75505Sopenharmony_ci case CHAN_WIDTH_80: 109e5b75505Sopenharmony_ci return "80 MHz"; 110e5b75505Sopenharmony_ci case CHAN_WIDTH_80P80: 111e5b75505Sopenharmony_ci return "80+80 MHz"; 112e5b75505Sopenharmony_ci case CHAN_WIDTH_160: 113e5b75505Sopenharmony_ci return "160 MHz"; 114e5b75505Sopenharmony_ci default: 115e5b75505Sopenharmony_ci return "unknown"; 116e5b75505Sopenharmony_ci } 117e5b75505Sopenharmony_ci} 118e5b75505Sopenharmony_ci 119e5b75505Sopenharmony_ci 120e5b75505Sopenharmony_ciint channel_width_to_int(enum chan_width width) 121e5b75505Sopenharmony_ci{ 122e5b75505Sopenharmony_ci switch (width) { 123e5b75505Sopenharmony_ci case CHAN_WIDTH_20_NOHT: 124e5b75505Sopenharmony_ci case CHAN_WIDTH_20: 125e5b75505Sopenharmony_ci return 20; 126e5b75505Sopenharmony_ci case CHAN_WIDTH_40: 127e5b75505Sopenharmony_ci return 40; 128e5b75505Sopenharmony_ci case CHAN_WIDTH_80: 129e5b75505Sopenharmony_ci return 80; 130e5b75505Sopenharmony_ci case CHAN_WIDTH_80P80: 131e5b75505Sopenharmony_ci case CHAN_WIDTH_160: 132e5b75505Sopenharmony_ci return 160; 133e5b75505Sopenharmony_ci default: 134e5b75505Sopenharmony_ci return 0; 135e5b75505Sopenharmony_ci } 136e5b75505Sopenharmony_ci} 137e5b75505Sopenharmony_ci 138e5b75505Sopenharmony_ci 139e5b75505Sopenharmony_ciint ht_supported(const struct hostapd_hw_modes *mode) 140e5b75505Sopenharmony_ci{ 141e5b75505Sopenharmony_ci if (!(mode->flags & HOSTAPD_MODE_FLAG_HT_INFO_KNOWN)) { 142e5b75505Sopenharmony_ci /* 143e5b75505Sopenharmony_ci * The driver did not indicate whether it supports HT. Assume 144e5b75505Sopenharmony_ci * it does to avoid connection issues. 145e5b75505Sopenharmony_ci */ 146e5b75505Sopenharmony_ci return 1; 147e5b75505Sopenharmony_ci } 148e5b75505Sopenharmony_ci 149e5b75505Sopenharmony_ci /* 150e5b75505Sopenharmony_ci * IEEE Std 802.11n-2009 20.1.1: 151e5b75505Sopenharmony_ci * An HT non-AP STA shall support all EQM rates for one spatial stream. 152e5b75505Sopenharmony_ci */ 153e5b75505Sopenharmony_ci return mode->mcs_set[0] == 0xff; 154e5b75505Sopenharmony_ci} 155e5b75505Sopenharmony_ci 156e5b75505Sopenharmony_ci 157e5b75505Sopenharmony_ciint vht_supported(const struct hostapd_hw_modes *mode) 158e5b75505Sopenharmony_ci{ 159e5b75505Sopenharmony_ci if (!(mode->flags & HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN)) { 160e5b75505Sopenharmony_ci /* 161e5b75505Sopenharmony_ci * The driver did not indicate whether it supports VHT. Assume 162e5b75505Sopenharmony_ci * it does to avoid connection issues. 163e5b75505Sopenharmony_ci */ 164e5b75505Sopenharmony_ci return 1; 165e5b75505Sopenharmony_ci } 166e5b75505Sopenharmony_ci 167e5b75505Sopenharmony_ci /* 168e5b75505Sopenharmony_ci * A VHT non-AP STA shall support MCS 0-7 for one spatial stream. 169e5b75505Sopenharmony_ci * TODO: Verify if this complies with the standard 170e5b75505Sopenharmony_ci */ 171e5b75505Sopenharmony_ci return (mode->vht_mcs_set[0] & 0x3) != 3; 172e5b75505Sopenharmony_ci} 173e5b75505Sopenharmony_ci 174e5b75505Sopenharmony_ci 175e5b75505Sopenharmony_cistatic int wpa_check_wowlan_trigger(const char *start, const char *trigger, 176e5b75505Sopenharmony_ci int capa_trigger, u8 *param_trigger) 177e5b75505Sopenharmony_ci{ 178e5b75505Sopenharmony_ci if (os_strcmp(start, trigger) != 0) 179e5b75505Sopenharmony_ci return 0; 180e5b75505Sopenharmony_ci if (!capa_trigger) 181e5b75505Sopenharmony_ci return 0; 182e5b75505Sopenharmony_ci 183e5b75505Sopenharmony_ci *param_trigger = 1; 184e5b75505Sopenharmony_ci return 1; 185e5b75505Sopenharmony_ci} 186e5b75505Sopenharmony_ci 187e5b75505Sopenharmony_ci 188e5b75505Sopenharmony_cistruct wowlan_triggers * 189e5b75505Sopenharmony_ciwpa_get_wowlan_triggers(const char *wowlan_triggers, 190e5b75505Sopenharmony_ci const struct wpa_driver_capa *capa) 191e5b75505Sopenharmony_ci{ 192e5b75505Sopenharmony_ci struct wowlan_triggers *triggers; 193e5b75505Sopenharmony_ci char *start, *end, *buf; 194e5b75505Sopenharmony_ci int last; 195e5b75505Sopenharmony_ci 196e5b75505Sopenharmony_ci if (!wowlan_triggers) 197e5b75505Sopenharmony_ci return NULL; 198e5b75505Sopenharmony_ci 199e5b75505Sopenharmony_ci buf = os_strdup(wowlan_triggers); 200e5b75505Sopenharmony_ci if (buf == NULL) 201e5b75505Sopenharmony_ci return NULL; 202e5b75505Sopenharmony_ci 203e5b75505Sopenharmony_ci triggers = os_zalloc(sizeof(*triggers)); 204e5b75505Sopenharmony_ci if (triggers == NULL) 205e5b75505Sopenharmony_ci goto out; 206e5b75505Sopenharmony_ci 207e5b75505Sopenharmony_ci#define CHECK_TRIGGER(trigger) \ 208e5b75505Sopenharmony_ci wpa_check_wowlan_trigger(start, #trigger, \ 209e5b75505Sopenharmony_ci capa->wowlan_triggers.trigger, \ 210e5b75505Sopenharmony_ci &triggers->trigger) 211e5b75505Sopenharmony_ci 212e5b75505Sopenharmony_ci start = buf; 213e5b75505Sopenharmony_ci while (*start != '\0') { 214e5b75505Sopenharmony_ci while (isblank((unsigned char) *start)) 215e5b75505Sopenharmony_ci start++; 216e5b75505Sopenharmony_ci if (*start == '\0') 217e5b75505Sopenharmony_ci break; 218e5b75505Sopenharmony_ci end = start; 219e5b75505Sopenharmony_ci while (!isblank((unsigned char) *end) && *end != '\0') 220e5b75505Sopenharmony_ci end++; 221e5b75505Sopenharmony_ci last = *end == '\0'; 222e5b75505Sopenharmony_ci *end = '\0'; 223e5b75505Sopenharmony_ci 224e5b75505Sopenharmony_ci if (!CHECK_TRIGGER(any) && 225e5b75505Sopenharmony_ci !CHECK_TRIGGER(disconnect) && 226e5b75505Sopenharmony_ci !CHECK_TRIGGER(magic_pkt) && 227e5b75505Sopenharmony_ci !CHECK_TRIGGER(gtk_rekey_failure) && 228e5b75505Sopenharmony_ci !CHECK_TRIGGER(eap_identity_req) && 229e5b75505Sopenharmony_ci !CHECK_TRIGGER(four_way_handshake) && 230e5b75505Sopenharmony_ci !CHECK_TRIGGER(rfkill_release)) { 231e5b75505Sopenharmony_ci wpa_printf(MSG_DEBUG, 232e5b75505Sopenharmony_ci "Unknown/unsupported wowlan trigger '%s'", 233e5b75505Sopenharmony_ci start); 234e5b75505Sopenharmony_ci os_free(triggers); 235e5b75505Sopenharmony_ci triggers = NULL; 236e5b75505Sopenharmony_ci goto out; 237e5b75505Sopenharmony_ci } 238e5b75505Sopenharmony_ci 239e5b75505Sopenharmony_ci if (last) 240e5b75505Sopenharmony_ci break; 241e5b75505Sopenharmony_ci start = end + 1; 242e5b75505Sopenharmony_ci } 243e5b75505Sopenharmony_ci#undef CHECK_TRIGGER 244e5b75505Sopenharmony_ci 245e5b75505Sopenharmony_ciout: 246e5b75505Sopenharmony_ci os_free(buf); 247e5b75505Sopenharmony_ci return triggers; 248e5b75505Sopenharmony_ci} 249e5b75505Sopenharmony_ci 250e5b75505Sopenharmony_ci 251e5b75505Sopenharmony_ciconst char * driver_flag_to_string(u64 flag) 252e5b75505Sopenharmony_ci{ 253e5b75505Sopenharmony_ci#define DF2S(x) case WPA_DRIVER_FLAGS_ ## x: return #x 254e5b75505Sopenharmony_ci switch (flag) { 255e5b75505Sopenharmony_ci DF2S(DRIVER_IE); 256e5b75505Sopenharmony_ci DF2S(SET_KEYS_AFTER_ASSOC); 257e5b75505Sopenharmony_ci DF2S(DFS_OFFLOAD); 258e5b75505Sopenharmony_ci DF2S(4WAY_HANDSHAKE_PSK); 259e5b75505Sopenharmony_ci DF2S(4WAY_HANDSHAKE_8021X); 260e5b75505Sopenharmony_ci DF2S(WIRED); 261e5b75505Sopenharmony_ci DF2S(SME); 262e5b75505Sopenharmony_ci DF2S(AP); 263e5b75505Sopenharmony_ci DF2S(SET_KEYS_AFTER_ASSOC_DONE); 264e5b75505Sopenharmony_ci DF2S(HT_2040_COEX); 265e5b75505Sopenharmony_ci DF2S(P2P_CONCURRENT); 266e5b75505Sopenharmony_ci DF2S(P2P_DEDICATED_INTERFACE); 267e5b75505Sopenharmony_ci DF2S(P2P_CAPABLE); 268e5b75505Sopenharmony_ci DF2S(AP_TEARDOWN_SUPPORT); 269e5b75505Sopenharmony_ci DF2S(P2P_MGMT_AND_NON_P2P); 270e5b75505Sopenharmony_ci DF2S(SANE_ERROR_CODES); 271e5b75505Sopenharmony_ci DF2S(OFFCHANNEL_TX); 272e5b75505Sopenharmony_ci DF2S(EAPOL_TX_STATUS); 273e5b75505Sopenharmony_ci DF2S(DEAUTH_TX_STATUS); 274e5b75505Sopenharmony_ci DF2S(BSS_SELECTION); 275e5b75505Sopenharmony_ci DF2S(TDLS_SUPPORT); 276e5b75505Sopenharmony_ci DF2S(TDLS_EXTERNAL_SETUP); 277e5b75505Sopenharmony_ci DF2S(PROBE_RESP_OFFLOAD); 278e5b75505Sopenharmony_ci DF2S(AP_UAPSD); 279e5b75505Sopenharmony_ci DF2S(INACTIVITY_TIMER); 280e5b75505Sopenharmony_ci DF2S(AP_MLME); 281e5b75505Sopenharmony_ci DF2S(SAE); 282e5b75505Sopenharmony_ci DF2S(OBSS_SCAN); 283e5b75505Sopenharmony_ci DF2S(IBSS); 284e5b75505Sopenharmony_ci DF2S(RADAR); 285e5b75505Sopenharmony_ci DF2S(DEDICATED_P2P_DEVICE); 286e5b75505Sopenharmony_ci DF2S(QOS_MAPPING); 287e5b75505Sopenharmony_ci DF2S(AP_CSA); 288e5b75505Sopenharmony_ci DF2S(MESH); 289e5b75505Sopenharmony_ci DF2S(ACS_OFFLOAD); 290e5b75505Sopenharmony_ci DF2S(KEY_MGMT_OFFLOAD); 291e5b75505Sopenharmony_ci DF2S(TDLS_CHANNEL_SWITCH); 292e5b75505Sopenharmony_ci DF2S(HT_IBSS); 293e5b75505Sopenharmony_ci DF2S(VHT_IBSS); 294e5b75505Sopenharmony_ci DF2S(SUPPORT_HW_MODE_ANY); 295e5b75505Sopenharmony_ci DF2S(OFFCHANNEL_SIMULTANEOUS); 296e5b75505Sopenharmony_ci DF2S(FULL_AP_CLIENT_STATE); 297e5b75505Sopenharmony_ci DF2S(P2P_LISTEN_OFFLOAD); 298e5b75505Sopenharmony_ci DF2S(SUPPORT_FILS); 299e5b75505Sopenharmony_ci DF2S(BEACON_RATE_LEGACY); 300e5b75505Sopenharmony_ci DF2S(BEACON_RATE_HT); 301e5b75505Sopenharmony_ci DF2S(BEACON_RATE_VHT); 302e5b75505Sopenharmony_ci DF2S(MGMT_TX_RANDOM_TA); 303e5b75505Sopenharmony_ci DF2S(MGMT_TX_RANDOM_TA_CONNECTED); 304e5b75505Sopenharmony_ci DF2S(SCHED_SCAN_RELATIVE_RSSI); 305e5b75505Sopenharmony_ci DF2S(HE_CAPABILITIES); 306e5b75505Sopenharmony_ci DF2S(FILS_SK_OFFLOAD); 307e5b75505Sopenharmony_ci DF2S(OCE_STA); 308e5b75505Sopenharmony_ci DF2S(OCE_AP); 309e5b75505Sopenharmony_ci DF2S(OCE_STA_CFON); 310e5b75505Sopenharmony_ci DF2S(MFP_OPTIONAL); 311e5b75505Sopenharmony_ci } 312e5b75505Sopenharmony_ci return "UNKNOWN"; 313e5b75505Sopenharmony_ci#undef DF2S 314e5b75505Sopenharmony_ci} 315