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();
35 return m_is_neighbour > m_runtime.now();
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;
82 m_is_neighbour = flag ? Clock::time_point::max() : Clock::time_point::min();
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);
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());
153 entry->update_position_vector(lpv);
160 return m_table.get_value(addr.mid());
165 return m_table.get_value(mac);
170 return m_table.get_value_ptr(addr.mid());
175 return m_table.get_value_ptr(mac);
180 return get_position(addr.mid());
185 const LongPositionVector* position =
nullptr;
186 auto* entry = m_table.get_value_ptr(mac);
187 if (entry && entry->has_position_vector()) {
188 position = &entry->get_position_vector();
void update_pdr(std::size_t packet_size, double beta=0.5)
bool update_position_vector(const LongPositionVector &pv)
bool has_position_vector() const
const LongPositionVector & get_position_vector() const
bool is_neighbour() const
bool set_position_vector(const LongPositionVector &pv)
void set_neighbour(bool flag)
bool has_value(const key_type &key) const