blob: 676d242e5658bd1c7b0404458ffd89ae0319830f [file] [log] [blame]
// Copyright 2021 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 "sim-frame.h"
namespace wlan::simulation {
/* InformationElement function implementations.*/
InformationElement::~InformationElement() = default;
// SsidInformationElement function implementations.
SsidInformationElement::SsidInformationElement(
const wlan::simulation::SsidInformationElement& ssid_ie) {
ssid_ = ssid_ie.ssid_;
}
InformationElement::SimIeType SsidInformationElement::IeType() const { return IE_TYPE_SSID; }
std::vector<uint8_t> SsidInformationElement::ToRawIe() const {
std::vector<uint8_t> buf = {IE_TYPE_SSID, static_cast<uint8_t>(ssid_.size())};
buf.insert(buf.end(), ssid_.begin(), ssid_.end());
return buf;
}
SsidInformationElement::~SsidInformationElement() = default;
// CsaInformationElement function implementations.
CsaInformationElement::CsaInformationElement(
const wlan::simulation::CsaInformationElement& csa_ie) {
channel_switch_mode_ = csa_ie.channel_switch_mode_;
new_channel_number_ = csa_ie.new_channel_number_;
channel_switch_count_ = csa_ie.channel_switch_count_;
}
InformationElement::SimIeType CsaInformationElement::IeType() const { return IE_TYPE_CSA; }
std::vector<uint8_t> CsaInformationElement::ToRawIe() const {
const uint8_t csa_len = 3; // CSA variable is 3 bytes long: CSM + NCN + CSC.
std::vector<uint8_t> buf = {IE_TYPE_CSA, csa_len,
static_cast<uint8_t>(channel_switch_mode_ ? 1 : 0),
new_channel_number_, channel_switch_count_};
return buf;
}
CsaInformationElement::~CsaInformationElement() = default;
/* SimFrame function implementations.*/
SimFrame::~SimFrame() = default;
/* SimManagementFrame function implementations.*/
SimManagementFrame::SimManagementFrame(const SimManagementFrame& mgmt_frame) {
src_addr_ = mgmt_frame.src_addr_;
dst_addr_ = mgmt_frame.dst_addr_;
sec_proto_type_ = mgmt_frame.sec_proto_type_;
for (const auto& ie : mgmt_frame.IEs_) {
switch (ie->IeType()) {
case SsidInformationElement::IE_TYPE_SSID:
IEs_.push_back(std::make_shared<SsidInformationElement>(
*(std::static_pointer_cast<SsidInformationElement>(ie))));
break;
case CsaInformationElement::IE_TYPE_CSA:
IEs_.push_back(std::make_shared<CsaInformationElement>(
*(std::static_pointer_cast<CsaInformationElement>(ie))));
break;
default:;
}
}
raw_ies_ = mgmt_frame.raw_ies_;
}
SimManagementFrame::~SimManagementFrame() = default;
SimFrame::SimFrameType SimManagementFrame::FrameType() const { return FRAME_TYPE_MGMT; }
std::shared_ptr<InformationElement> SimManagementFrame::FindIe(
InformationElement::SimIeType ie_type) const {
for (const auto& ie : IEs_) {
if (ie->IeType() == ie_type) {
return ie;
}
}
return std::shared_ptr<InformationElement>(nullptr);
}
void SimManagementFrame::AddSsidIe(const fuchsia_wlan_ieee80211::Ssid& ssid) {
auto ie = std::make_shared<SsidInformationElement>(ssid);
// Ensure no IE with this IE type exists.
AddIe(InformationElement::IE_TYPE_SSID, ie);
}
void SimManagementFrame::AddCsaIe(const wlan_ieee80211_wire::WlanChannel& channel,
uint8_t channel_switch_count) {
// for nonmesh STAs, this field either is set to the number of TBTTs until the STA sending the
// Channel Switch Announcement element switches to the new channel or is set to 0.
auto ie = std::make_shared<CsaInformationElement>(false, channel.primary, channel_switch_count);
// Ensure no IE with this IE type exist
AddIe(InformationElement::IE_TYPE_CSA, ie);
}
void SimManagementFrame::AddRawIes(cpp20::span<const uint8_t> raw_ies) {
raw_ies_.insert(raw_ies_.end(), raw_ies.begin(), raw_ies.end());
}
void SimManagementFrame::AddIe(InformationElement::SimIeType ie_type,
std::shared_ptr<InformationElement> ie) {
if (FindIe(ie_type)) {
RemoveIe(ie_type);
}
IEs_.push_back(ie);
}
void SimManagementFrame::RemoveIe(InformationElement::SimIeType ie_type) {
for (auto it = IEs_.begin(); it != IEs_.end();) {
if ((*it)->IeType() == ie_type) {
it = IEs_.erase(it);
} else {
it++;
}
}
}
/* SimBeaconFrame function implementations.*/
SimBeaconFrame::SimBeaconFrame(const fuchsia_wlan_ieee80211::Ssid& ssid,
const common::MacAddr& bssid)
: bssid_(bssid) {
// Beacon automatically gets the SSID information element.
AddSsidIe(ssid);
}
SimBeaconFrame::SimBeaconFrame(const SimBeaconFrame& beacon) : SimManagementFrame(beacon) {
bssid_ = beacon.bssid_;
interval_ = beacon.interval_;
capability_info_ = beacon.capability_info_;
// IEs are copied by SimManagementFrame copy constructor.
}
SimBeaconFrame::~SimBeaconFrame() = default;
SimManagementFrame::SimMgmtFrameType SimBeaconFrame::MgmtFrameType() const {
return FRAME_TYPE_BEACON;
}
SimFrame* SimBeaconFrame::CopyFrame() const { return new SimBeaconFrame(*this); }
/* SimProbeReqFrame function implementations.*/
SimProbeReqFrame::SimProbeReqFrame(const SimProbeReqFrame& probe_req)
: SimManagementFrame(probe_req) {}
SimProbeReqFrame::~SimProbeReqFrame() = default;
SimManagementFrame::SimMgmtFrameType SimProbeReqFrame::MgmtFrameType() const {
return FRAME_TYPE_PROBE_REQ;
}
SimFrame* SimProbeReqFrame::CopyFrame() const { return new SimProbeReqFrame(*this); }
/* SimProbeRespFrame function implementations.*/
SimProbeRespFrame::SimProbeRespFrame(const common::MacAddr& src, const common::MacAddr& dst,
const fuchsia_wlan_ieee80211::Ssid& ssid)
: SimManagementFrame(src, dst) {
// Probe response automatically gets the SSID information element.
AddSsidIe(ssid);
}
SimProbeRespFrame::SimProbeRespFrame(const SimProbeRespFrame& probe_resp)
: SimManagementFrame(probe_resp) {
capability_info_ = probe_resp.capability_info_;
// IEs are copied by SimManagementFrame copy constructor.
}
SimProbeRespFrame::~SimProbeRespFrame() = default;
SimManagementFrame::SimMgmtFrameType SimProbeRespFrame::MgmtFrameType() const {
return FRAME_TYPE_PROBE_RESP;
}
SimFrame* SimProbeRespFrame::CopyFrame() const { return new SimProbeRespFrame(*this); }
/* SimAssocReqFrame function implementations.*/
SimAssocReqFrame::SimAssocReqFrame(const SimAssocReqFrame& assoc_req)
: SimManagementFrame(assoc_req) {
bssid_ = assoc_req.bssid_;
ssid_ = assoc_req.ssid_;
}
SimAssocReqFrame::~SimAssocReqFrame() = default;
SimManagementFrame::SimMgmtFrameType SimAssocReqFrame::MgmtFrameType() const {
return FRAME_TYPE_ASSOC_REQ;
}
SimFrame* SimAssocReqFrame::CopyFrame() const { return new SimAssocReqFrame(*this); }
/* SimAssocRespFrame function implementations.*/
SimAssocRespFrame::SimAssocRespFrame(const SimAssocRespFrame& assoc_resp)
: SimManagementFrame(assoc_resp) {
status_ = assoc_resp.status_;
capability_info_ = assoc_resp.capability_info_;
}
SimAssocRespFrame::~SimAssocRespFrame() = default;
SimManagementFrame::SimMgmtFrameType SimAssocRespFrame::MgmtFrameType() const {
return FRAME_TYPE_ASSOC_RESP;
}
SimFrame* SimAssocRespFrame::CopyFrame() const { return new SimAssocRespFrame(*this); }
/* SimDisassocReqFrame function implementations.*/
SimDisassocReqFrame::SimDisassocReqFrame(const SimDisassocReqFrame& disassoc_req)
: SimManagementFrame(disassoc_req) {
reason_ = disassoc_req.reason_;
}
SimDisassocReqFrame::~SimDisassocReqFrame() = default;
SimManagementFrame::SimMgmtFrameType SimDisassocReqFrame::MgmtFrameType() const {
return FRAME_TYPE_DISASSOC_REQ;
}
SimFrame* SimDisassocReqFrame::CopyFrame() const { return new SimDisassocReqFrame(*this); }
/* SimAuthFrame function implementations.*/
SimAuthFrame::SimAuthFrame(const SimAuthFrame& auth) : SimManagementFrame(auth) {
seq_num_ = auth.seq_num_;
auth_type_ = auth.auth_type_;
status_ = auth.status_;
payload_ = auth.payload_;
}
SimAuthFrame::~SimAuthFrame() = default;
SimManagementFrame::SimMgmtFrameType SimAuthFrame::MgmtFrameType() const { return FRAME_TYPE_AUTH; }
SimFrame* SimAuthFrame::CopyFrame() const { return new SimAuthFrame(*this); }
void SimAuthFrame::AddChallengeText(cpp20::span<const uint8_t> text) {
// Clear the existing challenge text before setting new one.
payload_.clear();
payload_.insert(payload_.begin(), text.begin(), text.end());
}
/* SimDeauthFrame function implementations.*/
SimDeauthFrame::SimDeauthFrame(const SimDeauthFrame& deauth) : SimManagementFrame(deauth) {
reason_ = deauth.reason_;
}
SimDeauthFrame::~SimDeauthFrame() = default;
SimManagementFrame::SimMgmtFrameType SimDeauthFrame::MgmtFrameType() const {
return FRAME_TYPE_DEAUTH;
}
SimFrame* SimDeauthFrame::CopyFrame() const { return new SimDeauthFrame(*this); }
/* SimReassocReqFrame function implementations.*/
SimReassocReqFrame::SimReassocReqFrame(const SimReassocReqFrame& reassoc_req)
: SimManagementFrame(reassoc_req) {
bssid_ = reassoc_req.bssid_;
}
SimReassocReqFrame::~SimReassocReqFrame() = default;
SimManagementFrame::SimMgmtFrameType SimReassocReqFrame::MgmtFrameType() const {
return FRAME_TYPE_REASSOC_REQ;
}
SimFrame* SimReassocReqFrame::CopyFrame() const { return new SimReassocReqFrame(*this); }
/* SimReassocRespFrame function implementations.*/
SimReassocRespFrame::SimReassocRespFrame(const SimReassocRespFrame& reassoc_resp)
: SimManagementFrame(reassoc_resp) {
status_ = reassoc_resp.status_;
capability_info_ = reassoc_resp.capability_info_;
}
SimReassocRespFrame::~SimReassocRespFrame() = default;
SimManagementFrame::SimMgmtFrameType SimReassocRespFrame::MgmtFrameType() const {
return FRAME_TYPE_REASSOC_RESP;
}
SimFrame* SimReassocRespFrame::CopyFrame() const { return new SimReassocRespFrame(*this); }
/* SimActionFrame function implementations.*/
SimActionFrame::SimActionFrame(const SimActionFrame& action) = default;
SimActionFrame::~SimActionFrame() = default;
SimManagementFrame::SimMgmtFrameType SimActionFrame::MgmtFrameType() const {
return FRAME_TYPE_ACTION;
}
SimFrame* SimActionFrame::CopyFrame() const { return new SimActionFrame(*this); }
SimActionFrame::SimActionCategory SimActionFrame::ActionCategory() const { return category_; }
/* SimWnmActionFrame function implementations.*/
SimWnmActionFrame::SimWnmActionFrame(const SimWnmActionFrame& wnm_action) = default;
SimWnmActionFrame::~SimWnmActionFrame() = default;
SimFrame* SimWnmActionFrame::CopyFrame() const { return new SimWnmActionFrame(*this); }
/* SimBtmReqFrame function implementations.*/
SimBtmReqFrame::SimBtmReqFrame(const SimBtmReqFrame& btm_req) = default;
SimBtmReqFrame::~SimBtmReqFrame() = default;
SimFrame* SimBtmReqFrame::CopyFrame() const { return new SimBtmReqFrame(*this); }
std::vector<SimNeighborReportElement> SimBtmReqFrame::CandidateList() const {
std::vector<SimNeighborReportElement> candidates = candidate_list_;
return candidates;
}
/* SimDataFrame function implementations.*/
SimDataFrame::SimDataFrame(const SimDataFrame& data_frame) {
toDS_ = data_frame.toDS_;
fromDS_ = data_frame.fromDS_;
addr1_ = data_frame.addr1_;
addr2_ = data_frame.addr2_;
addr3_ = data_frame.addr3_;
addr4_ = data_frame.addr4_;
qosControl_ = data_frame.qosControl_;
payload_.assign(data_frame.payload_.begin(), data_frame.payload_.end());
}
SimDataFrame::~SimDataFrame() = default;
SimFrame::SimFrameType SimDataFrame::FrameType() const { return FRAME_TYPE_DATA; }
/* SimQosDataFrame function implementations.*/
SimQosDataFrame::SimQosDataFrame(const SimQosDataFrame& qos_data) : SimDataFrame(qos_data) {}
SimQosDataFrame::~SimQosDataFrame() = default;
SimDataFrame::SimDataFrameType SimQosDataFrame::DataFrameType() const {
return FRAME_TYPE_QOS_DATA;
}
SimFrame* SimQosDataFrame::CopyFrame() const { return new SimQosDataFrame(*this); }
} // namespace wlan::simulation