blob: b60a63e83f666ddfa28e41f8ed15f552dc3971c6 [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.
#ifndef SRC_CONNECTIVITY_WLAN_DRIVERS_TESTING_LIB_SIM_ENV_SIM_FRAME_H_
#define SRC_CONNECTIVITY_WLAN_DRIVERS_TESTING_LIB_SIM_ENV_SIM_FRAME_H_
#include <fidl/fuchsia.wlan.common/cpp/wire.h>
#include <fidl/fuchsia.wlan.ieee80211/cpp/common_types.h>
#include <fidl/fuchsia.wlan.ieee80211/cpp/natural_types.h>
#include <lib/stdcompat/span.h>
#include <zircon/types.h>
#include <list>
#include <memory>
#include <optional>
#include "src/connectivity/wlan/drivers/testing/lib/sim-env/sim-sta-ifc.h"
#include "src/connectivity/wlan/lib/common/cpp/include/wlan/common/mac_frame.h"
#include "wlan/common/macaddr.h"
namespace wlan_ieee80211_wire = fuchsia_wlan_ieee80211::wire;
namespace wlan::simulation {
class StationIfc;
typedef struct WlanRxInfo {
wlan_ieee80211_wire::WlanChannel channel;
double signal_strength;
double noise_level;
} WlanRxInfo;
typedef struct WlanTxInfo {
wlan_ieee80211_wire::WlanChannel channel;
} WlanTxInfo;
// Representative for security protocol, we don't have this field in real situation.
enum SimSecProtoType {
SEC_PROTO_TYPE_OPEN,
SEC_PROTO_TYPE_WEP,
SEC_PROTO_TYPE_WPA1,
SEC_PROTO_TYPE_WPA2,
SEC_PROTO_TYPE_WPA3
};
// AUTH_TYPE used by AP and authentication frame
enum SimAuthType { AUTH_TYPE_OPEN, AUTH_TYPE_SHARED_KEY, AUTH_TYPE_SAE };
class InformationElement {
public:
enum SimIeType { IE_TYPE_SSID = 0, IE_TYPE_CSA = 37, IE_TYPE_WPA1 = 221, IE_TYPE_WPA2 = 48 };
explicit InformationElement() = default;
virtual ~InformationElement();
virtual SimIeType IeType() const = 0;
// Return the IE as a buffer of bytes, in the 802.11-specified format for this IE type.
virtual std::vector<uint8_t> ToRawIe() const = 0;
};
// IEEE Std 802.11-2016, 9.4.2.2
class SsidInformationElement : public InformationElement {
public:
explicit SsidInformationElement(const fuchsia_wlan_ieee80211::Ssid& ssid) : ssid_(ssid) {}
SsidInformationElement(const SsidInformationElement& ssid_ie);
~SsidInformationElement() override;
SimIeType IeType() const override;
std::vector<uint8_t> ToRawIe() const override;
fuchsia_wlan_ieee80211::Ssid ssid_;
};
// IEEE Std 802.11-2016, 9.4.2.19
class CsaInformationElement : public InformationElement {
public:
explicit CsaInformationElement(bool switch_mode, uint8_t new_channel, uint8_t switch_count) {
channel_switch_mode_ = switch_mode;
new_channel_number_ = new_channel;
channel_switch_count_ = switch_count;
}
CsaInformationElement(const CsaInformationElement& csa_ie);
~CsaInformationElement() override;
SimIeType IeType() const override;
std::vector<uint8_t> ToRawIe() const override;
bool channel_switch_mode_;
uint8_t new_channel_number_;
uint8_t channel_switch_count_;
};
class SimFrame {
public:
enum SimFrameType { FRAME_TYPE_MGMT, FRAME_TYPE_CTRL, FRAME_TYPE_DATA };
SimFrame() = default;
virtual ~SimFrame();
// Frame type identifier
virtual SimFrameType FrameType() const = 0;
virtual SimFrame* CopyFrame() const = 0;
};
class SimManagementFrame : public SimFrame {
public:
enum SimMgmtFrameType {
FRAME_TYPE_BEACON,
FRAME_TYPE_PROBE_REQ,
FRAME_TYPE_PROBE_RESP,
FRAME_TYPE_ASSOC_REQ,
FRAME_TYPE_ASSOC_RESP,
FRAME_TYPE_DISASSOC_REQ,
FRAME_TYPE_AUTH,
FRAME_TYPE_DEAUTH,
FRAME_TYPE_REASSOC_REQ,
FRAME_TYPE_REASSOC_RESP,
FRAME_TYPE_ACTION,
};
SimManagementFrame() = default;
SimManagementFrame(const common::MacAddr& src, const common::MacAddr& dst)
: src_addr_(src), dst_addr_(dst) {}
SimManagementFrame(const SimManagementFrame& mgmt_frame);
~SimManagementFrame() override;
// Frame type identifier
SimFrameType FrameType() const override;
// Frame subtype identifier for management frames
virtual SimMgmtFrameType MgmtFrameType() const = 0;
void AddSsidIe(const fuchsia_wlan_ieee80211::Ssid& ssid);
void AddCsaIe(const wlan_ieee80211_wire::WlanChannel& channel, uint8_t channel_switch_count);
void AddRawIes(cpp20::span<const uint8_t> raw_ies);
std::shared_ptr<InformationElement> FindIe(InformationElement::SimIeType ie_type) const;
void RemoveIe(InformationElement::SimIeType);
common::MacAddr src_addr_ = {};
common::MacAddr dst_addr_ = {};
std::list<std::shared_ptr<InformationElement>> IEs_;
std::vector<uint8_t> raw_ies_;
// This is a brief alternative for security related IEs since we don't include entire IE for
// security protocol such as WPA IE or RSNE IE.
enum SimSecProtoType sec_proto_type_ = SEC_PROTO_TYPE_OPEN;
private:
void AddIe(InformationElement::SimIeType ie_type, std::shared_ptr<InformationElement> ie);
};
class SimBeaconFrame : public SimManagementFrame {
public:
SimBeaconFrame() = default;
explicit SimBeaconFrame(const fuchsia_wlan_ieee80211::Ssid& ssid, const common::MacAddr& bssid);
SimBeaconFrame(const SimBeaconFrame& beacon);
~SimBeaconFrame() override;
SimMgmtFrameType MgmtFrameType() const override;
SimFrame* CopyFrame() const override;
common::MacAddr bssid_;
zx::duration interval_;
wlan::CapabilityInfo capability_info_;
};
class SimProbeReqFrame : public SimManagementFrame {
public:
SimProbeReqFrame() = default;
explicit SimProbeReqFrame(const common::MacAddr& src) : SimManagementFrame(src, {}) {}
SimProbeReqFrame(const SimProbeReqFrame& probe_req);
~SimProbeReqFrame() override;
SimMgmtFrameType MgmtFrameType() const override;
SimFrame* CopyFrame() const override;
};
class SimProbeRespFrame : public SimManagementFrame {
public:
SimProbeRespFrame() = default;
explicit SimProbeRespFrame(const common::MacAddr& src, const common::MacAddr& dst,
const fuchsia_wlan_ieee80211::Ssid& ssid);
SimProbeRespFrame(const SimProbeRespFrame& probe_resp);
~SimProbeRespFrame() override;
SimMgmtFrameType MgmtFrameType() const override;
SimFrame* CopyFrame() const override;
wlan::CapabilityInfo capability_info_;
};
class SimAssocReqFrame : public SimManagementFrame {
public:
SimAssocReqFrame() = default;
explicit SimAssocReqFrame(const common::MacAddr& src, const common::MacAddr bssid,
const fuchsia_wlan_ieee80211::Ssid& ssid)
: SimManagementFrame(src, {}), bssid_(bssid), ssid_(ssid) {}
SimAssocReqFrame(const SimAssocReqFrame& assoc_req);
~SimAssocReqFrame() override;
SimMgmtFrameType MgmtFrameType() const override;
SimFrame* CopyFrame() const override;
common::MacAddr bssid_;
fuchsia_wlan_ieee80211::Ssid ssid_;
};
class SimAssocRespFrame : public SimManagementFrame {
public:
SimAssocRespFrame() = default;
explicit SimAssocRespFrame(const common::MacAddr& src, const common::MacAddr& dst,
wlan_ieee80211_wire::StatusCode status)
: SimManagementFrame(src, dst), status_(status) {
capability_info_.set_ess(1);
}
SimAssocRespFrame(const SimAssocRespFrame& assoc_resp);
~SimAssocRespFrame() override;
SimMgmtFrameType MgmtFrameType() const override;
SimFrame* CopyFrame() const override;
wlan_ieee80211_wire::StatusCode status_;
wlan::CapabilityInfo capability_info_;
};
class SimDisassocReqFrame : public SimManagementFrame {
public:
SimDisassocReqFrame() = default;
explicit SimDisassocReqFrame(const common::MacAddr& src, const common::MacAddr& dst,
wlan_ieee80211_wire::ReasonCode reason)
: SimManagementFrame(src, dst), reason_(reason) {}
SimDisassocReqFrame(const SimDisassocReqFrame& disassoc_req);
~SimDisassocReqFrame() override;
SimMgmtFrameType MgmtFrameType() const override;
SimFrame* CopyFrame() const override;
wlan_ieee80211_wire::ReasonCode reason_;
};
// Only one type of authentication frame for request and response
class SimAuthFrame : public SimManagementFrame {
public:
SimAuthFrame() = default;
explicit SimAuthFrame(const common::MacAddr& src, const common::MacAddr& dst, uint16_t seq,
SimAuthType auth_type, wlan_ieee80211_wire::StatusCode status)
: SimManagementFrame(src, dst), seq_num_(seq), auth_type_(auth_type), status_(status) {}
SimAuthFrame(const SimAuthFrame& auth);
~SimAuthFrame() override;
SimMgmtFrameType MgmtFrameType() const override;
SimFrame* CopyFrame() const override;
void AddChallengeText(cpp20::span<const uint8_t> text);
uint16_t seq_num_;
SimAuthType auth_type_;
wlan_ieee80211_wire::StatusCode status_;
// Payload for authentication frame, especially being used for SAE process for now.
std::vector<uint8_t> payload_;
};
class SimDeauthFrame : public SimManagementFrame {
public:
SimDeauthFrame() = default;
explicit SimDeauthFrame(const common::MacAddr& src, const common::MacAddr& dst,
wlan_ieee80211_wire::ReasonCode reason)
: SimManagementFrame(src, dst), reason_(reason) {}
SimDeauthFrame(const SimDeauthFrame& deauth);
~SimDeauthFrame() override;
SimMgmtFrameType MgmtFrameType() const override;
SimFrame* CopyFrame() const override;
wlan_ieee80211_wire::ReasonCode reason_;
};
// IEEE 802.11-2020 9.3.3.7
class SimReassocReqFrame : public SimManagementFrame {
public:
SimReassocReqFrame() = default;
explicit SimReassocReqFrame(const common::MacAddr& src, const common::MacAddr bssid)
: SimManagementFrame(src, {}), bssid_(bssid) {}
SimReassocReqFrame(const SimReassocReqFrame& reassoc_req);
~SimReassocReqFrame() override;
SimMgmtFrameType MgmtFrameType() const override;
SimFrame* CopyFrame() const override;
common::MacAddr bssid_;
};
// IEEE 802.11-2020 9.3.3.8
class SimReassocRespFrame : public SimManagementFrame {
public:
SimReassocRespFrame() = default;
explicit SimReassocRespFrame(const common::MacAddr& src, const common::MacAddr& dst,
wlan_ieee80211_wire::StatusCode status)
: SimManagementFrame(src, dst), status_(status) {
capability_info_.set_ess(1);
}
SimReassocRespFrame(const SimReassocRespFrame& reassoc_resp);
~SimReassocRespFrame() override;
SimMgmtFrameType MgmtFrameType() const override;
SimFrame* CopyFrame() const override;
wlan_ieee80211_wire::StatusCode status_;
wlan::CapabilityInfo capability_info_;
};
// IEEE 802.11-2020 9.3.3.13.
class SimActionFrame : public SimManagementFrame {
public:
// IEEE 802.11-2020 Table 9-51.
enum SimActionCategory {
WNM,
};
explicit SimActionFrame(const common::MacAddr& src, const common::MacAddr& dst,
SimActionCategory category)
: SimManagementFrame(src, dst), category_(category) {}
SimActionFrame(const SimActionFrame& action);
~SimActionFrame() override;
SimMgmtFrameType MgmtFrameType() const override;
SimFrame* CopyFrame() const override;
SimActionCategory ActionCategory() const;
private:
SimActionCategory category_;
};
// IEEE 802.11-2020 9.6.13.
class SimWnmActionFrame : public SimActionFrame {
public:
// IEEE 802.11-2020 9.6.13.1
enum SimWnmAction {
BSS_TRANSITION_MANAGEMENT_REQUEST,
};
explicit SimWnmActionFrame(const common::MacAddr& src, const common::MacAddr& dst)
: SimActionFrame(src, dst, SimActionCategory::WNM) {}
SimWnmActionFrame(const SimWnmActionFrame& wnm_action);
~SimWnmActionFrame() override;
SimFrame* CopyFrame() const override;
SimWnmAction WnmAction() const { return wnm_action_; }
private:
// Only WNM action, later will include other actions and will be non const.
const SimWnmAction wnm_action_ = BSS_TRANSITION_MANAGEMENT_REQUEST;
};
// IEEE 802.11-2020 Fig. 9-924.
struct SimBtmReqMode {
bool preferred_candidate_list_included = false;
};
// Info about a neighboring AP. IEEE 802.11-2020 9.4.2.36.
struct SimNeighborReportElement {
common::MacAddr bssid;
uint8_t operating_class; // IEEE 802.11-2020 Annex E
uint8_t channel_number;
};
// IEEE 802.11-2020 9.6.13.9.
class SimBtmReqFrame : public SimWnmActionFrame {
public:
explicit SimBtmReqFrame(const common::MacAddr& src, const common::MacAddr& dst,
const SimBtmReqMode& request_mode,
const std::vector<SimNeighborReportElement>& candidate_list)
: SimWnmActionFrame(src, dst), request_mode_(request_mode), candidate_list_(candidate_list) {}
SimBtmReqFrame(const SimBtmReqFrame& btm_req);
~SimBtmReqFrame() override;
SimFrame* CopyFrame() const override;
std::vector<SimNeighborReportElement> CandidateList() const;
private:
SimBtmReqMode request_mode_;
// IEEE 802.11-2020 9.4.2.36
std::vector<SimNeighborReportElement> candidate_list_;
};
// No support for contention-free data frames, aggregation or fragmentation for now
// Assumes singular MSDU frames
// reassembly, decryption also not supported
class SimDataFrame : public SimFrame {
public:
enum SimDataFrameType { FRAME_TYPE_QOS_DATA };
SimDataFrame() = default;
explicit SimDataFrame(bool toDS, bool fromDS, common::MacAddr addr1, common::MacAddr addr2,
common::MacAddr addr3, std::optional<uint16_t> qosControl,
std::vector<uint8_t> payload)
: toDS_(toDS),
fromDS_(fromDS),
addr1_(addr1),
addr2_(addr2),
addr3_(addr3),
qosControl_(qosControl),
payload_(payload) {}
SimDataFrame(const SimDataFrame& data_frame);
~SimDataFrame() override;
SimFrameType FrameType() const override;
// Frame subtype identifier for data frames
virtual SimDataFrameType DataFrameType() const = 0;
// Control bits
bool toDS_;
bool fromDS_;
// IEEE Std. 802.11-2016, 9.3.2.1 Table 9-26
common::MacAddr addr1_;
common::MacAddr addr2_;
common::MacAddr addr3_;
std::optional<common::MacAddr> addr4_;
std::optional<uint16_t> qosControl_;
// MAC Payload
std::vector<uint8_t> payload_;
};
class SimQosDataFrame : public SimDataFrame {
public:
SimQosDataFrame() = default;
explicit SimQosDataFrame(bool toDS, bool fromDS, common::MacAddr addr1, common::MacAddr addr2,
common::MacAddr addr3, std::optional<uint16_t> qosControl,
std::vector<uint8_t> payload)
: SimDataFrame(toDS, fromDS, addr1, addr2, addr3, qosControl, payload) {}
SimQosDataFrame(const SimQosDataFrame& qos_data);
~SimQosDataFrame() override;
SimDataFrameType DataFrameType() const override;
SimFrame* CopyFrame() const override;
};
} // namespace wlan::simulation
#endif // SRC_CONNECTIVITY_WLAN_DRIVERS_TESTING_LIB_SIM_ENV_SIM_FRAME_H_