LCOV - code coverage report
Current view: top level - src/fst - fst.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1443382998 Lines: 90 97 92.8 %
Date: 2015-09-27 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /*
       2             :  * FST module implementation
       3             :  * Copyright (c) 2014, Qualcomm Atheros, Inc.
       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 "utils/eloop.h"
      13             : #include "fst/fst.h"
      14             : #include "fst/fst_internal.h"
      15             : #include "fst/fst_defs.h"
      16             : #include "fst/fst_ctrl_iface.h"
      17             : 
      18             : struct dl_list fst_global_ctrls_list;
      19             : 
      20             : 
      21         996 : static void fst_ctrl_iface_notify_peer_state_change(struct fst_iface *iface,
      22             :                                                     Boolean connected,
      23             :                                                     const u8 *peer_addr)
      24             : {
      25             :         union fst_event_extra extra;
      26             : 
      27         996 :         extra.peer_state.connected = connected;
      28         996 :         os_strlcpy(extra.peer_state.ifname, fst_iface_get_name(iface),
      29             :                    sizeof(extra.peer_state.ifname));
      30         996 :         os_memcpy(extra.peer_state.addr, peer_addr, ETH_ALEN);
      31             : 
      32         996 :         foreach_fst_ctrl_call(on_event, EVENT_PEER_STATE_CHANGED,
      33             :                               iface, NULL, &extra);
      34         996 : }
      35             : 
      36             : 
      37         547 : struct fst_iface * fst_attach(const char *ifname, const u8 *own_addr,
      38             :                               const struct fst_wpa_obj *iface_obj,
      39             :                               const struct fst_iface_cfg *cfg)
      40             : {
      41             :         struct fst_group *g;
      42         547 :         struct fst_group *group = NULL;
      43         547 :         struct fst_iface *iface = NULL;
      44         547 :         Boolean new_group = FALSE;
      45             : 
      46             :         WPA_ASSERT(ifname != NULL);
      47             :         WPA_ASSERT(iface_obj != NULL);
      48             :         WPA_ASSERT(cfg != NULL);
      49             : 
      50         563 :         foreach_fst_group(g) {
      51         282 :                 if (os_strcmp(cfg->group_id, fst_group_get_id(g)) == 0) {
      52         266 :                         group = g;
      53         266 :                         break;
      54             :                 }
      55             :         }
      56             : 
      57         547 :         if (!group) {
      58         281 :                 group = fst_group_create(cfg->group_id);
      59         281 :                 if (!group) {
      60           1 :                         fst_printf(MSG_ERROR, "%s: FST group cannot be created",
      61             :                                    cfg->group_id);
      62           1 :                         return NULL;
      63             :                 }
      64         280 :                 new_group = TRUE;
      65             :         }
      66             : 
      67         546 :         iface = fst_iface_create(group, ifname, own_addr, iface_obj, cfg);
      68         546 :         if (!iface) {
      69           2 :                 fst_printf_group(group, MSG_ERROR, "cannot create iface for %s",
      70             :                                  ifname);
      71           2 :                 if (new_group)
      72           1 :                         fst_group_delete(group);
      73           2 :                 return NULL;
      74             :         }
      75             : 
      76         544 :         fst_group_attach_iface(group, iface);
      77         544 :         fst_group_update_ie(group);
      78             : 
      79         544 :         foreach_fst_ctrl_call(on_iface_added, iface);
      80             : 
      81         544 :         fst_printf_iface(iface, MSG_DEBUG,
      82             :                          "iface attached to group %s (prio=%d, llt=%d)",
      83             :                          cfg->group_id, cfg->priority, cfg->llt);
      84             : 
      85         544 :         return iface;
      86             : }
      87             : 
      88             : 
      89         544 : void fst_detach(struct fst_iface *iface)
      90             : {
      91         544 :         struct fst_group *group = fst_iface_get_group(iface);
      92             : 
      93         544 :         fst_printf_iface(iface, MSG_DEBUG, "iface detached from group %s",
      94             :                          fst_group_get_id(group));
      95         544 :         fst_session_global_on_iface_detached(iface);
      96         544 :         foreach_fst_ctrl_call(on_iface_removed, iface);
      97         544 :         fst_group_detach_iface(group, iface);
      98         544 :         fst_iface_delete(iface);
      99         544 :         fst_group_update_ie(group);
     100         544 :         fst_group_delete_if_empty(group);
     101         544 : }
     102             : 
     103             : 
     104          74 : int fst_global_init(void)
     105             : {
     106          74 :         dl_list_init(&fst_global_groups_list);
     107          74 :         dl_list_init(&fst_global_ctrls_list);
     108          74 :         fst_session_global_init();
     109          74 :         return 0;
     110             : }
     111             : 
     112             : 
     113          74 : void fst_global_deinit(void)
     114             : {
     115             :         struct fst_group *group;
     116             :         struct fst_ctrl_handle *h;
     117             : 
     118          74 :         fst_session_global_deinit();
     119         149 :         while ((group = fst_first_group()) != NULL)
     120           1 :                 fst_group_delete(group);
     121         222 :         while ((h = dl_list_first(&fst_global_ctrls_list,
     122             :                                   struct fst_ctrl_handle,
     123             :                                   global_ctrls_lentry)))
     124          74 :                 fst_global_del_ctrl(h);
     125          74 : }
     126             : 
     127             : 
     128          74 : struct fst_ctrl_handle * fst_global_add_ctrl(const struct fst_ctrl *ctrl)
     129             : {
     130             :         struct fst_ctrl_handle *h;
     131             : 
     132          74 :         if (!ctrl)
     133           0 :                 return NULL;
     134             : 
     135          74 :         h = os_zalloc(sizeof(*h));
     136          74 :         if (!h)
     137           0 :                 return NULL;
     138             : 
     139          74 :         if (ctrl->init && ctrl->init()) {
     140           0 :                 os_free(h);
     141           0 :                 return NULL;
     142             :         }
     143             : 
     144          74 :         h->ctrl = *ctrl;
     145          74 :         dl_list_add_tail(&fst_global_ctrls_list, &h->global_ctrls_lentry);
     146             : 
     147          74 :         return h;
     148             : }
     149             : 
     150             : 
     151          74 : void fst_global_del_ctrl(struct fst_ctrl_handle *h)
     152             : {
     153          74 :         dl_list_del(&h->global_ctrls_lentry);
     154          74 :         if (h->ctrl.deinit)
     155           0 :                 h->ctrl.deinit();
     156          74 :         os_free(h);
     157          74 : }
     158             : 
     159             : 
     160         941 : void fst_rx_action(struct fst_iface *iface, const struct ieee80211_mgmt *mgmt,
     161             :                    size_t len)
     162             : {
     163         941 :         if (fst_iface_is_connected(iface, mgmt->sa))
     164         940 :                 fst_session_on_action_rx(iface, mgmt, len);
     165             :         else
     166           6 :                 wpa_printf(MSG_DEBUG,
     167             :                            "FST: Ignore FST Action frame - no FST connection with "
     168           6 :                            MACSTR, MAC2STR(mgmt->sa));
     169         941 : }
     170             : 
     171             : 
     172         499 : void fst_notify_peer_connected(struct fst_iface *iface, const u8 *addr)
     173             : {
     174         499 :         if (is_zero_ether_addr(addr))
     175         499 :                 return;
     176             : 
     177             : #ifndef HOSTAPD
     178         252 :         fst_group_update_ie(fst_iface_get_group(iface));
     179             : #endif /* HOSTAPD */
     180             : 
     181         499 :         fst_printf_iface(iface, MSG_DEBUG, MACSTR " became connected",
     182             :                          MAC2STR(addr));
     183             : 
     184         499 :         fst_ctrl_iface_notify_peer_state_change(iface, TRUE, addr);
     185             : }
     186             : 
     187             : 
     188         497 : void fst_notify_peer_disconnected(struct fst_iface *iface, const u8 *addr)
     189             : {
     190         497 :         if (is_zero_ether_addr(addr))
     191         497 :                 return;
     192             : 
     193             : #ifndef HOSTAPD
     194         251 :         fst_group_update_ie(fst_iface_get_group(iface));
     195             : #endif /* HOSTAPD */
     196             : 
     197         497 :         fst_printf_iface(iface, MSG_DEBUG, MACSTR " became disconnected",
     198             :                          MAC2STR(addr));
     199             : 
     200         497 :         fst_ctrl_iface_notify_peer_state_change(iface, FALSE, addr);
     201             : }
     202             : 
     203             : 
     204         247 : Boolean fst_are_ifaces_aggregated(struct fst_iface *iface1,
     205             :                                   struct fst_iface *iface2)
     206             : {
     207         247 :         return fst_iface_get_group(iface1) == fst_iface_get_group(iface2);
     208             : }
     209             : 
     210             : 
     211        7142 : enum mb_band_id fst_hw_mode_to_band(enum hostapd_hw_mode mode)
     212             : {
     213        7142 :         switch (mode) {
     214             :         case HOSTAPD_MODE_IEEE80211B:
     215             :         case HOSTAPD_MODE_IEEE80211G:
     216        4619 :                 return MB_BAND_ID_WIFI_2_4GHZ;
     217             :         case HOSTAPD_MODE_IEEE80211A:
     218        2523 :                 return MB_BAND_ID_WIFI_5GHZ;
     219             :         case HOSTAPD_MODE_IEEE80211AD:
     220           0 :                 return MB_BAND_ID_WIFI_60GHZ;
     221             :         default:
     222             :                 WPA_ASSERT(0);
     223           0 :                 return MB_BAND_ID_WIFI_2_4GHZ;
     224             :         }
     225             : }

Generated by: LCOV version 1.10