blob: f528cc6efa1004b73272892aa648ea0ce95bb115 [file] [log] [blame]
// Copyright 2017 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 GARNET_LIB_WLAN_MLME_INCLUDE_WLAN_MLME_AP_INFRA_BSS_H_
#define GARNET_LIB_WLAN_MLME_INCLUDE_WLAN_MLME_AP_INFRA_BSS_H_
#include <fuchsia/wlan/mlme/cpp/fidl.h>
#include <wlan/mlme/ap/beacon_sender.h>
#include <wlan/mlme/ap/bss_interface.h>
#include <wlan/mlme/ap/remote_client.h>
#include <wlan/mlme/ap/tim.h>
#include <wlan/mlme/device_interface.h>
#include <wlan/mlme/mac_frame.h>
#include <wlan/mlme/sequence.h>
#include <wlan/mlme/service.h>
#include <wlan/common/macaddr.h>
#include <zircon/types.h>
#include <queue>
namespace wlan {
class ObjectId;
template <typename T> class MlmeMsg;
// An infrastructure BSS which keeps track of its client and owned by the AP
// MLME.
class InfraBss : public BssInterface, public RemoteClient::Listener {
public:
InfraBss(DeviceInterface* device, fbl::unique_ptr<BeaconSender> bcn_sender,
const common::MacAddr& bssid, fbl::unique_ptr<Timer> timer);
virtual ~InfraBss();
// Starts the BSS. Beacons will be sent and incoming frames are processed.
void Start(const MlmeMsg<::fuchsia::wlan::mlme::StartRequest>&);
// Stops the BSS. All incoming frames are dropped and Beacons are not sent
// anymore.
void Stop();
bool IsStarted();
// Entry point for ethernet and WLAN frames.
void HandleAnyFrame(fbl::unique_ptr<Packet>);
// Entry point for MLME messages except START-/STOP.request which are handled in the `ApMlme`.
zx_status_t HandleMlmeMsg(const BaseMlmeMsg& msg);
zx_status_t ScheduleTimeout(wlan_tu_t tus, const common::MacAddr& client_addr,
TimeoutId* id) override;
void CancelTimeout(TimeoutId id) override;
zx_status_t HandleTimeout();
// BssInterface implementation
const common::MacAddr& bssid() const override;
uint64_t timestamp() override;
zx_status_t SendMgmtFrame(MgmtFrame<>&& mgmt_frame) override;
zx_status_t SendDataFrame(DataFrame<>&& data_frame, uint32_t flags = 0) override;
zx_status_t DeliverEthernet(Span<const uint8_t> frame) override;
seq_t NextSeq(const MgmtFrameHeader& hdr) override;
seq_t NextSeq(const MgmtFrameHeader& hdr, uint8_t aci) override;
seq_t NextSeq(const DataFrameHeader& hdr) override;
std::optional<DataFrame<LlcHeader>> EthToDataFrame(const EthFrame& eth_frame,
bool needs_protection) override;
void OnPreTbtt() override;
void OnBcnTxComplete() override;
bool IsRsn() const override;
HtConfig Ht() const override;
const Span<const SupportedRate> Rates() const override;
wlan_channel_t Chan() const override { return chan_; }
private:
using ClientMap = std::unordered_map<common::MacAddr, fbl::unique_ptr<RemoteClientInterface>,
common::MacAddrHasher>;
void HandleEthFrame(EthFrame&&);
void HandleAnyWlanFrame(fbl::unique_ptr<Packet>);
void HandleAnyMgmtFrame(MgmtFrame<>&&);
void HandleAnyDataFrame(DataFrame<>&&);
void HandleAnyCtrlFrame(CtrlFrame<>&&);
void HandleNewClientAuthAttempt(const MgmtFrameView<Authentication>&);
zx_status_t HandleMlmeSetKeysReq(const MlmeMsg<::fuchsia::wlan::mlme::SetKeysRequest>&);
bool HasClient(const common::MacAddr& client);
RemoteClientInterface* GetClient(const common::MacAddr& addr);
// Maximum number of group addressed packets buffered while at least one
// client is dozing.
// TODO(NET-687): Find good BU limit.
static constexpr size_t kMaxGroupAddressedBu = 128;
// RemoteClient::Listener implementation
void HandleClientFailedAuth(const common::MacAddr& client_addr) override;
void HandleClientDeauth(const common::MacAddr& client_addr) override;
void HandleClientDisassociation(aid_t aid) override;
void HandleClientBuChange(const common::MacAddr& client_addr, aid_t aid,
size_t bu_count) override;
void StopTrackingClient(const common::MacAddr& client_addr);
// Returns `true` if a frame with the given destination should get buffered.
bool ShouldBufferFrame(const common::MacAddr& dest) const;
zx_status_t BufferFrame(fbl::unique_ptr<Packet> packet);
zx_status_t SendNextBu();
const common::MacAddr bssid_;
DeviceInterface* device_;
fbl::unique_ptr<BeaconSender> bcn_sender_;
zx_time_t started_at_;
ClientMap clients_;
Sequence seq_;
// Queue which holds buffered non-GCR-SP frames when at least one client is
// dozing.
std::queue<fbl::unique_ptr<Packet>> bu_queue_;
PsCfg ps_cfg_;
wlan_channel_t chan_;
// MLME-START.request holds all information required to correctly configure
// and start a BSS.
::fuchsia::wlan::mlme::StartRequest start_req_;
TimerManager<common::MacAddr> timer_mgr_;
};
} // namespace wlan
#endif // GARNET_LIB_WLAN_MLME_INCLUDE_WLAN_MLME_AP_INFRA_BSS_H_