blob: cb5c6f049643b70224074d94a1fe8bb15dbc90cc [file] [log] [blame]
// Copyright 2019 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-env.h"
#include <zircon/assert.h>
namespace wlan::simulation {
uint64_t Environment::event_count_ = 0;
Environment::Environment()
: signal_loss_model_(std::unique_ptr<SignalLossModel>(new LogSignalLossModel())){};
void Environment::Run() {
while (!events_.empty()) {
auto event = std::move(events_.front());
events_.pop_front();
// Make sure that time is always moving forward
ZX_ASSERT(event->time >= time_);
time_ = event->time;
// Send event to client who requested it
event->requester->ReceiveNotification(event->payload);
}
}
void Environment::Tx(const SimFrame* frame, const WlanTxInfo& tx_info, StationIfc* sender) {
for (auto& sta : stations_) {
if (sta.first != sender) {
double signal_strength =
signal_loss_model_->CalcSignalStrength(stations_.at(sender), stations_.at(sta.first));
WlanRxInfo rx_info = {.channel = tx_info.channel, .signal_strength = signal_strength};
sta.first->Rx(frame, rx_info);
}
}
}
zx_status_t Environment::ScheduleNotification(StationIfc* sta, zx::duration delay, void* payload,
uint64_t* id_out) {
uint64_t id = event_count_++;
// Disallow past events
if (delay < zx::usec(0)) {
return ZX_ERR_INVALID_ARGS;
}
auto event = std::make_unique<EnvironmentEvent>();
event->id = id;
event->time = time_ + delay;
event->requester = sta;
event->payload = payload;
// Keep our events sorted in ascending order of absolute time. When multiple events are
// scheduled for the same time, the first requested will be processed first.
auto event_iter = events_.begin();
while (event_iter != events_.end() && (*event_iter)->time <= event->time) {
event_iter++;
}
events_.insert(event_iter, std::move(event));
if (id_out != nullptr) {
*id_out = id;
}
return ZX_OK;
}
// Since all events are processed synchronously, we don't have to worry about locking.
zx_status_t Environment::CancelNotification(StationIfc* sta, uint64_t id) {
for (auto& event_iter : events_) {
if (event_iter->requester == sta && event_iter->id == id) {
events_.remove(event_iter);
return ZX_OK;
}
}
return ZX_ERR_NOT_FOUND;
}
} // namespace wlan::simulation