obu-firmware builds against the vanetza-idf C-ITS library, which until now came from the colleague's microbu-esp32c5 tree beside the repository and was not tracked here, so a clone of this repository could not build the firmware it ships. The library alone is now part of obu-firmware, as obu-firmware/external/vanetza-idf: their external/vanetza-idf at commit cf4b99f, unchanged (9775 files; see its PROVENANCE.md). CMake takes it from there by default; -DVANETZA_IDF_DIR still points the build elsewhere. The rest of the colleague's tree (their own VAM firmware, PKI tooling, station-link Python tools, the V2X2MAP bridge) stays out of this repository and gitignored; nothing is pushed to their repository. NOTES.md, docs/06, TODO.md and the pcap verifier's usage line point at the new location.
196 lines
5.0 KiB
C++
196 lines
5.0 KiB
C++
#include "location_table.hpp"
|
|
#include <chrono>
|
|
#include <limits>
|
|
|
|
namespace vanetza
|
|
{
|
|
namespace geonet
|
|
{
|
|
|
|
static_assert(std::numeric_limits<double>::has_quiet_NaN, "quiet NaN value unavailable");
|
|
|
|
LocationTableEntry::LocationTableEntry(const Runtime& rt) :
|
|
m_runtime(rt), m_is_neighbour(Clock::time_point::min()), m_has_position_vector(false),
|
|
m_pdr(std::numeric_limits<double>::quiet_NaN()), m_pdr_update(rt.now())
|
|
{
|
|
}
|
|
|
|
StationType LocationTableEntry::station_type() const
|
|
{
|
|
return geonet_address().station_type();
|
|
}
|
|
|
|
const Address& LocationTableEntry::geonet_address() const
|
|
{
|
|
return m_position_vector.gn_addr;
|
|
}
|
|
|
|
const MacAddress& LocationTableEntry::link_layer_address() const
|
|
{
|
|
return geonet_address().mid();
|
|
}
|
|
|
|
bool LocationTableEntry::is_neighbour() const
|
|
{
|
|
return m_is_neighbour > m_runtime.now();
|
|
}
|
|
|
|
void LocationTableEntry::update_pdr(std::size_t packet_size, double beta)
|
|
{
|
|
using namespace vanetza::units;
|
|
|
|
if (std::isnan(m_pdr)) {
|
|
m_pdr = 0.0;
|
|
m_pdr_update = m_runtime.now();
|
|
} else if (beta > 0.0 && beta < 1.0) {
|
|
const std::chrono::duration<double> time_period = m_runtime.now() - m_pdr_update;
|
|
if (time_period.count() > 0.0) {
|
|
double instant_pdr = packet_size / time_period.count();
|
|
m_pdr *= beta;
|
|
m_pdr += (1.0 - beta) * instant_pdr;
|
|
m_pdr_update = m_runtime.now();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool LocationTableEntry::set_position_vector(const LongPositionVector& pv)
|
|
{
|
|
if (is_valid(pv)) {
|
|
m_has_position_vector = true;
|
|
m_position_vector = pv;
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool LocationTableEntry::update_position_vector(const LongPositionVector& lpv)
|
|
{
|
|
if (has_position_vector()) {
|
|
if (get_position_vector().timestamp < lpv.timestamp) {
|
|
return set_position_vector(lpv);
|
|
}
|
|
} else {
|
|
return set_position_vector(lpv);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void LocationTableEntry::set_neighbour(bool flag)
|
|
{
|
|
m_is_neighbour = flag ? Clock::time_point::max() : Clock::time_point::min();
|
|
}
|
|
|
|
void LocationTableEntry::set_neighbour(bool flag, Clock::duration expiry)
|
|
{
|
|
if (flag && expiry > Clock::duration::zero()) {
|
|
m_is_neighbour = m_runtime.now() + expiry;
|
|
} else {
|
|
set_neighbour(flag);
|
|
}
|
|
}
|
|
|
|
|
|
LocationTable::LocationTable(const MIB& mib, Runtime& rt) :
|
|
m_table(rt, LocationTableEntryCreator(rt))
|
|
{
|
|
m_table.set_lifetime(std::chrono::seconds(mib.itsGnLifetimeLocTE / units::si::seconds));
|
|
}
|
|
|
|
bool LocationTable::has_entry(const Address& addr) const
|
|
{
|
|
return m_table.has_value(addr.mid());
|
|
}
|
|
|
|
bool LocationTable::has_neighbours() const
|
|
{
|
|
bool found_neighbour = false;
|
|
for (const auto& entry : m_table.map()) {
|
|
if (entry.second.is_neighbour()) {
|
|
found_neighbour = true;
|
|
break;
|
|
}
|
|
}
|
|
return found_neighbour;
|
|
}
|
|
|
|
auto LocationTable::neighbours() const -> neighbour_range
|
|
{
|
|
const entry_predicate neighbour_predicate =
|
|
[](const MacAddress&, const LocationTableEntry& entry) {
|
|
return entry.is_neighbour();
|
|
};
|
|
return filter(neighbour_predicate);
|
|
}
|
|
|
|
auto LocationTable::filter(const entry_predicate& predicate) const -> entry_range
|
|
{
|
|
using namespace boost::adaptors;
|
|
std::function<bool(const typename table_type::value_type&)> filter_fn =
|
|
[predicate](const typename table_type::value_type& v) {
|
|
return predicate(v.first, v.second);
|
|
};
|
|
return m_table.map() | filtered(filter_fn) | map_values;
|
|
}
|
|
|
|
void LocationTable::visit(const entry_visitor& visitor) const
|
|
{
|
|
for (const auto& entry : m_table.map()) {
|
|
visitor(entry.first, entry.second);
|
|
}
|
|
}
|
|
|
|
LocationTableEntry& LocationTable::update(const LongPositionVector& lpv)
|
|
{
|
|
LocationTableEntry* entry = m_table.get_value_ptr(lpv.gn_addr.mid());
|
|
if (entry && entry->has_position_vector()) {
|
|
if (entry->update_position_vector(lpv)) {
|
|
m_table.refresh(lpv.gn_addr.mid());
|
|
}
|
|
} else {
|
|
entry = &m_table.refresh(lpv.gn_addr.mid());
|
|
entry->update_position_vector(lpv);
|
|
}
|
|
return *entry;
|
|
}
|
|
|
|
LocationTableEntry& LocationTable::get_or_create_entry(const Address& addr)
|
|
{
|
|
return m_table.get_value(addr.mid());
|
|
}
|
|
|
|
LocationTableEntry& LocationTable::get_or_create_entry(const MacAddress& mac)
|
|
{
|
|
return m_table.get_value(mac);
|
|
}
|
|
|
|
const LocationTableEntry* LocationTable::get_entry(const Address& addr) const
|
|
{
|
|
return m_table.get_value_ptr(addr.mid());
|
|
}
|
|
|
|
const LocationTableEntry* LocationTable::get_entry(const MacAddress& mac) const
|
|
{
|
|
return m_table.get_value_ptr(mac);
|
|
}
|
|
|
|
const LongPositionVector* LocationTable::get_position(const Address& addr) const
|
|
{
|
|
return get_position(addr.mid());
|
|
}
|
|
|
|
const LongPositionVector* LocationTable::get_position(const MacAddress& mac) const
|
|
{
|
|
const LongPositionVector* position = nullptr;
|
|
auto* entry = m_table.get_value_ptr(mac);
|
|
if (entry && entry->has_position_vector()) {
|
|
position = &entry->get_position_vector();
|
|
}
|
|
return position;
|
|
}
|
|
|
|
} // namespace geonet
|
|
} // namespace vanetza
|
|
|