blob: 3015b129740ecb27349dda6b125df4cc6fc1c9ac [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <wlan/mlme/mesh/write_mp_action.h>
#include <wlan/common/write_element.h>
#include <wlan/mlme/rates_elements.h>
namespace wlan_mlme = ::fuchsia::wlan::mlme;
namespace wlan {
static void WriteFixed(BufferWriter* w, const MacHeaderWriter& mac_header_writer,
const common::MacAddr& dst_addr, action::SelfProtectedAction action) {
// Mac header
mac_header_writer.WriteMeshMgmtHeader(w, kAction, dst_addr);
// Action header
w->Write<ActionFrame>()->category = action::kSelfProtected;
w->Write<SelfProtectedActionHeader>()->self_prot_action = action;
// Capability info: leave ESS and IBSS set to zero to indicate 'mesh'.
// Hardcode short preamble because the rest of our code does so...
auto cap_info = w->Write<CapabilityInfo>();
cap_info->set_short_preamble(1);
}
static void WriteCommonElementsHead(BufferWriter* w, const wlan_mlme::MeshPeeringCommon& c) {
RatesWriter rates_writer({
reinterpret_cast<const SupportedRate*>(c.rates.data()),
c.rates.size(),
});
rates_writer.WriteSupportedRates(w);
rates_writer.WriteExtendedSupportedRates(w);
common::WriteMeshId(w, c.mesh_id);
common::WriteMeshConfiguration(w, MeshConfiguration::FromFidl(c.mesh_config));
}
static void WriteCommonElementsTail(BufferWriter* w, const wlan_mlme::MeshPeeringCommon& c) {
if (c.ht_cap != nullptr) {
common::WriteHtCapabilities(w, HtCapabilities::FromFidl(*c.ht_cap));
}
if (c.ht_op != nullptr) { common::WriteHtOperation(w, HtOperation::FromFidl(*c.ht_op)); }
if (c.vht_cap != nullptr) {
common::WriteVhtCapabilities(w, VhtCapabilities::FromFidl(*c.vht_cap));
}
if (c.vht_op != nullptr) { common::WriteVhtOperation(w, VhtOperation::FromFidl(*c.vht_op)); }
}
void WriteMpOpenActionFrame(BufferWriter* w, const MacHeaderWriter& mac_header_writer,
const wlan_mlme::MeshPeeringOpenAction& action) {
common::MacAddr dst_addr{action.common.peer_sta_address};
WriteFixed(w, mac_header_writer, dst_addr, action::kMeshPeeringOpen);
WriteCommonElementsHead(w, action.common);
MpmHeader mpm_header = {
.protocol = static_cast<MpmHeader::Protocol>(action.common.protocol_id),
.local_link_id = action.common.local_link_id,
};
common::WriteMpmOpen(w, mpm_header, nullptr);
WriteCommonElementsTail(w, action.common);
}
void WriteMpConfirmActionFrame(BufferWriter* w, const MacHeaderWriter& mac_header_writer,
const wlan_mlme::MeshPeeringConfirmAction& action) {
common::MacAddr dst_addr{action.common.peer_sta_address};
WriteFixed(w, mac_header_writer, dst_addr, action::kMeshPeeringConfirm);
w->WriteValue<uint16_t>(action.aid);
WriteCommonElementsHead(w, action.common);
MpmHeader mpm_header = {
.protocol = static_cast<MpmHeader::Protocol>(action.common.protocol_id),
.local_link_id = action.common.local_link_id,
};
common::WriteMpmConfirm(w, mpm_header, action.peer_link_id, nullptr);
WriteCommonElementsTail(w, action.common);
}
} // namespace wlan