driver_common.c revision 6c0da2bb83f6915d8260912362692d1a742e057b
11f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/* 21f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Common driver-related functions 31f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi> 41f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 71f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 81f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 91f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "includes.h" 101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "utils/common.h" 111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "driver.h" 121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpa_scan_results_free(struct wpa_scan_results *res) 141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t i; 161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (res == NULL) 181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; i < res->num; i++) 211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(res->res[i]); 221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(res->res); 231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(res); 241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst char * event_to_string(enum wpa_event_type event) 281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define E2S(n) case EVENT_ ## n: return #n 301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (event) { 311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(ASSOC); 321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(DISASSOC); 331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(MICHAEL_MIC_FAILURE); 341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(SCAN_RESULTS); 351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(ASSOCINFO); 361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(INTERFACE_STATUS); 371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(PMKID_CANDIDATE); 381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(STKSTART); 391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(TDLS); 401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(FT_RESPONSE); 411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(IBSS_RSN_START); 421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(AUTH); 431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(DEAUTH); 441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(ASSOC_REJECT); 451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(AUTH_TIMED_OUT); 461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(ASSOC_TIMED_OUT); 471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(WPS_BUTTON_PUSHED); 481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(TX_STATUS); 491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(RX_FROM_UNKNOWN); 501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(RX_MGMT); 511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(REMAIN_ON_CHANNEL); 521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(CANCEL_REMAIN_ON_CHANNEL); 531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(RX_PROBE_REQ); 541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(NEW_STA); 551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(EAPOL_RX); 561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(SIGNAL_CHANGE); 571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(INTERFACE_ENABLED); 581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(INTERFACE_DISABLED); 591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(CHANNEL_LIST_CHANGED); 601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(INTERFACE_UNAVAILABLE); 611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(BEST_CHANNEL); 621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(UNPROT_DEAUTH); 631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(UNPROT_DISASSOC); 641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(STATION_LOW_ACK); 651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(IBSS_PEER_LOST); 661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(DRIVER_GTK_REKEY); 671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(SCHED_SCAN_STOPPED); 681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(DRIVER_CLIENT_POLL_OK); 691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt E2S(EAPOL_TX_STATUS); 7004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt E2S(CH_SWITCH); 7161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt E2S(WNM); 72f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt E2S(CONNECT_FAILED_REASON); 73ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt E2S(DFS_RADAR_DETECTED); 74ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt E2S(DFS_CAC_FINISHED); 75ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt E2S(DFS_CAC_ABORTED); 76ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt E2S(DFS_NOP_FINISHED); 77b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt E2S(SURVEY); 78fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt E2S(SCAN_STARTED); 79cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt E2S(AVOID_FREQUENCIES); 806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt E2S(NEW_PEER_CANDIDATE); 816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt E2S(ACS_CHANNEL_SELECTED); 821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return "UNKNOWN"; 851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#undef E2S 861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 87661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 88661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 89661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidtconst char * channel_width_to_string(enum chan_width width) 90661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt{ 91661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt switch (width) { 92661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt case CHAN_WIDTH_20_NOHT: 93661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return "20 MHz (no HT)"; 94661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt case CHAN_WIDTH_20: 95661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return "20 MHz"; 96661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt case CHAN_WIDTH_40: 97661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return "40 MHz"; 98661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt case CHAN_WIDTH_80: 99661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return "80 MHz"; 100661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt case CHAN_WIDTH_80P80: 101661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return "80+80 MHz"; 102661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt case CHAN_WIDTH_160: 103661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return "160 MHz"; 104661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt default: 105661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return "unknown"; 106661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 107661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt} 1086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtint ht_supported(const struct hostapd_hw_modes *mode) 1116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 1126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!(mode->flags & HOSTAPD_MODE_FLAG_HT_INFO_KNOWN)) { 1136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 1146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * The driver did not indicate whether it supports HT. Assume 1156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * it does to avoid connection issues. 1166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 1176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 1; 1186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 1196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 1216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * IEEE Std 802.11n-2009 20.1.1: 1226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * An HT non-AP STA shall support all EQM rates for one spatial stream. 1236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 1246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return mode->mcs_set[0] == 0xff; 1256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 1266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtint vht_supported(const struct hostapd_hw_modes *mode) 1296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 1306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!(mode->flags & HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN)) { 1316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 1326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * The driver did not indicate whether it supports VHT. Assume 1336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * it does to avoid connection issues. 1346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 1356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 1; 1366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 1376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 1396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * A VHT non-AP STA shall support MCS 0-7 for one spatial stream. 1406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * TODO: Verify if this complies with the standard 1416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 1426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return (mode->vht_mcs_set[0] & 0x3) != 3; 1436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 1446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic int wpa_check_wowlan_trigger(const char *start, const char *trigger, 1476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int capa_trigger, u8 *param_trigger) 1486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 1496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_strcmp(start, trigger) != 0) 1506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 0; 1516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!capa_trigger) 1526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 0; 1536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt *param_trigger = 1; 1556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 1; 1566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 1576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstruct wowlan_triggers * 1606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtwpa_get_wowlan_triggers(const char *wowlan_triggers, 1616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const struct wpa_driver_capa *capa) 1626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 1636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wowlan_triggers *triggers; 1646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt char *start, *end, *buf; 1656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int last; 1666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!wowlan_triggers) 1686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 1696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt buf = os_strdup(wowlan_triggers); 1716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (buf == NULL) 1726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 1736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt triggers = os_zalloc(sizeof(*triggers)); 1756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (triggers == NULL) 1766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto out; 1776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#define CHECK_TRIGGER(trigger) \ 1796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_check_wowlan_trigger(start, #trigger, \ 1806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt capa->wowlan_triggers.trigger, \ 1816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt &triggers->trigger) 1826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt start = buf; 1846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt while (*start != '\0') { 1856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt while (isblank(*start)) 1866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt start++; 1876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (*start == '\0') 1886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 1896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt end = start; 1906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt while (!isblank(*end) && *end != '\0') 1916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt end++; 1926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt last = *end == '\0'; 1936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt *end = '\0'; 1946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!CHECK_TRIGGER(any) && 1966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !CHECK_TRIGGER(disconnect) && 1976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !CHECK_TRIGGER(magic_pkt) && 1986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !CHECK_TRIGGER(gtk_rekey_failure) && 1996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !CHECK_TRIGGER(eap_identity_req) && 2006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !CHECK_TRIGGER(four_way_handshake) && 2016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !CHECK_TRIGGER(rfkill_release)) { 2026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 2036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "Unknown/unsupported wowlan trigger '%s'", 2046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt start); 2056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_free(triggers); 2066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt triggers = NULL; 2076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto out; 2086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 2096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (last) 2116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 2126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt start = end + 1; 2136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 2146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#undef CHECK_TRIGGER 2156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtout: 2176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_free(buf); 2186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return triggers; 2196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 220