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

Generated by: LCOV version 1.10