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

Generated by: LCOV version 1.10