diff --git a/agent/src/beerocks/slave/backhaul_manager/backhaul_manager_thread.cpp b/agent/src/beerocks/slave/backhaul_manager/backhaul_manager_thread.cpp index 7a57169f5e..512c0c9e86 100644 --- a/agent/src/beerocks/slave/backhaul_manager/backhaul_manager_thread.cpp +++ b/agent/src/beerocks/slave/backhaul_manager/backhaul_manager_thread.cpp @@ -1025,21 +1025,16 @@ bool backhaul_manager::backhaul_fsm_main(bool &skip_select) for (const auto &socket : slaves_sockets) { if (socket) { for (int i = 0; i < beerocks::IFACE_TOTAL_VAPS; ++i) { - if (socket->vaps_list.vaps[i].mac != network_utils::ZERO_MAC) { + if ((socket->vaps_list.vaps[i].mac != network_utils::ZERO_MAC) && + (socket->vaps_list.vaps[i].ssid[0] != '\0')) { bssid_list.push_back(socket->vaps_list.vaps[i].mac); } } } } - // We must generate a new MID for the periodic AP Metrics Response messages that - // do not correspond to an AP Metrics Query message. - // We cannot set MID to 0 here because we must also differentiate periodic - // AP Metrics Response messages and messages received from monitor thread - // due to channel utilization crossed configured threshold value. - // As a temporary solution, set MID to UINT16_MAX here. - // TODO: to be fixed as part of #1328 + if (!bssid_list.empty()) { - send_slave_ap_metric_query_message(UINT16_MAX, bssid_list); + send_slave_ap_metric_query_message(0, bssid_list); } else { LOG(DEBUG) << "Skipping AP_METRICS_QUERY for slave, empty BSSID list"; } @@ -1235,51 +1230,51 @@ bool backhaul_manager::send_autoconfig_search_message(std::shared_ptr &bssid_list) { - bool ret = false; - for (auto socket : slaves_sockets) { - for (const auto &mac : bssid_list) { - int i = 0; - if (mac == socket->vaps_list.vaps[i].mac) { - LOG(DEBUG) << "Forwarding AP_METRICS_QUERY_MESSAGE message to son_slave, bssid: " - << std::hex << tlvf::mac_to_string(mac); - - auto forward = - cmdu_tx.create(mid, ieee1905_1::eMessageType::AP_METRICS_QUERY_MESSAGE); - if (!forward) { - LOG(ERROR) << "Failed to create AP_METRICS_QUERY_MESSAGE"; - return false; - } - auto query = cmdu_tx.addClass(); - if (!query) { - LOG(ERROR) << "Failed addClass"; - return false; - } + // Save mid and clear previous query + m_expected_ap_metrics_response.mid = mid; + m_expected_ap_metrics_response.expected_bssids.clear(); + m_expected_ap_metrics_response.response.create( + mid, ieee1905_1::eMessageType::AP_METRICS_RESPONSE_MESSAGE); - if (!query->alloc_bssid_list(1)) { - LOG(ERROR) << "Failed allocate memory for bssid_list"; - return false; - } + auto forward = cmdu_tx.create(mid, ieee1905_1::eMessageType::AP_METRICS_QUERY_MESSAGE); + if (!forward) { + LOG(ERROR) << "Failed to create AP_METRICS_QUERY_MESSAGE"; + return false; + } - auto list = query->bssid_list(0); - std::get<0>(list) = true; - std::get<1>(list) = mac; + auto query = cmdu_tx.addClass(); + if (!query) { + LOG(ERROR) << "Failed addClass"; + return false; + } - if (!message_com::send_cmdu(socket->slave, cmdu_tx)) { - LOG(ERROR) << "Failed forwarding AP_METRICS_QUERY_MESSAGE message to son_slave"; - ret = false; - continue; - } else { - ret = true; - // Fill a query vector - m_ap_metric_query.push_back({socket->slave, mac}); - } - } - i++; + if (!query->alloc_bssid_list(bssid_list.size())) { + LOG(ERROR) << "Failed allocate memory for bssid_list, size: " << bssid_list.size(); + return false; + } + + int i = 0; + for (const auto &mac : bssid_list) { + auto list = query->bssid_list(i); + std::get<0>(list) = true; + std::get<1>(list) = mac; + i++; + } + + auto ret = false; + for (auto socket : slaves_sockets) { + if (!message_com::send_cmdu(socket->slave, cmdu_tx)) { + LOG(ERROR) << "Failed forwarding AP_METRICS_QUERY_MESSAGE message to son_slave"; + ret = false; + continue; + } else { + ret = true; } } + return ret; -} +} // namespace beerocks bool backhaul_manager::backhaul_fsm_wireless(bool &skip_select) { @@ -2539,8 +2534,15 @@ bool backhaul_manager::handle_ap_capability_query(ieee1905_1::CmduMessageRx &cmd bool backhaul_manager::handle_ap_metrics_query(ieee1905_1::CmduMessageRx &cmdu_rx, const std::string &src_mac) { - std::vector bssid; - const auto mid = cmdu_rx.getMessageId(); + + const auto mid = cmdu_rx.getMessageId(); + + // Save mid and erase data for previous query and response + m_expected_ap_metrics_response.mid = mid; + m_expected_ap_metrics_response.expected_bssids.clear(); + m_expected_ap_metrics_response.response.create( + mid, ieee1905_1::eMessageType::AP_METRICS_RESPONSE_MESSAGE); + auto ap_metric_query_tlv = cmdu_rx.getClass(); if (!ap_metric_query_tlv) { LOG(ERROR) << "AP Metrics Query CMDU mid=" << mid << " does not have AP Metric Query TLV"; @@ -2552,14 +2554,22 @@ bool backhaul_manager::handle_ap_metrics_query(ieee1905_1::CmduMessageRx &cmdu_r LOG(ERROR) << "Failed to get bssid " << bssid_idx << " from AP_METRICS_QUERY"; return false; } - bssid.push_back(std::get<1>(bssid_tuple)); + + m_expected_ap_metrics_response.expected_bssids.push_back( + std::get<1>(bssid_tuple)); //New implementation + LOG(DEBUG) << "Received AP_METRICS_QUERY_MESSAGE, mid=" << std::hex << int(mid) << " bssid " << std::get<1>(bssid_tuple); } - if (!send_slave_ap_metric_query_message(mid, bssid)) { - LOG(ERROR) << "Failed to forward AP_METRICS_RESPONSE to the son_slave_thread"; - return false; + LOG(DEBUG) << "Forwarding AP_METRICS_QUERY_MESSAGE to all slaves, mid=" << std::hex << int(mid); + uint16_t length = message_com::get_uds_header(cmdu_rx)->length; + cmdu_rx.swap(); // swap back before forwarding + for (const auto &soc : slaves_sockets) { + if (!message_com::forward_cmdu_to_uds(soc->slave, cmdu_rx, length)) { + LOG(ERROR) << "Failed forwarding AP_METRICS_QUERY_MESSAGE message to slave: " + << tlvf::mac_to_string(soc->radio_mac); + } } return true; @@ -2569,33 +2579,21 @@ bool backhaul_manager::handle_slave_ap_metrics_response(ieee1905_1::CmduMessageR const std::string &src_mac) { auto mid = cmdu_rx.getMessageId(); - LOG(DEBUG) << "Received AP_METRICS_RESPONSE_MESSAGE, mid=" << std::hex << int(mid); - /** - * If AP Metrics Response message does not correspond to a previously received and forwarded - * AP Metrics Query message (which we know because message id is not set), then forward message - * to controller. - * This might happen when channel utilization value has crossed configured threshold or when - * periodic metrics reporting interval has elapsed. - */ - if (0 == mid) { - uint16_t length = message_com::get_uds_header(cmdu_rx)->length; - cmdu_rx.swap(); //swap back before forwarding - return send_cmdu_to_bus(cmdu_rx, controller_bridge_mac, bridge_info.mac, length); + if (mid != m_expected_ap_metrics_response.mid) { + LOG(ERROR) << "Received AP_METRICS_RESPONSE_MESSAGE with bad mid=" << std::hex << int(mid); + return false; } - /** - * When periodic metrics reporting interval has elapsed, we emulate that we have received an - * AP Metrics Query message from controller. To differentiate real queries from emulated ones, - * we use a "special" mid value. - * Note that this design is flaw as a real query might also have this special mid value. This - * is just a quick and dirty fix to pass 4.7.5 and 4.7.6 for M1 - * TODO: to be fixed as part of #1328 - */ - if (UINT16_MAX == mid) { - mid = 0; + if (mid == 0) { + LOG(DEBUG) << "Forward AP_METRICS_RESPONSE_MESSAGE to controller, mid=" << std::hex + << int(mid); + return send_cmdu_to_bus(cmdu_rx, controller_bridge_mac, bridge_info.mac, + cmdu_rx.getMessageLength()); } + LOG(DEBUG) << "Received AP_METRICS_RESPONSE_MESSAGE, mid=" << std::hex << int(mid); + auto ap_metrics_tlv = cmdu_rx.getClass(); if (!ap_metrics_tlv) { LOG(ERROR) << "Failed cmdu_rx.getClass(), mid=" << std::hex @@ -2604,43 +2602,71 @@ bool backhaul_manager::handle_slave_ap_metrics_response(ieee1905_1::CmduMessageR } auto bssid_tlv = ap_metrics_tlv->bssid(); - auto mac = std::find_if( - m_ap_metric_query.begin(), m_ap_metric_query.end(), - [&bssid_tlv](sApMetricsQuery const &query) { return query.bssid == bssid_tlv; }); + auto mac = std::find_if(m_expected_ap_metrics_response.expected_bssids.begin(), + m_expected_ap_metrics_response.expected_bssids.end(), + [&bssid_tlv](sMacAddr const &query) { return query == bssid_tlv; }); - if (mac == m_ap_metric_query.end()) { + if (mac == m_expected_ap_metrics_response.expected_bssids.end()) { LOG(ERROR) << "Failed search in ap_metric_query for bssid: " << bssid_tlv << " from mid=" << std::hex << int(mid); return false; } - sApMetrics metric; - // Copy data to the response vector - metric.bssid = ap_metrics_tlv->bssid(); - metric.channel_utilization = ap_metrics_tlv->channel_utilization(); - metric.number_of_stas_currently_associated = + m_expected_ap_metrics_response.response.create( + mid, ieee1905_1::eMessageType::AP_METRICS_RESPONSE_MESSAGE); + + // Prepare AP Metrics TLV + auto ap_metrics_response_tlv = + m_expected_ap_metrics_response.response.addClass(); + if (!ap_metrics_response_tlv) { + LOG(ERROR) << "Failed addClass"; + return false; + } + ap_metrics_response_tlv->bssid() = ap_metrics_tlv->bssid(); + ap_metrics_response_tlv->channel_utilization() = ap_metrics_tlv->channel_utilization(); + ap_metrics_response_tlv->number_of_stas_currently_associated() = ap_metrics_tlv->number_of_stas_currently_associated(); - metric.estimated_service_parameters = ap_metrics_tlv->estimated_service_parameters(); - auto info = ap_metrics_tlv->estimated_service_info_field(); + ap_metrics_response_tlv->estimated_service_parameters() = + ap_metrics_tlv->estimated_service_parameters(); + + if (!ap_metrics_response_tlv->alloc_estimated_service_info_field( + ap_metrics_tlv->estimated_service_info_field_length())) { + LOG(ERROR) << "Couldn't allocate " + "ap_metrics_response_tlv->alloc_estimated_service_info_field"; + return false; + } + auto rx_info = ap_metrics_tlv->estimated_service_info_field(); + auto tx_info = ap_metrics_response_tlv->estimated_service_info_field(); for (size_t i = 0; i < ap_metrics_tlv->estimated_service_info_field_length(); i++) { - metric.estimated_service_info_field.push_back(info[i]); + tx_info[i] = rx_info[i]; } - std::vector traffic_stats_response; + // Prepare STA Traffic Stats TLV's for (auto &sta_traffic : cmdu_rx.getClassList()) { if (!sta_traffic) { LOG(ERROR) << "Failed to get class list for tlvAssociatedStaTrafficStats"; continue; } - traffic_stats_response.push_back( - {sta_traffic->sta_mac(), sta_traffic->byte_sent(), sta_traffic->byte_recived(), - sta_traffic->packets_sent(), sta_traffic->packets_recived(), - sta_traffic->tx_packets_error(), sta_traffic->rx_packets_error(), - sta_traffic->retransmission_count()}); + auto sta_traffic_response_tlv = m_expected_ap_metrics_response.response + .addClass(); + + if (!sta_traffic_response_tlv) { + LOG(ERROR) << "Failed addClass"; + continue; + } + + sta_traffic_response_tlv->sta_mac() = sta_traffic->sta_mac(); + sta_traffic_response_tlv->byte_sent() = sta_traffic->byte_sent(); + sta_traffic_response_tlv->byte_recived() = sta_traffic->byte_recived(); + sta_traffic_response_tlv->packets_sent() = sta_traffic->packets_sent(); + sta_traffic_response_tlv->packets_recived() = sta_traffic->packets_recived(); + sta_traffic_response_tlv->tx_packets_error() = sta_traffic->tx_packets_error(); + sta_traffic_response_tlv->rx_packets_error() = sta_traffic->rx_packets_error(); + sta_traffic_response_tlv->retransmission_count() = sta_traffic->retransmission_count(); } - std::vector link_metrics_response; + // Prepare STA Link Metrics TLV's for (auto &sta_link_metric : cmdu_rx.getClassList()) { if (!sta_link_metric) { LOG(ERROR) << "Failed getClassList"; @@ -2651,99 +2677,40 @@ bool backhaul_manager::handle_slave_ap_metrics_response(ieee1905_1::CmduMessageR continue; } auto response_list = sta_link_metric->bssid_info_list(0); - link_metrics_response.push_back({sta_link_metric->sta_mac(), std::get<1>(response_list)}); - } - // Fill a response vector - m_ap_metric_response.push_back({metric, traffic_stats_response, link_metrics_response}); + auto sta_link_metric_response_tlv = m_expected_ap_metrics_response.response + .addClass(); - // Remove an entry from the processed query - m_ap_metric_query.erase( - std::remove_if(m_ap_metric_query.begin(), m_ap_metric_query.end(), - [&](sApMetricsQuery const &query) { return mac->bssid == query.bssid; }), - m_ap_metric_query.end()); - - if (!m_ap_metric_query.empty()) { - return true; - } - - // We received all responses - prepare and send response message to the controller - auto cmdu_header = cmdu_tx.create(mid, ieee1905_1::eMessageType::AP_METRICS_RESPONSE_MESSAGE); - - if (!cmdu_header) { - LOG(ERROR) << "Failed building IEEE1905 AP_METRICS_RESPONSE_MESSAGE"; - return false; - } - - // Prepare tlvApMetrics for each processed query - for (const auto &response : m_ap_metric_response) { - auto ap_metrics_response_tlv = cmdu_tx.addClass(); - if (!ap_metrics_response_tlv) { - LOG(ERROR) << "Failed addClass"; - return false; - } - - ap_metrics_response_tlv->bssid() = response.metric.bssid; - ap_metrics_response_tlv->channel_utilization() = response.metric.channel_utilization; - ap_metrics_response_tlv->number_of_stas_currently_associated() = - response.metric.number_of_stas_currently_associated; - ap_metrics_response_tlv->estimated_service_parameters() = - response.metric.estimated_service_parameters; - if (!ap_metrics_response_tlv->alloc_estimated_service_info_field( - response.metric.estimated_service_info_field.size())) { - LOG(ERROR) << "Couldn't allocate " - "ap_metrics_response_tlv->alloc_estimated_service_info_field"; - return false; + if (!sta_link_metric_response_tlv) { + LOG(ERROR) << "Failed addClass"; + continue; } - std::copy_n(response.metric.estimated_service_info_field.begin(), - response.metric.estimated_service_info_field.size(), - ap_metrics_response_tlv->estimated_service_info_field()); - - for (auto &stat : response.sta_traffic_stats) { - auto sta_traffic_response_tlv = - cmdu_tx.addClass(); - if (!sta_traffic_response_tlv) { - LOG(ERROR) << "Failed addClass"; - continue; - } - - sta_traffic_response_tlv->sta_mac() = stat.sta_mac; - sta_traffic_response_tlv->byte_sent() = stat.byte_sent; - sta_traffic_response_tlv->byte_recived() = stat.byte_recived; - sta_traffic_response_tlv->packets_sent() = stat.packets_sent; - sta_traffic_response_tlv->packets_recived() = stat.packets_recived; - sta_traffic_response_tlv->tx_packets_error() = stat.tx_packets_error; - sta_traffic_response_tlv->rx_packets_error() = stat.rx_packets_error; - sta_traffic_response_tlv->retransmission_count() = stat.retransmission_count; + sta_link_metric_response_tlv->sta_mac() = sta_link_metric->sta_mac(); + if (!sta_link_metric_response_tlv->alloc_bssid_info_list(1)) { + LOG(ERROR) << "Failed alloc_bssid_info_list"; + continue; } + auto &sta_link_metric_response = + std::get<1>(sta_link_metric_response_tlv->bssid_info_list(0)); + sta_link_metric_response = std::get<1>(response_list); + } - for (auto &link_metric : response.sta_link_metrics) { - auto sta_link_metric_response_tlv = - cmdu_tx.addClass(); - - if (!sta_link_metric_response_tlv) { - LOG(ERROR) << "Failed addClass"; - continue; - } + // Remove an entry from the processed query + m_expected_ap_metrics_response.expected_bssids.erase( + std::remove_if(m_expected_ap_metrics_response.expected_bssids.begin(), + m_expected_ap_metrics_response.expected_bssids.end(), + [&](sMacAddr const &query) { return *mac == query; }), + m_expected_ap_metrics_response.expected_bssids.end()); - sta_link_metric_response_tlv->sta_mac() = link_metric.sta_mac; - if (!sta_link_metric_response_tlv->alloc_bssid_info_list(1)) { - LOG(ERROR) << "Failed alloc_bssid_info_list"; - continue; - } - auto &sta_link_metric_response = - std::get<1>(sta_link_metric_response_tlv->bssid_info_list(0)); - sta_link_metric_response = link_metric.bssid_info; - } + if (!m_expected_ap_metrics_response.expected_bssids.empty()) { + return true; } - // Clear the m_ap_metric_response vector after preparing response to the controller - m_ap_metric_response.clear(); - LOG(DEBUG) << "Sending AP_METRICS_RESPONSE_MESSAGE, mid=" << std::hex << int(mid); - return send_cmdu_to_bus(cmdu_tx, controller_bridge_mac, bridge_info.mac); -} + return send_cmdu_to_bus(m_expected_ap_metrics_response.response, controller_bridge_mac, + bridge_info.mac); +} // namespace beerocks /** * @brief Handles 1905 Topology Query message diff --git a/agent/src/beerocks/slave/backhaul_manager/backhaul_manager_thread.h b/agent/src/beerocks/slave/backhaul_manager/backhaul_manager_thread.h index e44fbc8c86..167feaa536 100644 --- a/agent/src/beerocks/slave/backhaul_manager/backhaul_manager_thread.h +++ b/agent/src/beerocks/slave/backhaul_manager/backhaul_manager_thread.h @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -519,43 +520,14 @@ class backhaul_manager : public btl::transport_socket_thread { const sLinkNeighbor &link_neighbor, const sLinkMetrics &link_metrics, ieee1905_1::eLinkMetricsType link_metrics_type); - struct sStaTrafficStats { - sMacAddr sta_mac; - uint32_t byte_sent; - uint32_t byte_recived; - uint32_t packets_sent; - uint32_t packets_recived; - uint32_t tx_packets_error; - uint32_t rx_packets_error; - uint32_t retransmission_count; - }; - - struct sStaLinkMetrics { - sMacAddr sta_mac; - wfa_map::tlvAssociatedStaLinkMetrics::sBssidInfo bssid_info; - }; - - struct sApMetricsQuery { - Socket *soc; - sMacAddr bssid; - }; - - struct sApMetrics { - sMacAddr bssid; - uint8_t channel_utilization; - uint16_t number_of_stas_currently_associated; - wfa_map::tlvApMetrics::sEstimatedService estimated_service_parameters; - std::vector estimated_service_info_field; - }; - - struct sApMetricsResponse { - sApMetrics metric; - std::vector sta_traffic_stats; - std::vector sta_link_metrics; + struct sExpectedApMetricsResponse { + uint16_t mid; + std::vector expected_bssids; + uint8_t response_buffer[message::MESSAGE_BUFFER_LENGTH]; + ieee1905_1::CmduMessageTx response = {response_buffer, sizeof(response_buffer)}; }; - std::vector m_ap_metric_query; - std::vector m_ap_metric_response; + sExpectedApMetricsResponse m_expected_ap_metrics_response; struct sChannelSelectionResponse { sMacAddr radio_mac;