1#include "location_table.hpp"
10static_assert(std::numeric_limits<double>::has_quiet_NaN,
"quiet NaN value unavailable");
12LocationTableEntry::LocationTableEntry(
const Runtime& rt) :
13 m_runtime(rt), m_is_neighbour(Clock::time_point::min()), m_has_position_vector(false),
14 m_pdr(
std::numeric_limits<double>::quiet_NaN()), m_pdr_update(rt.now())
18StationType LocationTableEntry::station_type()
const
20 return geonet_address().station_type();
23const Address& LocationTableEntry::geonet_address()
const
25 return m_position_vector.gn_addr;
28const MacAddress& LocationTableEntry::link_layer_address()
const
30 return geonet_address().mid();
33bool LocationTableEntry::is_neighbour()
const
35 return m_is_neighbour > m_runtime.now();
38void LocationTableEntry::update_pdr(std::size_t packet_size,
double beta)
40 using namespace vanetza::units;
42 if (std::isnan(m_pdr)) {
44 m_pdr_update = m_runtime.now();
45 }
else if (beta > 0.0 && beta < 1.0) {
46 const std::chrono::duration<double> time_period = m_runtime.now() - m_pdr_update;
47 if (time_period.count() > 0.0) {
48 double instant_pdr = packet_size / time_period.count();
50 m_pdr += (1.0 - beta) * instant_pdr;
51 m_pdr_update = m_runtime.now();
59 m_has_position_vector =
true;
60 m_position_vector = pv;
69 if (has_position_vector()) {
70 if (get_position_vector().timestamp < lpv.timestamp) {
71 return set_position_vector(lpv);
74 return set_position_vector(lpv);
80void LocationTableEntry::set_neighbour(
bool flag)
82 m_is_neighbour = flag ? Clock::time_point::max() : Clock::time_point::min();
85void LocationTableEntry::set_neighbour(
bool flag, Clock::duration expiry)
87 if (flag && expiry > Clock::duration::zero()) {
88 m_is_neighbour = m_runtime.now() + expiry;
95LocationTable::LocationTable(
const MIB& mib,
Runtime& rt) :
98 m_table.set_lifetime(std::chrono::seconds(mib.itsGnLifetimeLocTE / units::si::seconds));
101bool LocationTable::has_entry(
const Address& addr)
const
106bool LocationTable::has_neighbours()
const
108 bool found_neighbour =
false;
109 for (
const auto& entry : m_table.
map()) {
110 if (entry.second.is_neighbour()) {
111 found_neighbour =
true;
115 return found_neighbour;
118auto LocationTable::neighbours() const -> neighbour_range
120 const entry_predicate neighbour_predicate =
121 [](
const MacAddress&,
const LocationTableEntry& entry) {
122 return entry.is_neighbour();
124 return filter(neighbour_predicate);
127auto LocationTable::filter(
const entry_predicate& predicate)
const -> entry_range
129 using namespace boost::adaptors;
130 std::function<bool(
const typename table_type::value_type&)> filter_fn =
131 [predicate](
const typename table_type::value_type& v) {
132 return predicate(v.first, v.second);
134 return m_table.map() | filtered(filter_fn) | map_values;
137void LocationTable::visit(
const entry_visitor& visitor)
const
139 for (
const auto& entry : m_table.
map()) {
140 visitor(entry.first, entry.second);
144LocationTableEntry& LocationTable::update(
const LongPositionVector& lpv)
146 LocationTableEntry* entry = m_table.
get_value_ptr(lpv.gn_addr.mid());
147 if (entry && entry->has_position_vector()) {
148 if (entry->update_position_vector(lpv)) {
149 m_table.
refresh(lpv.gn_addr.mid());
152 entry = &m_table.
refresh(lpv.gn_addr.mid());
158LocationTableEntry& LocationTable::get_or_create_entry(
const Address& addr)
163LocationTableEntry& LocationTable::get_or_create_entry(
const MacAddress& mac)
168const LocationTableEntry* LocationTable::get_entry(
const Address& addr)
const
173const LocationTableEntry* LocationTable::get_entry(
const MacAddress& mac)
const
178const LongPositionVector* LocationTable::get_position(
const Address& addr)
const
180 return get_position(addr.mid());
183const LongPositionVector* LocationTable::get_position(
const MacAddress& mac)
const
185 const LongPositionVector* position =
nullptr;
187 if (entry && entry->has_position_vector()) {
bool update_position_vector(const LongPositionVector &pv)
const LongPositionVector & get_position_vector() const
bool has_value(const key_type &key) const
mapped_type & refresh(const key_type &key)
mapped_type & get_value(const key_type &key)
mapped_type * get_value_ptr(const key_type &key)