Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Add multichannel operation with explicit channel selection #60

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions vanetza/common/channel.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef CHANNEL_HPP
#define CHANNEL_HPP

#include <cstdint>

namespace vanetza
{

using Channel = int;

namespace channel
{

/**
* Channel assigned for ETSI ITS
* \see TS 102 965 V1.3.1 Annex A
*/
constexpr Channel SCH0 = 180;
constexpr Channel CCH = SCH0;

constexpr Channel SCH1 = 176;
constexpr Channel SCH2 = 178;

constexpr Channel SCH3 = 174;
constexpr Channel SCH4 = 172;

constexpr Channel SCH5 = 182;
constexpr Channel SCH6 = 184;

} // namespace channel
} // namespace vanetza

#endif /* CHANNEL_HPP */

2 changes: 2 additions & 0 deletions vanetza/geonet/data_request.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef DATA_REQUEST_HPP_3JYISVXB
#define DATA_REQUEST_HPP_3JYISVXB

#include <vanetza/common/channel.hpp>
#include <vanetza/common/its_aid.hpp>
#include <vanetza/geonet/address.hpp>
#include <vanetza/geonet/areas.hpp>
Expand Down Expand Up @@ -45,6 +46,7 @@ struct DataRequest
boost::optional<Repetition> repetition;
unsigned max_hop_limit;
TrafficClass traffic_class;
Channel channel;
};

/**
Expand Down
2 changes: 2 additions & 0 deletions vanetza/geonet/link_layer.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef LINK_LAYER_HPP_F2JBRUTL
#define LINK_LAYER_HPP_F2JBRUTL

#include <vanetza/common/channel.hpp>
#include <vanetza/net/mac_address.hpp>

namespace vanetza
Expand All @@ -12,6 +13,7 @@ struct LinkLayer
{
MacAddress sender;
MacAddress destination;
Channel channel;
};

} // namespace geonet
Expand Down
140 changes: 107 additions & 33 deletions vanetza/geonet/location_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,33 @@ namespace geonet

static_assert(std::numeric_limits<double>::has_quiet_NaN, "quiet NaN value unavailable");

LinkInfoEntry::LinkInfoEntry(const Runtime& rt) :
m_runtime(rt),
m_pdr(std::numeric_limits<double>::quiet_NaN()), m_pdr_update(rt.now())
{
}

void LinkInfoEntry::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();
}
}
}

LocationTableEntry::LocationTableEntry(const Runtime& rt) :
m_runtime(rt), m_is_neighbour(false), m_has_position_vector(false),
m_pdr(std::numeric_limits<double>::quiet_NaN()), m_pdr_update(rt.now())
m_link_info(rt, LinkInfoEntryCreator(rt))
{
}

Expand All @@ -25,27 +49,27 @@ const Address& LocationTableEntry::geonet_address() const
return m_position_vector.gn_addr;
}

const MacAddress& LocationTableEntry::link_layer_address() const
const MacAddress& LocationTableEntry::link_layer_address(Channel channel) const
{
return geonet_address().mid();
auto link_info = m_link_info.get_value_ptr(channel);
return link_info->link_layer_address();
}

void LocationTableEntry::update_pdr(std::size_t packet_size, double beta)
bool LocationTableEntry::has_channel(Channel channel) const
{
using namespace vanetza::units;
return m_link_info.has_value(channel);
}

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();
}
}
double LocationTableEntry::get_pdr(Channel channel) const
{
auto link_info = m_link_info.get_value_ptr(channel);
return link_info->get_pdr();
}

void LocationTableEntry::update_pdr(Channel channel, std::size_t packet_size, double beta)
{
LinkInfoEntry& link_info = m_link_info.get_value(channel);
link_info.update_pdr(packet_size, beta);
}

void LocationTableEntry::set_position_vector(const LongPositionVector& pv)
Expand All @@ -54,6 +78,14 @@ void LocationTableEntry::set_position_vector(const LongPositionVector& pv)
m_position_vector = pv;
}

void LocationTableEntry::add_link(const Channel channel, const MacAddress& mac)
{
m_link_info.drop_expired();
LinkInfoEntry& link_info = m_link_info.get_value(channel);
link_info.set_link_layer_address(mac);
link_info.set_channel(channel);
}

bool LocationTableEntry::update_position_vector(const LongPositionVector& lpv)
{
if (has_position_vector()) {
Expand All @@ -76,14 +108,15 @@ void LocationTableEntry::set_neighbour(bool flag)


LocationTable::LocationTable(const MIB& mib, Runtime& rt) :
m_table(rt, LocationTableEntryCreator(rt))
m_table(rt, LocationTableEntryCreator(rt)),
m_link_table(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());
return m_table.has_value(addr);
}

bool LocationTable::has_neighbours() const
Expand All @@ -98,15 +131,38 @@ bool LocationTable::has_neighbours() const
return found_neighbour;
}

bool LocationTable::has_neighbours(Channel channel) const
{
bool found_neighbour = false;
for (const auto& entry : m_table.map()) {
if (entry.second.is_neighbour()) {
if (entry.second.has_channel(channel)) {
found_neighbour = true;
break;
}
}
}
return found_neighbour;
}

auto LocationTable::neighbours() const -> neighbour_range
{
const entry_predicate neighbour_predicate =
[](const MacAddress&, const LocationTableEntry& entry) {
[](const Address&, const LocationTableEntry& entry) {
return entry.is_neighbour();
};
return filter(neighbour_predicate);
}

auto LocationTable::neighbours(Channel channel) const -> neighbour_range
{
const entry_predicate neighbour_predicate =
[channel](const Address&, const LocationTableEntry& entry) {
return entry.has_channel(channel);
};
return filter(neighbour_predicate);
}

auto LocationTable::filter(const entry_predicate& predicate) const -> entry_range
{
using namespace boost::adaptors;
Expand All @@ -124,55 +180,73 @@ void LocationTable::visit(const entry_visitor& visitor) const
}
}

void LocationTable::drop_expired()
{
m_link_table.drop_expired();
m_table.drop_expired();
}

void LocationTable::update(const Channel channel, const MacAddress& mac, const Address& addr)
{
LocationTableEntry& entry = m_table.get_value(addr);
entry.add_link(channel, mac);

LinkTableEntry& link_entry = m_link_table.get_value(mac);
link_entry.set_geonet_address(addr);
}

LocationTableEntry& LocationTable::update(const LongPositionVector& lpv)
{
LocationTableEntry* entry = m_table.get_value_ptr(lpv.gn_addr.mid());
LocationTableEntry* entry = m_table.get_value_ptr(lpv.gn_addr);
if (entry && entry->has_position_vector()) {
if (entry->update_position_vector(lpv)) {
m_table.refresh(lpv.gn_addr.mid());
m_table.refresh(lpv.gn_addr);
}
} else {
entry = &m_table.refresh(lpv.gn_addr.mid());
entry = &m_table.refresh(lpv.gn_addr);
entry->update_position_vector(lpv);
}
return *entry;
}

LocationTableEntry& LocationTable::get_or_create_entry(const Address& addr)
{
return m_table.get_value(addr.mid());
return m_table.get_value(addr);
}

LocationTableEntry& LocationTable::get_or_create_entry(const MacAddress& mac)
{
return m_table.get_value(mac);
auto addr = m_link_table.get_value(mac);
return m_table.get_value(addr.geonet_address());
}

const LocationTableEntry* LocationTable::get_entry(const Address& addr) const
{
return m_table.get_value_ptr(addr.mid());
return m_table.get_value_ptr(addr);
}

const LocationTableEntry* LocationTable::get_entry(const MacAddress& mac) const
{
return m_table.get_value_ptr(mac);
auto addr = m_link_table.get_value_ptr(mac);
return m_table.get_value_ptr(addr->geonet_address());
}

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);
auto* entry = m_table.get_value_ptr(addr);
if (entry && entry->has_position_vector()) {
position = &entry->get_position_vector();
}
return position;
}

const LongPositionVector* LocationTable::get_position(const MacAddress& mac) const
{
auto addr = m_link_table.get_value_ptr(mac);
return get_position(addr->geonet_address());
}

} // namespace geonet
} // namespace vanetza

Loading