Skip to content
This repository has been archived by the owner on Sep 7, 2020. It is now read-only.

[Task] Compute MediaType for wireless ifaces in Device Information TLV #1060

Merged
3 changes: 3 additions & 0 deletions agent/src/beerocks/slave/ap_manager_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1555,6 +1555,9 @@ void ap_manager_thread::handle_hostapd_attached()
notification->cs_params().bandwidth = uint8_t(
beerocks::utils::convert_bandwidth_to_enum(ap_wlan_hal->get_radio_info().bandwidth));

notification->params().frequency_band = ap_wlan_hal->get_radio_info().frequency_band;
notification->params().max_bandwidth = ap_wlan_hal->get_radio_info().max_bandwidth;

// Copy the channels supported by the AP
copy_radio_supported_channels(ap_wlan_hal, notification->params().supported_channels);

Expand Down
195 changes: 117 additions & 78 deletions agent/src/beerocks/slave/backhaul_manager/backhaul_manager_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
* move all these includes into a separate header because
* over time this list is going to get very long
*/
#include <tlvf/ieee_1905_1/eMessageType.h>
#include <tlvf/ieee_1905_1/s802_11SpecificInformation.h>
#include <tlvf/ieee_1905_1/tlv1905NeighborDevice.h>
#include <tlvf/ieee_1905_1/tlvAlMacAddressType.h>
Expand Down Expand Up @@ -83,71 +82,45 @@ namespace beerocks {
const char *backhaul_manager::s_arrStates[] = {FOREACH_STATE(GENERATE_STRING)};

/**
* @brief Gets media type group for given interface.
* IEEE Std 1905.1, Table 6-12—Media type (intfType)
*
* @param[in] interface_name Name of the local interface.
* @param[in, out] media_type_group The media type group of the connecting interface.
*
* @return True on success and false otherwise.
* Value and Description Frequency MaxBandwith Comments
* 0 IEEE 802.11b (2.4 GHz) 2.4 GHz 22 MHz Not supported
* 1 IEEE 802.11g (2.4 GHz) 2.4 GHz 20 MHz
* 2 IEEE 802.11a (5 GHz) 5 GHz 20 MHz
* 3 IEEE 802.11n (2.4 GHz) 2.4 GHz 40 MHz
* 4 IEEE 802.11n (5 GHz) 5 GHz 40 MHz
* 5 IEEE 802.11ac (5 GHz) 5 GHz 80 MHz
* 6 IEEE 802.11ad (60 GHz) 60 GHz 160 MHz Not supported
* 7 IEEE 802.11af (whitespace) Not supported
* 8 IEEE 802.11ax (2.4 GHz) 2.4 GHz 160 MHz Not included in Table 6-12—Media type (intfType), WiFi6 is specified to use 0x0108 in R2
* 8 IEEE 802.11ax (5 GHz) 5 GHz 160 MHz Not included in Table 6-12—Media type (intfType), WiFi6 is specified to use 0x0108 in R2
*/
static bool get_media_type_group(const std::string &interface_name,
ieee1905_1::eMediaTypeGroup &media_type_group)
{
// TODO: Currently, only Ethernet is supported
// When dealing with WiFi interfaces in task #792, use NL80211_CMD_GET_INTERFACE command to
// find out if media type group is WiFi
media_type_group = ieee1905_1::eMediaTypeGroup::IEEE_802_3;
static const std::vector<std::tuple<eFreqType, eWiFiBandwidth, ieee1905_1::eMediaType>>
table_6_12_media_type //
{
{eFreqType::FREQ_24G, eWiFiBandwidth::BANDWIDTH_20, //
ieee1905_1::eMediaType::IEEE_802_11G_2_4_GHZ},

return true;
}
{eFreqType::FREQ_5G, eWiFiBandwidth::BANDWIDTH_20, //
ieee1905_1::eMediaType::IEEE_802_11A_5_GHZ},

/**
* @brief Gets media type for given interface.
*
* The mechanism to use to obtain media type depends on the media type group:
* Ethernet, WiFi, MoCA, etc.
*
* @param[in] interface_name Name of the local interface.
* @param[in] media_type_group The media type group of the connecting interface.
* @param[in, out] media_type The underlying network technology of the connecting interface.
*
* @return True on success and false otherwise.
*/
static bool get_media_type(const std::string &interface_name,
ieee1905_1::eMediaTypeGroup media_type_group,
ieee1905_1::eMediaType &media_type)
{
bool result = false;
{eFreqType::FREQ_24G, eWiFiBandwidth::BANDWIDTH_40, //
ieee1905_1::eMediaType::IEEE_802_11N_2_4_GHZ},

if (ieee1905_1::eMediaTypeGroup::IEEE_802_3 == media_type_group) {
uint32_t speed;
if (network_utils::linux_iface_get_speed(interface_name, speed)) {
if (SPEED_100 == speed) {
media_type = ieee1905_1::eMediaType::IEEE_802_3U_FAST_ETHERNET;
} else if (SPEED_1000 <= speed) {
media_type = ieee1905_1::eMediaType::IEEE_802_3AB_GIGABIT_ETHERNET;
} else {
media_type = ieee1905_1::eMediaType::UNKNONWN_MEDIA;
}
{eFreqType::FREQ_5G, eWiFiBandwidth::BANDWIDTH_40, //
ieee1905_1::eMediaType::IEEE_802_11N_5_GHZ},

result = true;
}
} else if (ieee1905_1::eMediaTypeGroup::IEEE_802_11 == media_type_group) {
// TODO: Not supported yet
LOG(ERROR) << "IEEE_802_11 media is not supported yet";
} else if (ieee1905_1::eMediaTypeGroup::IEEE_1901 == media_type_group) {
// TODO: Not supported yet
LOG(ERROR) << "IEEE_1901 media is not supported yet";
} else if (ieee1905_1::eMediaTypeGroup::MoCA == media_type_group) {
// TODO: Not supported yet
LOG(ERROR) << "MoCA media is not supported yet";
} else {
media_type = ieee1905_1::eMediaType::UNKNONWN_MEDIA;
result = true;
}
{eFreqType::FREQ_5G, eWiFiBandwidth::BANDWIDTH_80, //
ieee1905_1::eMediaType::IEEE_802_11AC_5_GHZ},

return result;
}
{eFreqType::FREQ_24G, eWiFiBandwidth::BANDWIDTH_160, //
ieee1905_1::eMediaType::IEEE_802_11AX},

{eFreqType::FREQ_5G, eWiFiBandwidth::BANDWIDTH_160, //
ieee1905_1::eMediaType::IEEE_802_11AX},

};

/**
* @brief Adds link metrics to response message.
Expand Down Expand Up @@ -1781,6 +1754,12 @@ bool backhaul_manager::handle_slave_backhaul_message(std::shared_ptr<SSlaveSocke
return false;
}

auto radio_info = m_radio_info_map[request->iface_mac()];

radio_info.interface_name = request->ap_iface();
radio_info.frequency_band = request->frequency_band();
radio_info.max_bandwidth = request->max_bandwidth();

std::string mac = network_utils::mac_to_string(request->iface_mac());

auto tuple_supported_channels = request->supported_channels_list(0);
Expand All @@ -1792,7 +1771,7 @@ bool backhaul_manager::handle_slave_backhaul_message(std::shared_ptr<SSlaveSocke
auto channels = &std::get<1>(tuple_supported_channels);

std::copy_n(channels, beerocks::message::SUPPORTED_CHANNELS_LENGTH,
m_radio_info_map[request->iface_mac()].supported_channels.begin());
radio_info.supported_channels.begin());

soc->radio_mac = mac;
soc->freq_type = (request->iface_is_5ghz() ? beerocks::eFreqType::FREQ_5G
Expand Down Expand Up @@ -2274,14 +2253,12 @@ bool backhaul_manager::handle_1905_topology_query(ieee1905_1::CmduMessageRx &cmd
tlvDeviceInformation->add_local_interface_list(localInterfaceInfo);
}

// TODO: Add a LocalInterfaceInfo field for each wireless interface.
// This is something that cannot be done at this moment because the MediaType field
// must be computed with information obtained through NL80211_CMD_GET_WIPHY command of DWPAL,
// which is currently not supported. See "Send standard NL80211 commands using DWPAL #782"
// For now, fill from radio data with dummy values based on information we have.
/**
* Add a LocalInterfaceInfo field for each wireless interface.
*/
for (const auto &soc : slaves_sockets) {
// Iterate on front radio iface and then switch to back radio iface
auto fill_radio_iface_info = [&](bool front_iface) {
auto fill_radio_iface_info = [&](ieee1905_1::eMediaType media_type, bool front_iface) {
LOG(DEBUG) << "filling interface information on radio="
<< (front_iface ? soc->radio_mac : soc->radio_mac + " backhaul");

Expand All @@ -2301,16 +2278,6 @@ bool backhaul_manager::handle_1905_topology_query(ieee1905_1::CmduMessageRx &cmd
LOG(DEBUG) << "Added radio interface to tlvDeviceInformation: "
<< localInterfaceInfo->mac();

ieee1905_1::eMediaType media_type = ieee1905_1::eMediaType::UNKNONWN_MEDIA;
if (soc->freq_type == beerocks::eFreqType::FREQ_24G) {
media_type = ieee1905_1::eMediaType::IEEE_802_11N_2_4_GHZ;
} else if (soc->freq_type == beerocks::eFreqType::FREQ_5G) {
media_type = ieee1905_1::eMediaType::IEEE_802_11AC_5_GHZ;
} else {
LOG(ERROR) << "Unsupported freq_type=" << int(soc->freq_type)
<< ", iface=" << soc->hostap_iface;
return false;
}
localInterfaceInfo->media_type() = media_type;

ieee1905_1::s802_11SpecificInformation media_info = {};
Expand Down Expand Up @@ -2352,13 +2319,22 @@ bool backhaul_manager::handle_1905_topology_query(ieee1905_1::CmduMessageRx &cmd
return true;
};

if (!fill_radio_iface_info(true)) {
std::string local_interface_name = soc->hostap_iface;

ieee1905_1::eMediaTypeGroup media_type_group = ieee1905_1::eMediaTypeGroup::IEEE_802_11;
ieee1905_1::eMediaType media_type = ieee1905_1::eMediaType::UNKNONWN_MEDIA;
if (!get_media_type(local_interface_name, media_type_group, media_type)) {
LOG(ERROR) << "Unable to compute media type for interface " << local_interface_name;
return false;
}

if (!fill_radio_iface_info(media_type, true)) {
LOG(DEBUG) << "filling interface information on radio=" << soc->radio_mac
<< " has failed!";
return true;
}

if (!fill_radio_iface_info(false)) {
if (!fill_radio_iface_info(media_type, false)) {
LOG(DEBUG) << "filling interface information on radio=" << soc->radio_mac
<< " backhaul has failed!";
return true;
Expand Down Expand Up @@ -3421,6 +3397,69 @@ std::shared_ptr<bwl::sta_wlan_hal> backhaul_manager::get_wireless_hal(std::strin
return slave_sk->second->sta_wlan_hal;
}

bool backhaul_manager::get_media_type_group(const std::string &interface_name,
ieee1905_1::eMediaTypeGroup &media_type_group)
{
// TODO: Currently, only Ethernet is supported
// When dealing with WiFi interfaces in task #792, use NL80211_CMD_GET_INTERFACE command to
// find out if media type group is WiFi
media_type_group = ieee1905_1::eMediaTypeGroup::IEEE_802_3;

return true;
}

bool backhaul_manager::get_media_type(const std::string &interface_name,
ieee1905_1::eMediaTypeGroup media_type_group,
ieee1905_1::eMediaType &media_type)
{
bool result = false;

if (ieee1905_1::eMediaTypeGroup::IEEE_802_3 == media_type_group) {
uint32_t speed;
if (network_utils::linux_iface_get_speed(interface_name, speed)) {
if (SPEED_100 == speed) {
media_type = ieee1905_1::eMediaType::IEEE_802_3U_FAST_ETHERNET;
} else if (SPEED_1000 <= speed) {
media_type = ieee1905_1::eMediaType::IEEE_802_3AB_GIGABIT_ETHERNET;
} else {
media_type = ieee1905_1::eMediaType::UNKNONWN_MEDIA;
}

result = true;
}
} else if (ieee1905_1::eMediaTypeGroup::IEEE_802_11 == media_type_group) {

for (const auto &radio_info_entry : m_radio_info_map) {
auto radio_info = radio_info_entry.second;

if (interface_name == radio_info.interface_name) {

for (const auto &tuple : table_6_12_media_type) {
if ((std::get<0>(tuple) == radio_info.frequency_band) &&
(std::get<1>(tuple) == radio_info.max_bandwidth)) {
media_type = std::get<2>(tuple);

break;
}
}

break;
}
}
} else if (ieee1905_1::eMediaTypeGroup::IEEE_1901 == media_type_group) {
// TODO: Not supported yet
LOG(ERROR) << "IEEE_1901 media is not supported yet";
} else if (ieee1905_1::eMediaTypeGroup::MoCA == media_type_group) {
// TODO: Not supported yet
LOG(ERROR) << "MoCA media is not supported yet";
} else {
media_type = ieee1905_1::eMediaType::UNKNONWN_MEDIA;
result = true;
}

return result;
}

bool backhaul_manager::get_neighbor_links(
const sMacAddr &neighbor_mac_filter,
std::map<std::string, std::vector<sMacAddr>> &neighbor_links_map)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

#include <beerocks/tlvf/beerocks_message_header.h>

#include <tlvf/ieee_1905_1/eMediaType.h>

#include "../agent_ucc_listener.h"

#include <future>
Expand Down Expand Up @@ -263,7 +265,12 @@ class backhaul_manager : public btl::transport_socket_thread {
* the TLVs to include in notification messages or responses to CDMU query messages.
*/
struct sRadioInfo {
beerocks_message::sVapsList vaps_list; /**< List of VAPs in radio. */
std::string interface_name; /**< Name of the radio interface */
beerocks::eFreqType frequency_band =
beerocks::eFreqType::FREQ_UNKNOWN; /**< Frequency band */
beerocks::eWiFiBandwidth max_bandwidth =
beerocks::eWiFiBandwidth::BANDWIDTH_UNKNOWN; /**< Maximum supported bandwidth */
beerocks_message::sVapsList vaps_list; /**< List of VAPs in radio. */
std::array<beerocks::message::sWifiChannel, beerocks::message::SUPPORTED_CHANNELS_LENGTH>
supported_channels; /**< Array of supported channels in radio. */
std::unordered_map<sMacAddr, associated_clients_t>
Expand All @@ -275,6 +282,33 @@ class backhaul_manager : public btl::transport_socket_thread {
*/
std::unordered_map<sMacAddr, sRadioInfo> m_radio_info_map;

/**
* @brief Gets media type group for given interface.
*
* @param[in] interface_name Name of the local interface.
* @param[in, out] media_type_group The media type group of the connecting interface.
*
* @return True on success and false otherwise.
*/
bool get_media_type_group(const std::string &interface_name,
ieee1905_1::eMediaTypeGroup &media_type_group);

/**
* @brief Gets media type for given interface.
*
* The mechanism to use to obtain media type depends on the media type group:
* Ethernet, WiFi, MoCA, etc.
*
* @param[in] interface_name Name of the local interface.
* @param[in] media_type_group The media type group of the connecting interface.
* @param[in, out] media_type The underlying network technology of the connecting interface.
*
* @return True on success and false otherwise.
*/
bool get_media_type(const std::string &interface_name,
ieee1905_1::eMediaTypeGroup media_type_group,
ieee1905_1::eMediaType &media_type);

/**
* @brief Gets the list of neighbor links from topology database.
*
Expand Down
3 changes: 3 additions & 0 deletions agent/src/beerocks/slave/son_slave_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3250,6 +3250,9 @@ bool slave_thread::slave_fsm(bool &call_slave_select)
config.backhaul_wireless_iface.c_str(),
message::IFACE_NAME_LENGTH);

bh_enable->frequency_band() = hostap_params.frequency_band;
bh_enable->max_bandwidth() = hostap_params.max_bandwidth;

auto tuple_supported_channels = bh_enable->supported_channels_list(0);
if (!std::get<0>(tuple_supported_channels)) {
LOG(ERROR) << "getting supported channels has failed!";
Expand Down
8 changes: 7 additions & 1 deletion common/beerocks/bwl/dummy/base_wlan_hal_dummy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,15 @@ bool base_wlan_hal_dummy::process_nl_events()

bool base_wlan_hal_dummy::refresh_radio_info()
{
m_radio_info.max_bandwidth = beerocks::eWiFiBandwidth::BANDWIDTH_40;

if (get_iface_name() == "wlan2") {
m_radio_info.is_5ghz = true;
m_radio_info.is_5ghz = true;
m_radio_info.frequency_band = beerocks::eFreqType::FREQ_5G;
} else {
m_radio_info.frequency_band = beerocks::eFreqType::FREQ_24G;
}

std::string radio_mac;
beerocks::net::network_utils::linux_iface_get_mac(m_radio_info.iface_name, radio_mac);
for (int vap_id = 0; vap_id < predefined_vaps_num; vap_id++) {
Expand Down
17 changes: 17 additions & 0 deletions common/beerocks/bwl/dwpal/base_wlan_hal_dwpal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,23 @@ bool base_wlan_hal_dwpal::refresh_radio_info()
{
char *reply = nullptr;

/**
* Obtain frequency band and maximum supported bandwidth using NL80211.
* As this information does not change, this is required the first time this method is called
* only.
*/
if (beerocks::eFreqType::FREQ_UNKNOWN == m_radio_info.frequency_band) {
nl80211_client::radio_info radio_info;
if (m_nl80211_client->get_radio_info(get_iface_name(), radio_info)) {
if (!radio_info.bands.empty()) {
nl80211_client::band_info band_info = radio_info.bands.at(0);

m_radio_info.frequency_band = band_info.get_frequency_band();
m_radio_info.max_bandwidth = band_info.get_max_bandwidth();
}
}
}

// TODO: Add radio_info get for station

// Station HAL
Expand Down
Loading