Skip to content

Commit

Permalink
geonet: process TSB packets
Browse files Browse the repository at this point in the history
  • Loading branch information
riebl committed Jul 14, 2024
1 parent c6f7528 commit a68dd95
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 7 deletions.
1 change: 1 addition & 0 deletions vanetza/geonet/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ set(CXX_SOURCES
shb_header.cpp
timestamp.cpp
traffic_class.cpp
tsb_header.cpp
variant_pdu.cpp
)

Expand Down
7 changes: 4 additions & 3 deletions vanetza/geonet/header_variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@
#include <vanetza/geonet/beacon_header.hpp>
#include <vanetza/geonet/gbc_header.hpp>
#include <vanetza/geonet/shb_header.hpp>
#include <vanetza/geonet/tsb_header.hpp>
#include <boost/variant/variant.hpp>

namespace vanetza
{
namespace geonet
{

typedef boost::variant<BeaconHeader, GeoBroadcastHeader, ShbHeader> HeaderVariant;
typedef boost::variant<BeaconHeader&, GeoBroadcastHeader&, ShbHeader&> HeaderRefVariant;
typedef boost::variant<const BeaconHeader&, const GeoBroadcastHeader&, const ShbHeader&> HeaderConstRefVariant;
typedef boost::variant<BeaconHeader, GeoBroadcastHeader, ShbHeader, TsbHeader> HeaderVariant;
typedef boost::variant<BeaconHeader&, GeoBroadcastHeader&, ShbHeader&, TsbHeader&> HeaderRefVariant;
typedef boost::variant<const BeaconHeader&, const GeoBroadcastHeader&, const ShbHeader&, const TsbHeader&> HeaderConstRefVariant;

/** \brief get the length of the underlying header type
*
Expand Down
4 changes: 3 additions & 1 deletion vanetza/geonet/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ std::size_t Parser::parse_extended(HeaderVariant& extended, HeaderType ht)
case HeaderType::TSB_Single_Hop:
bytes = deserialize_extended<ShbHeader>(m_archive, extended);
break;
case HeaderType::TSB_Multi_Hop:
bytes = deserialize_extended<TsbHeader>(m_archive, extended);
break;
case HeaderType::GeoBroadcast_Circle:
case HeaderType::GeoBroadcast_Rect:
case HeaderType::GeoBroadcast_Elip:
Expand All @@ -102,7 +105,6 @@ std::size_t Parser::parse_extended(HeaderVariant& extended, HeaderType ht)
case HeaderType::GeoAnycast_Circle:
case HeaderType::GeoAnycast_Rect:
case HeaderType::GeoAnycast_Elip:
case HeaderType::TSB_Multi_Hop:
case HeaderType::LS_Request:
case HeaderType::LS_Reply:
// unimplemented types
Expand Down
2 changes: 2 additions & 0 deletions vanetza/geonet/pdu_variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <vanetza/geonet/beacon_header.hpp>
#include <vanetza/geonet/gbc_header.hpp>
#include <vanetza/geonet/shb_header.hpp>
#include <vanetza/geonet/tsb_header.hpp>
#include <boost/variant.hpp>

namespace vanetza
Expand All @@ -13,6 +14,7 @@ namespace geonet
{

typedef ExtendedPdu<ShbHeader> ShbPdu;
typedef ExtendedPdu<TsbHeader> TsbPdu;
typedef ExtendedPdu<BeaconHeader> BeaconPdu;
typedef ExtendedPdu<GeoBroadcastHeader> GbcPdu;

Expand Down
108 changes: 107 additions & 1 deletion vanetza/geonet/router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,10 +545,20 @@ void Router::indicate_extended(IndicationContext& ctx, const CommonHeader& commo

auto& pdu = m_context.pdu();
ExtendedPduConstRefs<ShbHeader> shb_pdu(pdu.basic(), pdu.common(), shb, pdu.secured());

return m_router.process_extended(shb_pdu, m_packet, m_context.link_layer());
}

bool operator()(const TsbHeader& tsb)
{
DataIndication& indication = m_context.service_primitive();
indication.transport_type = TransportType::TSB;
indication.source_position = static_cast<ShortPositionVector>(tsb.source_position);

auto& pdu = m_context.pdu();
ExtendedPduConstRefs<TsbHeader> tsb_pdu(pdu.basic(), pdu.common(), tsb, pdu.secured());
return m_router.process_extended(tsb_pdu, m_packet, m_context.link_layer());
}

bool operator()(const GeoBroadcastHeader& gbc)
{
DataIndication& indication = m_context.service_primitive();
Expand Down Expand Up @@ -1000,6 +1010,102 @@ bool Router::process_extended(const ExtendedPduConstRefs<ShbHeader>& pdu, const
return true;
}

bool Router::process_extended(const ExtendedPduConstRefs<TsbHeader>& pdu, const UpPacket& packet, const LinkLayer& ll)
{
const TsbHeader& tsb = pdu.extended();
const Address& source_addr = tsb.source_position.gn_addr;

// remember if LocTE(SO) exists (5) before duplicate packet detection might (3) silently create an entry
const bool locte_exists = m_location_table.has_entry(source_addr);

// step 3: execute duplicate packet detection
if (detect_duplicate_packet(source_addr, tsb.sequence_number)) {
// discard packet and omit execution of further steps
return false;
}

// step 4: execute duplicate address detection
if (m_mib.vanetzaMultiHopDuplicateAddressDetection) {
// Be careful, DAD is broken with address mode AUTO for multi-hop communication
detect_duplicate_address(source_addr, ll.sender);
}

// step 5a & step 6a (make sure IS_NEIGHBOUR is false for new location table entry)
auto& source_entry = m_location_table.update(tsb.source_position);
if (!locte_exists) {
// step 5b only
source_entry.set_neighbour(false);
}

// step 5c and step 6b
const std::size_t packet_size = size(packet, OsiLayer::Network, OsiLayer::Application);
source_entry.update_pdr(packet_size, m_mib.itsGnMaxPacketDataRateEmaBeta);

// step 7: packet is passed up depending on return value of this method

// step 8a: TODO: flush SO LS packet buffer if LS_pending, reset LS_pending
// step 8b: flush UC forwarding packet buffer
flush_unicast_forwarding_buffer(source_addr);

// step 9: discard packet (no forwarding) if hop limit is reached
if (pdu.basic().hop_limit <= 1) {
// step 9a: discard packet and omit execution of further steps
forwarding_stopped(ForwardingStopReason::Hop_Limit);
return true;
} else if (m_mib.itsGnMaxPacketDataRate < std::numeric_limits<decltype(m_mib.itsGnMaxPacketDataRate)>::max()) {
// do packet data rate checks (annex B.2) if set maximum rate is not "infinity" (i.e. max unsigned value)
if (source_entry.get_pdr() > m_mib.itsGnMaxPacketDataRate * 1000.0) {
forwarding_stopped(ForwardingStopReason::Source_PDR);
return true; // omit forwarding, source exceeds PDR limit
} else if (const auto* sender_entry = m_location_table.get_entry(ll.sender)) {
if (sender_entry->get_pdr() > m_mib.itsGnMaxPacketDataRate * 1000.0) {
forwarding_stopped(ForwardingStopReason::Sender_PDR);
return true; // omit forwarding, sender exceeds PDR limit
}
}
}

// step 9b: update hop limit in basic header
auto fwd_dup = create_forwarding_duplicate(pdu, packet);
TsbPdu& fwd_pdu = get_pdu(fwd_dup);
--fwd_pdu.basic().hop_limit;
assert(fwd_pdu.basic().hop_limit + 1 == pdu.basic().hop_limit);

auto transmit = [this](PendingPacket<TsbPdu>::Packet&& packet) {
// step 11: execute media-dependent procedures
execute_media_procedures(m_mib.itsGnIfType);

// step 12: pass down to link-layer
std::unique_ptr<Pdu> pdu;
std::unique_ptr<DownPacket> payload;
std::tie(pdu, payload) = std::move(packet);

dcc::DataRequest request;
request.destination = cBroadcastMacAddress;
request.source = m_local_position_vector.gn_addr.mid();
request.dcc_profile = dcc::Profile::DP3;
request.ether_type = geonet::ether_type;
request.lifetime = clock_cast(pdu->basic().lifetime.decode());
pass_down(request, std::move(pdu), std::move(payload));
};

PendingPacket<TsbPdu> fwd_packet(std::move(fwd_dup), transmit);

// step 10: store & carry forwarding procedure
const bool scf = pdu.common().traffic_class.store_carry_forward();
if (scf && !m_location_table.has_neighbours()) {
PacketBuffer::data_ptr data { new PendingPacketBufferData<TsbPdu>(std::move(fwd_packet)) };
m_bc_forward_buffer.push(std::move(data), m_runtime.now());
return true; // step 10a: buffer packet and omit further steps
}

// immediately execute steps 11 & 12
std::move(fwd_packet).process();

// step 7: pass up TSB finally
return true;
}

bool Router::process_extended(const ExtendedPduConstRefs<BeaconHeader>& pdu, const UpPacket& packet, const LinkLayer& ll)
{
const BeaconHeader& beacon = pdu.extended();
Expand Down
10 changes: 10 additions & 0 deletions vanetza/geonet/router.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,16 @@ class Router
*/
bool process_extended(const ExtendedPduConstRefs<ShbHeader>&, const UpPacket&, const LinkLayer& ll);

/**
* \brief packet handling of received TSB packet
*
* \param pdu PDU with TSB header
* \param packet received packet
* \param ll link-layer control info
* \return pass up decision (true for all non-duplicate TSBs)
*/
bool process_extended(const ExtendedPduConstRefs<TsbHeader>&, const UpPacket&, const LinkLayer& ll);

/**
* \brief Process ExtendedHeader information.
* Update router's LocationTable and neighbour relationship.
Expand Down
26 changes: 26 additions & 0 deletions vanetza/geonet/tsb_header.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "tsb_header.hpp"
#include "serialization.hpp"

namespace vanetza
{
namespace geonet
{

constexpr std::size_t TsbHeader::length_bytes;

void serialize(const TsbHeader& hdr, OutputArchive& ar)
{
serialize(hdr.sequence_number, ar);
serialize(hdr.reserved, ar);
serialize(hdr.source_position, ar);
}

void deserialize(TsbHeader& hdr, InputArchive& ar)
{
deserialize(hdr.sequence_number, ar);
deserialize(hdr.reserved, ar);
deserialize(hdr.source_position, ar);
}

} // namespace geonet
} // namespace vanetza
6 changes: 4 additions & 2 deletions vanetza/geonet/tsb_header.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ struct TsbHeader
static constexpr std::size_t length_bytes = 4 + LongPositionVector::length_bytes;

SequenceNumber sequence_number;
uint16_t reserved;
uint16_t reserved = 0;
LongPositionVector source_position;
};

void serialize(const TsbHeader&, OutputArchive&);
void deserialize(TsbHeader&, InputArchive&);

} // namespace geonet
} // namespace vanetza

#endif /* TSB_HEADER_HPP_RS2USUPV */

0 comments on commit a68dd95

Please sign in to comment.