451a27b1ad
Add a configuration option in hostapd.conf and in neighbor report that sets an AP as stationary. To enable this option on the current AP set the config option stationary_ap to 1. To set a neighbor entry to be marked as stationary add the word stat to the SET_NEIGHBOR command. This option tells hostapd to send LCI data even if it is older than requested by max age subelement in RRM request. Signed-off-by: David Spinadel <david.spinadel@intel.com>
136 lines
2.9 KiB
C
136 lines
2.9 KiB
C
/*
|
|
* hostapd / Neighboring APs DB
|
|
* Copyright(c) 2013 - 2016 Intel Mobile Communications GmbH.
|
|
* Copyright(c) 2011 - 2016 Intel Corporation. All rights reserved.
|
|
*
|
|
* This software may be distributed under the terms of the BSD license.
|
|
* See README for more details.
|
|
*/
|
|
|
|
#include "utils/includes.h"
|
|
|
|
#include "utils/common.h"
|
|
#include "hostapd.h"
|
|
#include "neighbor_db.h"
|
|
|
|
|
|
struct hostapd_neighbor_entry *
|
|
hostapd_neighbor_get(struct hostapd_data *hapd, const u8 *bssid,
|
|
const struct wpa_ssid_value *ssid)
|
|
{
|
|
struct hostapd_neighbor_entry *nr;
|
|
|
|
dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
|
|
list) {
|
|
if (os_memcmp(bssid, nr->bssid, ETH_ALEN) == 0 &&
|
|
(!ssid ||
|
|
(ssid->ssid_len == nr->ssid.ssid_len &&
|
|
os_memcmp(ssid->ssid, nr->ssid.ssid,
|
|
ssid->ssid_len) == 0)))
|
|
return nr;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
static void hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry *nr)
|
|
{
|
|
wpabuf_free(nr->nr);
|
|
nr->nr = NULL;
|
|
wpabuf_free(nr->lci);
|
|
nr->lci = NULL;
|
|
wpabuf_free(nr->civic);
|
|
nr->civic = NULL;
|
|
os_memset(nr->bssid, 0, sizeof(nr->bssid));
|
|
os_memset(&nr->ssid, 0, sizeof(nr->ssid));
|
|
nr->stationary = 0;
|
|
}
|
|
|
|
|
|
static struct hostapd_neighbor_entry *
|
|
hostapd_neighbor_add(struct hostapd_data *hapd)
|
|
{
|
|
struct hostapd_neighbor_entry *nr;
|
|
|
|
nr = os_zalloc(sizeof(struct hostapd_neighbor_entry));
|
|
if (!nr)
|
|
return NULL;
|
|
|
|
dl_list_add(&hapd->nr_db, &nr->list);
|
|
|
|
return nr;
|
|
}
|
|
|
|
|
|
int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
|
|
const struct wpa_ssid_value *ssid,
|
|
const struct wpabuf *nr, const struct wpabuf *lci,
|
|
const struct wpabuf *civic, int stationary)
|
|
{
|
|
struct hostapd_neighbor_entry *entry;
|
|
|
|
entry = hostapd_neighbor_get(hapd, bssid, ssid);
|
|
if (!entry)
|
|
entry = hostapd_neighbor_add(hapd);
|
|
if (!entry)
|
|
return -1;
|
|
|
|
hostapd_neighbor_clear_entry(entry);
|
|
|
|
os_memcpy(entry->bssid, bssid, ETH_ALEN);
|
|
os_memcpy(&entry->ssid, ssid, sizeof(entry->ssid));
|
|
|
|
entry->nr = wpabuf_dup(nr);
|
|
if (!entry->nr)
|
|
goto fail;
|
|
|
|
if (lci && wpabuf_len(lci)) {
|
|
entry->lci = wpabuf_dup(lci);
|
|
if (!entry->lci || os_get_time(&entry->lci_date))
|
|
goto fail;
|
|
}
|
|
|
|
if (civic && wpabuf_len(civic)) {
|
|
entry->civic = wpabuf_dup(civic);
|
|
if (!entry->civic)
|
|
goto fail;
|
|
}
|
|
|
|
entry->stationary = stationary;
|
|
|
|
return 0;
|
|
|
|
fail:
|
|
hostapd_neighbor_remove(hapd, bssid, ssid);
|
|
return -1;
|
|
}
|
|
|
|
|
|
int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
|
|
const struct wpa_ssid_value *ssid)
|
|
{
|
|
struct hostapd_neighbor_entry *nr;
|
|
|
|
nr = hostapd_neighbor_get(hapd, bssid, ssid);
|
|
if (!nr)
|
|
return -1;
|
|
|
|
hostapd_neighbor_clear_entry(nr);
|
|
dl_list_del(&nr->list);
|
|
os_free(nr);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void hostpad_free_neighbor_db(struct hostapd_data *hapd)
|
|
{
|
|
struct hostapd_neighbor_entry *nr, *prev;
|
|
|
|
dl_list_for_each_safe(nr, prev, &hapd->nr_db,
|
|
struct hostapd_neighbor_entry, list) {
|
|
hostapd_neighbor_clear_entry(nr);
|
|
dl_list_del(&nr->list);
|
|
os_free(nr);
|
|
}
|
|
}
|