LCOV - code coverage report
Current view: top level - src/ap - ap_drv_ops.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1422976643 Lines: 308 405 76.0 %
Date: 2015-02-03 Functions: 41 46 89.1 %

          Line data    Source code
       1             : /*
       2             :  * hostapd - Driver operations
       3             :  * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "utils/includes.h"
      10             : 
      11             : #include "utils/common.h"
      12             : #include "common/ieee802_11_defs.h"
      13             : #include "wps/wps.h"
      14             : #include "p2p/p2p.h"
      15             : #include "hostapd.h"
      16             : #include "ieee802_11.h"
      17             : #include "sta_info.h"
      18             : #include "ap_config.h"
      19             : #include "p2p_hostapd.h"
      20             : #include "hs20.h"
      21             : #include "ap_drv_ops.h"
      22             : 
      23             : 
      24       18154 : u32 hostapd_sta_flags_to_drv(u32 flags)
      25             : {
      26       18154 :         int res = 0;
      27       18154 :         if (flags & WLAN_STA_AUTHORIZED)
      28        2918 :                 res |= WPA_STA_AUTHORIZED;
      29       18154 :         if (flags & WLAN_STA_WMM)
      30       18117 :                 res |= WPA_STA_WMM;
      31       18154 :         if (flags & WLAN_STA_SHORT_PREAMBLE)
      32       17994 :                 res |= WPA_STA_SHORT_PREAMBLE;
      33       18154 :         if (flags & WLAN_STA_MFP)
      34         370 :                 res |= WPA_STA_MFP;
      35       18154 :         return res;
      36             : }
      37             : 
      38             : 
      39        2742 : int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
      40             :                                struct wpabuf **beacon_ret,
      41             :                                struct wpabuf **proberesp_ret,
      42             :                                struct wpabuf **assocresp_ret)
      43             : {
      44        2742 :         struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL;
      45             :         u8 buf[200], *pos;
      46             : 
      47        2742 :         *beacon_ret = *proberesp_ret = *assocresp_ret = NULL;
      48             : 
      49        2742 :         pos = buf;
      50        2742 :         pos = hostapd_eid_time_adv(hapd, pos);
      51        2742 :         if (pos != buf) {
      52           6 :                 if (wpabuf_resize(&beacon, pos - buf) != 0)
      53           0 :                         goto fail;
      54           6 :                 wpabuf_put_data(beacon, buf, pos - buf);
      55             :         }
      56        2742 :         pos = hostapd_eid_time_zone(hapd, pos);
      57        2742 :         if (pos != buf) {
      58           6 :                 if (wpabuf_resize(&proberesp, pos - buf) != 0)
      59           0 :                         goto fail;
      60           6 :                 wpabuf_put_data(proberesp, buf, pos - buf);
      61             :         }
      62             : 
      63        2742 :         pos = buf;
      64        2742 :         pos = hostapd_eid_ext_capab(hapd, pos);
      65        2742 :         if (pos != buf) {
      66        2742 :                 if (wpabuf_resize(&assocresp, pos - buf) != 0)
      67           0 :                         goto fail;
      68        2742 :                 wpabuf_put_data(assocresp, buf, pos - buf);
      69             :         }
      70        2742 :         pos = hostapd_eid_interworking(hapd, pos);
      71        2742 :         pos = hostapd_eid_adv_proto(hapd, pos);
      72        2742 :         pos = hostapd_eid_roaming_consortium(hapd, pos);
      73        2742 :         if (pos != buf) {
      74        2742 :                 if (wpabuf_resize(&beacon, pos - buf) != 0)
      75           0 :                         goto fail;
      76        2742 :                 wpabuf_put_data(beacon, buf, pos - buf);
      77             : 
      78        2742 :                 if (wpabuf_resize(&proberesp, pos - buf) != 0)
      79           0 :                         goto fail;
      80        2742 :                 wpabuf_put_data(proberesp, buf, pos - buf);
      81             :         }
      82             : 
      83        2742 :         if (hapd->wps_beacon_ie) {
      84        1698 :                 if (wpabuf_resize(&beacon, wpabuf_len(hapd->wps_beacon_ie)) <
      85             :                     0)
      86           0 :                         goto fail;
      87        1698 :                 wpabuf_put_buf(beacon, hapd->wps_beacon_ie);
      88             :         }
      89             : 
      90        2742 :         if (hapd->wps_probe_resp_ie) {
      91        1698 :                 if (wpabuf_resize(&proberesp,
      92        1698 :                                   wpabuf_len(hapd->wps_probe_resp_ie)) < 0)
      93           0 :                         goto fail;
      94        1698 :                 wpabuf_put_buf(proberesp, hapd->wps_probe_resp_ie);
      95             :         }
      96             : 
      97             : #ifdef CONFIG_P2P
      98        1402 :         if (hapd->p2p_beacon_ie) {
      99        1376 :                 if (wpabuf_resize(&beacon, wpabuf_len(hapd->p2p_beacon_ie)) <
     100             :                     0)
     101           0 :                         goto fail;
     102        1376 :                 wpabuf_put_buf(beacon, hapd->p2p_beacon_ie);
     103             :         }
     104             : 
     105        1402 :         if (hapd->p2p_probe_resp_ie) {
     106        1376 :                 if (wpabuf_resize(&proberesp,
     107        1376 :                                   wpabuf_len(hapd->p2p_probe_resp_ie)) < 0)
     108           0 :                         goto fail;
     109        1376 :                 wpabuf_put_buf(proberesp, hapd->p2p_probe_resp_ie);
     110             :         }
     111             : #endif /* CONFIG_P2P */
     112             : 
     113             : #ifdef CONFIG_P2P_MANAGER
     114        1340 :         if (hapd->conf->p2p & P2P_MANAGE) {
     115           5 :                 if (wpabuf_resize(&beacon, 100) == 0) {
     116             :                         u8 *start, *p;
     117           5 :                         start = wpabuf_put(beacon, 0);
     118           5 :                         p = hostapd_eid_p2p_manage(hapd, start);
     119           5 :                         wpabuf_put(beacon, p - start);
     120             :                 }
     121             : 
     122           5 :                 if (wpabuf_resize(&proberesp, 100) == 0) {
     123             :                         u8 *start, *p;
     124           5 :                         start = wpabuf_put(proberesp, 0);
     125           5 :                         p = hostapd_eid_p2p_manage(hapd, start);
     126           5 :                         wpabuf_put(proberesp, p - start);
     127             :                 }
     128             :         }
     129             : #endif /* CONFIG_P2P_MANAGER */
     130             : 
     131             : #ifdef CONFIG_WPS
     132        2742 :         if (hapd->conf->wps_state) {
     133        1698 :                 struct wpabuf *a = wps_build_assoc_resp_ie();
     134        1698 :                 if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0)
     135        1698 :                         wpabuf_put_buf(assocresp, a);
     136        1698 :                 wpabuf_free(a);
     137             :         }
     138             : #endif /* CONFIG_WPS */
     139             : 
     140             : #ifdef CONFIG_P2P_MANAGER
     141        1340 :         if (hapd->conf->p2p & P2P_MANAGE) {
     142           5 :                 if (wpabuf_resize(&assocresp, 100) == 0) {
     143             :                         u8 *start, *p;
     144           5 :                         start = wpabuf_put(assocresp, 0);
     145           5 :                         p = hostapd_eid_p2p_manage(hapd, start);
     146           5 :                         wpabuf_put(assocresp, p - start);
     147             :                 }
     148             :         }
     149             : #endif /* CONFIG_P2P_MANAGER */
     150             : 
     151             : #ifdef CONFIG_WIFI_DISPLAY
     152        1402 :         if (hapd->p2p_group) {
     153             :                 struct wpabuf *a;
     154        1402 :                 a = p2p_group_assoc_resp_ie(hapd->p2p_group, P2P_SC_SUCCESS);
     155        1402 :                 if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0)
     156        1402 :                         wpabuf_put_buf(assocresp, a);
     157        1402 :                 wpabuf_free(a);
     158             :         }
     159             : #endif /* CONFIG_WIFI_DISPLAY */
     160             : 
     161             : #ifdef CONFIG_HS20
     162        2742 :         pos = buf;
     163        2742 :         pos = hostapd_eid_hs20_indication(hapd, pos);
     164        2742 :         if (pos != buf) {
     165         119 :                 if (wpabuf_resize(&beacon, pos - buf) != 0)
     166           0 :                         goto fail;
     167         119 :                 wpabuf_put_data(beacon, buf, pos - buf);
     168             : 
     169         119 :                 if (wpabuf_resize(&proberesp, pos - buf) != 0)
     170           0 :                         goto fail;
     171         119 :                 wpabuf_put_data(proberesp, buf, pos - buf);
     172             :         }
     173             : 
     174        2742 :         pos = hostapd_eid_osen(hapd, buf);
     175        2742 :         if (pos != buf) {
     176           1 :                 if (wpabuf_resize(&beacon, pos - buf) != 0)
     177           0 :                         goto fail;
     178           1 :                 wpabuf_put_data(beacon, buf, pos - buf);
     179             : 
     180           1 :                 if (wpabuf_resize(&proberesp, pos - buf) != 0)
     181           0 :                         goto fail;
     182           1 :                 wpabuf_put_data(proberesp, buf, pos - buf);
     183             :         }
     184             : #endif /* CONFIG_HS20 */
     185             : 
     186        2742 :         if (hapd->conf->vendor_elements) {
     187           1 :                 size_t add = wpabuf_len(hapd->conf->vendor_elements);
     188           1 :                 if (wpabuf_resize(&beacon, add) == 0)
     189           1 :                         wpabuf_put_buf(beacon, hapd->conf->vendor_elements);
     190           1 :                 if (wpabuf_resize(&proberesp, add) == 0)
     191           1 :                         wpabuf_put_buf(proberesp, hapd->conf->vendor_elements);
     192             :         }
     193             : 
     194        2742 :         *beacon_ret = beacon;
     195        2742 :         *proberesp_ret = proberesp;
     196        2742 :         *assocresp_ret = assocresp;
     197             : 
     198        2742 :         return 0;
     199             : 
     200             : fail:
     201           0 :         wpabuf_free(beacon);
     202           0 :         wpabuf_free(proberesp);
     203           0 :         wpabuf_free(assocresp);
     204           0 :         return -1;
     205             : }
     206             : 
     207             : 
     208        2742 : void hostapd_free_ap_extra_ies(struct hostapd_data *hapd,
     209             :                                struct wpabuf *beacon,
     210             :                                struct wpabuf *proberesp,
     211             :                                struct wpabuf *assocresp)
     212             : {
     213        2742 :         wpabuf_free(beacon);
     214        2742 :         wpabuf_free(proberesp);
     215        2742 :         wpabuf_free(assocresp);
     216        2742 : }
     217             : 
     218             : 
     219        2604 : int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
     220             : {
     221             :         struct wpabuf *beacon, *proberesp, *assocresp;
     222             :         int ret;
     223             : 
     224        2604 :         if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
     225        2604 :                 return 0;
     226             : 
     227           0 :         if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
     228             :             0)
     229           0 :                 return -1;
     230             : 
     231           0 :         ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
     232             :                                           assocresp);
     233             : 
     234           0 :         hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
     235             : 
     236           0 :         return ret;
     237             : }
     238             : 
     239             : 
     240        4066 : int hostapd_set_authorized(struct hostapd_data *hapd,
     241             :                            struct sta_info *sta, int authorized)
     242             : {
     243        4066 :         if (authorized) {
     244        1295 :                 return hostapd_sta_set_flags(hapd, sta->addr,
     245        1295 :                                              hostapd_sta_flags_to_drv(
     246             :                                                      sta->flags),
     247             :                                              WPA_STA_AUTHORIZED, ~0);
     248             :         }
     249             : 
     250        2771 :         return hostapd_sta_set_flags(hapd, sta->addr,
     251        2771 :                                      hostapd_sta_flags_to_drv(sta->flags),
     252             :                                      0, ~WPA_STA_AUTHORIZED);
     253             : }
     254             : 
     255             : 
     256        2461 : int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta)
     257             : {
     258             :         int set_flags, total_flags, flags_and, flags_or;
     259        2461 :         total_flags = hostapd_sta_flags_to_drv(sta->flags);
     260        2461 :         set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP;
     261        4588 :         if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
     262        2682 :              sta->auth_alg == WLAN_AUTH_FT) &&
     263         555 :             sta->flags & WLAN_STA_AUTHORIZED)
     264         553 :                 set_flags |= WPA_STA_AUTHORIZED;
     265        2461 :         flags_or = total_flags & set_flags;
     266        2461 :         flags_and = total_flags | ~set_flags;
     267        2461 :         return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
     268             :                                      flags_or, flags_and);
     269             : }
     270             : 
     271             : 
     272        1755 : int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
     273             :                               int enabled)
     274             : {
     275             :         struct wpa_bss_params params;
     276        1755 :         os_memset(&params, 0, sizeof(params));
     277        1755 :         params.ifname = ifname;
     278        1755 :         params.enabled = enabled;
     279        1755 :         if (enabled) {
     280         873 :                 params.wpa = hapd->conf->wpa;
     281         873 :                 params.ieee802_1x = hapd->conf->ieee802_1x;
     282         873 :                 params.wpa_group = hapd->conf->wpa_group;
     283        1746 :                 params.wpa_pairwise = hapd->conf->wpa_pairwise |
     284         873 :                         hapd->conf->rsn_pairwise;
     285         873 :                 params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
     286         873 :                 params.rsn_preauth = hapd->conf->rsn_preauth;
     287             : #ifdef CONFIG_IEEE80211W
     288         873 :                 params.ieee80211w = hapd->conf->ieee80211w;
     289             : #endif /* CONFIG_IEEE80211W */
     290             :         }
     291        1755 :         return hostapd_set_ieee8021x(hapd, &params);
     292             : }
     293             : 
     294             : 
     295          13 : int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
     296             : {
     297             :         char force_ifname[IFNAMSIZ];
     298             :         u8 if_addr[ETH_ALEN];
     299          13 :         return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr,
     300             :                               NULL, NULL, force_ifname, if_addr, NULL, 0);
     301             : }
     302             : 
     303             : 
     304          13 : int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname)
     305             : {
     306          13 :         return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
     307             : }
     308             : 
     309             : 
     310           2 : int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
     311             :                         const u8 *addr, int aid, int val)
     312             : {
     313           2 :         const char *bridge = NULL;
     314             : 
     315           2 :         if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
     316           0 :                 return -1;
     317           2 :         if (hapd->conf->wds_bridge[0])
     318           2 :                 bridge = hapd->conf->wds_bridge;
     319           0 :         else if (hapd->conf->bridge[0])
     320           0 :                 bridge = hapd->conf->bridge;
     321           2 :         return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
     322             :                                          bridge, ifname_wds);
     323             : }
     324             : 
     325             : 
     326         113 : int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
     327             :                          u16 auth_alg)
     328             : {
     329         113 :         if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL)
     330         113 :                 return 0;
     331           0 :         return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg);
     332             : }
     333             : 
     334             : 
     335           0 : int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
     336             :                      u16 seq, u16 status, const u8 *ie, size_t len)
     337             : {
     338           0 :         if (hapd->driver == NULL || hapd->driver->sta_auth == NULL)
     339           0 :                 return 0;
     340           0 :         return hapd->driver->sta_auth(hapd->drv_priv, hapd->own_addr, addr,
     341             :                                       seq, status, ie, len);
     342             : }
     343             : 
     344             : 
     345           0 : int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
     346             :                       int reassoc, u16 status, const u8 *ie, size_t len)
     347             : {
     348           0 :         if (hapd->driver == NULL || hapd->driver->sta_assoc == NULL)
     349           0 :                 return 0;
     350           0 :         return hapd->driver->sta_assoc(hapd->drv_priv, hapd->own_addr, addr,
     351             :                                        reassoc, status, ie, len);
     352             : }
     353             : 
     354             : 
     355        2461 : int hostapd_sta_add(struct hostapd_data *hapd,
     356             :                     const u8 *addr, u16 aid, u16 capability,
     357             :                     const u8 *supp_rates, size_t supp_rates_len,
     358             :                     u16 listen_interval,
     359             :                     const struct ieee80211_ht_capabilities *ht_capab,
     360             :                     const struct ieee80211_vht_capabilities *vht_capab,
     361             :                     u32 flags, u8 qosinfo, u8 vht_opmode)
     362             : {
     363             :         struct hostapd_sta_add_params params;
     364             : 
     365        2461 :         if (hapd->driver == NULL)
     366           0 :                 return 0;
     367        2461 :         if (hapd->driver->sta_add == NULL)
     368           0 :                 return 0;
     369             : 
     370        2461 :         os_memset(&params, 0, sizeof(params));
     371        2461 :         params.addr = addr;
     372        2461 :         params.aid = aid;
     373        2461 :         params.capability = capability;
     374        2461 :         params.supp_rates = supp_rates;
     375        2461 :         params.supp_rates_len = supp_rates_len;
     376        2461 :         params.listen_interval = listen_interval;
     377        2461 :         params.ht_capabilities = ht_capab;
     378        2461 :         params.vht_capabilities = vht_capab;
     379        2461 :         params.vht_opmode_enabled = !!(flags & WLAN_STA_VHT_OPMODE_ENABLED);
     380        2461 :         params.vht_opmode = vht_opmode;
     381        2461 :         params.flags = hostapd_sta_flags_to_drv(flags);
     382        2461 :         params.qosinfo = qosinfo;
     383        2461 :         return hapd->driver->sta_add(hapd->drv_priv, &params);
     384             : }
     385             : 
     386             : 
     387           0 : int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
     388             :                       u8 *tspec_ie, size_t tspec_ielen)
     389             : {
     390           0 :         if (hapd->driver == NULL || hapd->driver->add_tspec == NULL)
     391           0 :                 return 0;
     392           0 :         return hapd->driver->add_tspec(hapd->drv_priv, addr, tspec_ie,
     393             :                                        tspec_ielen);
     394             : }
     395             : 
     396             : 
     397        3091 : int hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
     398             : {
     399        3091 :         if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
     400        3091 :                 return 0;
     401           0 :         return hapd->driver->set_privacy(hapd->drv_priv, enabled);
     402             : }
     403             : 
     404             : 
     405        1741 : int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
     406             :                              size_t elem_len)
     407             : {
     408        1741 :         if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
     409        1741 :                 return 0;
     410           0 :         return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
     411             : }
     412             : 
     413             : 
     414        1252 : int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
     415             : {
     416        1252 :         if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
     417        1252 :                 return 0;
     418           0 :         return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
     419             : }
     420             : 
     421             : 
     422        1227 : int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
     423             : {
     424        1227 :         if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
     425        1227 :                 return 0;
     426           0 :         return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
     427             : }
     428             : 
     429             : 
     430          54 : int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
     431             :                    const char *ifname, const u8 *addr, void *bss_ctx,
     432             :                    void **drv_priv, char *force_ifname, u8 *if_addr,
     433             :                    const char *bridge, int use_existing)
     434             : {
     435          54 :         if (hapd->driver == NULL || hapd->driver->if_add == NULL)
     436           0 :                 return -1;
     437          54 :         return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
     438             :                                     bss_ctx, drv_priv, force_ifname, if_addr,
     439             :                                     bridge, use_existing);
     440             : }
     441             : 
     442             : 
     443          54 : int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
     444             :                       const char *ifname)
     445             : {
     446         108 :         if (hapd->driver == NULL || hapd->drv_priv == NULL ||
     447          54 :             hapd->driver->if_remove == NULL)
     448           0 :                 return -1;
     449          54 :         return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
     450             : }
     451             : 
     452             : 
     453        1755 : int hostapd_set_ieee8021x(struct hostapd_data *hapd,
     454             :                           struct wpa_bss_params *params)
     455             : {
     456        1755 :         if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
     457        1755 :                 return 0;
     458           0 :         return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
     459             : }
     460             : 
     461             : 
     462        1588 : int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
     463             :                        const u8 *addr, int idx, u8 *seq)
     464             : {
     465        1588 :         if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
     466           0 :                 return 0;
     467        1588 :         return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
     468             :                                         seq);
     469             : }
     470             : 
     471             : 
     472        1097 : int hostapd_flush(struct hostapd_data *hapd)
     473             : {
     474        1097 :         if (hapd->driver == NULL || hapd->driver->flush == NULL)
     475           0 :                 return 0;
     476        1097 :         return hapd->driver->flush(hapd->drv_priv);
     477             : }
     478             : 
     479             : 
     480        3872 : int hostapd_set_freq_params(struct hostapd_freq_params *data,
     481             :                             enum hostapd_hw_mode mode,
     482             :                             int freq, int channel, int ht_enabled,
     483             :                             int vht_enabled, int sec_channel_offset,
     484             :                             int vht_oper_chwidth, int center_segment0,
     485             :                             int center_segment1, u32 vht_caps)
     486             : {
     487             :         int tmp;
     488             : 
     489        3872 :         os_memset(data, 0, sizeof(*data));
     490        3872 :         data->mode = mode;
     491        3872 :         data->freq = freq;
     492        3872 :         data->channel = channel;
     493        3872 :         data->ht_enabled = ht_enabled;
     494        3872 :         data->vht_enabled = vht_enabled;
     495        3872 :         data->sec_channel_offset = sec_channel_offset;
     496        3872 :         data->center_freq1 = freq + sec_channel_offset * 10;
     497        3872 :         data->center_freq2 = 0;
     498        3872 :         data->bandwidth = sec_channel_offset ? 40 : 20;
     499             : 
     500             :         /*
     501             :          * This validation code is probably misplaced, maybe it should be
     502             :          * in src/ap/hw_features.c and check the hardware support as well.
     503             :          */
     504        3872 :         if (data->vht_enabled) switch (vht_oper_chwidth) {
     505             :         case VHT_CHANWIDTH_USE_HT:
     506          90 :                 if (center_segment1)
     507           0 :                         return -1;
     508         173 :                 if (center_segment0 != 0 &&
     509         164 :                     5000 + center_segment0 * 5 != data->center_freq1 &&
     510          81 :                     2407 + center_segment0 * 5 != data->center_freq1)
     511           0 :                         return -1;
     512          90 :                 break;
     513             :         case VHT_CHANWIDTH_80P80MHZ:
     514           3 :                 if (!(vht_caps & VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)) {
     515           0 :                         wpa_printf(MSG_ERROR,
     516             :                                    "80+80 channel width is not supported!");
     517           0 :                         return -1;
     518             :                 }
     519           6 :                 if (center_segment1 == center_segment0 + 4 ||
     520           3 :                     center_segment1 == center_segment0 - 4)
     521           0 :                         return -1;
     522           3 :                 data->center_freq2 = 5000 + center_segment1 * 5;
     523             :                 /* fall through */
     524             :         case VHT_CHANWIDTH_80MHZ:
     525          15 :                 data->bandwidth = 80;
     526          15 :                 if (vht_oper_chwidth == 1 && center_segment1)
     527           0 :                         return -1;
     528          15 :                 if (vht_oper_chwidth == 3 && !center_segment1)
     529           0 :                         return -1;
     530          15 :                 if (!sec_channel_offset)
     531           0 :                         return -1;
     532             :                 /* primary 40 part must match the HT configuration */
     533          15 :                 tmp = (30 + freq - 5000 - center_segment0 * 5)/20;
     534          15 :                 tmp /= 2;
     535          30 :                 if (data->center_freq1 != 5000 +
     536          15 :                                          center_segment0 * 5 - 20 + 40 * tmp)
     537           0 :                         return -1;
     538          15 :                 data->center_freq1 = 5000 + center_segment0 * 5;
     539          15 :                 break;
     540             :         case VHT_CHANWIDTH_160MHZ:
     541           6 :                 data->bandwidth = 160;
     542           6 :                 if (!(vht_caps & (VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
     543             :                                   VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))) {
     544           0 :                         wpa_printf(MSG_ERROR,
     545             :                                    "160MHZ channel width is not supported!");
     546           0 :                         return -1;
     547             :                 }
     548           6 :                 if (center_segment1)
     549           0 :                         return -1;
     550           6 :                 if (!sec_channel_offset)
     551           0 :                         return -1;
     552             :                 /* primary 40 part must match the HT configuration */
     553           6 :                 tmp = (70 + freq - 5000 - center_segment0 * 5)/20;
     554           6 :                 tmp /= 2;
     555          12 :                 if (data->center_freq1 != 5000 +
     556           6 :                                          center_segment0 * 5 - 60 + 40 * tmp)
     557           0 :                         return -1;
     558           6 :                 data->center_freq1 = 5000 + center_segment0 * 5;
     559           6 :                 break;
     560             :         }
     561             : 
     562        3872 :         return 0;
     563             : }
     564             : 
     565             : 
     566        1172 : int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode,
     567             :                      int freq, int channel, int ht_enabled, int vht_enabled,
     568             :                      int sec_channel_offset, int vht_oper_chwidth,
     569             :                      int center_segment0, int center_segment1)
     570             : {
     571             :         struct hostapd_freq_params data;
     572             : 
     573        2344 :         if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
     574             :                                     vht_enabled, sec_channel_offset,
     575             :                                     vht_oper_chwidth,
     576             :                                     center_segment0, center_segment1,
     577        1172 :                                     hapd->iface->current_mode ?
     578        1172 :                                     hapd->iface->current_mode->vht_capab : 0))
     579           0 :                 return -1;
     580             : 
     581        1172 :         if (hapd->driver == NULL)
     582           0 :                 return 0;
     583        1172 :         if (hapd->driver->set_freq == NULL)
     584           0 :                 return 0;
     585        1172 :         return hapd->driver->set_freq(hapd->drv_priv, &data);
     586             : }
     587             : 
     588           1 : int hostapd_set_rts(struct hostapd_data *hapd, int rts)
     589             : {
     590           1 :         if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
     591           0 :                 return 0;
     592           1 :         return hapd->driver->set_rts(hapd->drv_priv, rts);
     593             : }
     594             : 
     595             : 
     596           3 : int hostapd_set_frag(struct hostapd_data *hapd, int frag)
     597             : {
     598           3 :         if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
     599           0 :                 return 0;
     600           3 :         return hapd->driver->set_frag(hapd->drv_priv, frag);
     601             : }
     602             : 
     603             : 
     604        6527 : int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
     605             :                           int total_flags, int flags_or, int flags_and)
     606             : {
     607        6527 :         if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
     608           0 :                 return 0;
     609        6527 :         return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
     610             :                                            flags_or, flags_and);
     611             : }
     612             : 
     613             : 
     614          40 : int hostapd_set_country(struct hostapd_data *hapd, const char *country)
     615             : {
     616          80 :         if (hapd->driver == NULL ||
     617          40 :             hapd->driver->set_country == NULL)
     618           0 :                 return 0;
     619          40 :         return hapd->driver->set_country(hapd->drv_priv, country);
     620             : }
     621             : 
     622             : 
     623        3864 : int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
     624             :                                 int cw_min, int cw_max, int burst_time)
     625             : {
     626        3864 :         if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
     627          40 :                 return 0;
     628        3824 :         return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
     629             :                                                  cw_min, cw_max, burst_time);
     630             : }
     631             : 
     632             : 
     633             : struct hostapd_hw_modes *
     634        1214 : hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
     635             :                             u16 *flags)
     636             : {
     637        2428 :         if (hapd->driver == NULL ||
     638        1214 :             hapd->driver->get_hw_feature_data == NULL)
     639           0 :                 return NULL;
     640        1214 :         return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
     641             :                                                  flags);
     642             : }
     643             : 
     644             : 
     645        1202 : int hostapd_driver_commit(struct hostapd_data *hapd)
     646             : {
     647        1202 :         if (hapd->driver == NULL || hapd->driver->commit == NULL)
     648        1202 :                 return 0;
     649           0 :         return hapd->driver->commit(hapd->drv_priv);
     650             : }
     651             : 
     652             : 
     653        8261 : int hostapd_drv_none(struct hostapd_data *hapd)
     654             : {
     655        8261 :         return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
     656             : }
     657             : 
     658             : 
     659          94 : int hostapd_driver_scan(struct hostapd_data *hapd,
     660             :                         struct wpa_driver_scan_params *params)
     661             : {
     662          94 :         if (hapd->driver && hapd->driver->scan2)
     663          94 :                 return hapd->driver->scan2(hapd->drv_priv, params);
     664           0 :         return -1;
     665             : }
     666             : 
     667             : 
     668          39 : struct wpa_scan_results * hostapd_driver_get_scan_results(
     669             :         struct hostapd_data *hapd)
     670             : {
     671          39 :         if (hapd->driver && hapd->driver->get_scan_results2)
     672          39 :                 return hapd->driver->get_scan_results2(hapd->drv_priv);
     673           0 :         return NULL;
     674             : }
     675             : 
     676             : 
     677           0 : int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
     678             :                            int duration)
     679             : {
     680           0 :         if (hapd->driver && hapd->driver->set_noa)
     681           0 :                 return hapd->driver->set_noa(hapd->drv_priv, count, start,
     682             :                                              duration);
     683           0 :         return -1;
     684             : }
     685             : 
     686             : 
     687       18634 : int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
     688             :                         enum wpa_alg alg, const u8 *addr,
     689             :                         int key_idx, int set_tx,
     690             :                         const u8 *seq, size_t seq_len,
     691             :                         const u8 *key, size_t key_len)
     692             : {
     693       18634 :         if (hapd->driver == NULL || hapd->driver->set_key == NULL)
     694          80 :                 return 0;
     695       18554 :         return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
     696             :                                      key_idx, set_tx, seq, seq_len, key,
     697             :                                      key_len);
     698             : }
     699             : 
     700             : 
     701        7748 : int hostapd_drv_send_mlme(struct hostapd_data *hapd,
     702             :                           const void *msg, size_t len, int noack)
     703             : {
     704        7748 :         if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
     705           0 :                 return 0;
     706        7748 :         return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack);
     707             : }
     708             : 
     709             : 
     710        2712 : int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
     711             :                            const u8 *addr, int reason)
     712             : {
     713        2712 :         if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL)
     714           0 :                 return 0;
     715        2712 :         return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
     716             :                                         reason);
     717             : }
     718             : 
     719             : 
     720           4 : int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
     721             :                              const u8 *addr, int reason)
     722             : {
     723           4 :         if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL)
     724           0 :                 return 0;
     725           4 :         return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
     726             :                                           reason);
     727             : }
     728             : 
     729             : 
     730          26 : int hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper,
     731             :                          const u8 *peer, u8 *buf, u16 *buf_len)
     732             : {
     733          26 :         if (hapd->driver == NULL || hapd->driver->wnm_oper == NULL)
     734          26 :                 return -1;
     735           0 :         return hapd->driver->wnm_oper(hapd->drv_priv, oper, peer, buf,
     736             :                                       buf_len);
     737             : }
     738             : 
     739             : 
     740         258 : int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
     741             :                             unsigned int wait, const u8 *dst, const u8 *data,
     742             :                             size_t len)
     743             : {
     744         258 :         if (hapd->driver == NULL || hapd->driver->send_action == NULL)
     745           0 :                 return 0;
     746         516 :         return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
     747         258 :                                          hapd->own_addr, hapd->own_addr, data,
     748             :                                          len, 0);
     749             : }
     750             : 
     751             : 
     752          12 : int hostapd_start_dfs_cac(struct hostapd_iface *iface,
     753             :                           enum hostapd_hw_mode mode, int freq,
     754             :                           int channel, int ht_enabled, int vht_enabled,
     755             :                           int sec_channel_offset, int vht_oper_chwidth,
     756             :                           int center_segment0, int center_segment1)
     757             : {
     758          12 :         struct hostapd_data *hapd = iface->bss[0];
     759             :         struct hostapd_freq_params data;
     760             :         int res;
     761             : 
     762          12 :         if (!hapd->driver || !hapd->driver->start_dfs_cac)
     763           0 :                 return 0;
     764             : 
     765          12 :         if (!iface->conf->ieee80211h) {
     766           0 :                 wpa_printf(MSG_ERROR, "Can't start DFS CAC, DFS functionality "
     767             :                            "is not enabled");
     768           0 :                 return -1;
     769             :         }
     770             : 
     771          12 :         if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
     772             :                                     vht_enabled, sec_channel_offset,
     773             :                                     vht_oper_chwidth, center_segment0,
     774             :                                     center_segment1,
     775          12 :                                     iface->current_mode->vht_capab)) {
     776           0 :                 wpa_printf(MSG_ERROR, "Can't set freq params");
     777           0 :                 return -1;
     778             :         }
     779             : 
     780          12 :         res = hapd->driver->start_dfs_cac(hapd->drv_priv, &data);
     781          12 :         if (!res) {
     782          11 :                 iface->cac_started = 1;
     783          11 :                 os_get_reltime(&iface->dfs_cac_start);
     784             :         }
     785             : 
     786          12 :         return res;
     787             : }
     788             : 
     789             : 
     790           3 : int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
     791             :                             const u8 *qos_map_set, u8 qos_map_set_len)
     792             : {
     793           3 :         if (hapd->driver == NULL || hapd->driver->set_qos_map == NULL)
     794           0 :                 return 0;
     795           3 :         return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
     796             :                                          qos_map_set_len);
     797             : }
     798             : 
     799             : 
     800           0 : int hostapd_drv_do_acs(struct hostapd_data *hapd)
     801             : {
     802             :         struct drv_acs_params params;
     803             : 
     804           0 :         if (hapd->driver == NULL || hapd->driver->do_acs == NULL)
     805           0 :                 return 0;
     806           0 :         os_memset(&params, 0, sizeof(params));
     807           0 :         params.hw_mode = hapd->iface->conf->hw_mode;
     808           0 :         params.ht_enabled = !!(hapd->iface->conf->ieee80211n);
     809           0 :         params.ht40_enabled = !!(hapd->iface->conf->ht_capab &
     810             :                                  HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET);
     811           0 :         return hapd->driver->do_acs(hapd->drv_priv, &params);
     812             : }

Generated by: LCOV version 1.10