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

Generated by: LCOV version 1.10