Files
MicrOBU/microbu-esp32c5/external/vanetza-idf/vanetza/geonet/cbf_packet_buffer.hpp
T
Ashin Walpola 0e9525162d Keep the colleague's microbu-esp32c5 tree in this repository
obu-firmware builds against vanetza-idf from microbu-esp32c5/external, but
that tree was gitignored, so a clone of this repository could not build the
firmware it ships. It is now committed here as ordinary files in its own
folder, microbu-esp32c5/: the colleague's commit cf4b99f plus the V2X2MAP
bridge's signature verification (--trust) used on the bench. Nothing is
fetched from or pushed to the colleague's repository; this repository and
its remotes carry everything. The folder's own .gitignore keeps build output,
downloaded components and private key material out, as it did there; the
committed file set is identical to that repository's tracked files.

The ESP32-C5 is still flashed from obu-firmware/, which only takes
vanetza-idf from microbu-esp32c5/, so the two stay separate folders.
FLASHING.md says how to take a newer version of the colleague's tree (copy
it over the folder, rebuild, test, commit).
2026-09-23 17:46:40 +02:00

203 lines
5.4 KiB
C++

#ifndef CBF_PACKET_BUFFER_HPP_MU3RK5V1
#define CBF_PACKET_BUFFER_HPP_MU3RK5V1
#include <vanetza/common/clock.hpp>
#include <vanetza/geonet/cbf_packet_identifier.hpp>
#include <vanetza/geonet/packet.hpp>
#include <vanetza/geonet/pending_packet.hpp>
#include <vanetza/geonet/pdu_variant.hpp>
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <boost/optional/optional.hpp>
#include <cstddef>
#include <list>
#include <memory>
// forward declarations
namespace vanetza
{
class Runtime;
namespace geonet
{
class Address;
class CbfCounter;
class CbfPacket;
class Lifetime;
/**
* CbfPacket enables handling of conventional packets in a CBF packet buffer.
* It contains a GeoBroadcast PDU and the network layer payload.
*/
class CbfPacket
{
public:
CbfPacket(PendingPacket<GbcPdu>&&, const MacAddress& sender);
CbfPacket(PendingPacket<GbcPdu, const MacAddress&>&&, const MacAddress& sender);
CbfPacket(CbfPacket&&) = default;
CbfPacket& operator=(CbfPacket&&) = default;
/**
* Get sender of buffered packet
* \return sender's link-layer address
*/
const MacAddress& sender() const;
/**
* Get source address of buffered packet
* \return source address
*/
const Address& source() const;
/**
* Get sequence number of buffered packet
* \return sequence number
*/
SequenceNumber sequence_number() const;
/**
* Reduce lifetime of buffered packet
* \param d reduce lifetime by this duration
* \return remaining lifetime
*/
Clock::duration reduce_lifetime(Clock::duration d);
/**
* Length of packet data in bytes (PDU including payload)
* \return size of packet on wire
*/
std::size_t length() const;
PendingPacket<GbcPdu> packet() && { return std::move(m_packet); }
private:
PendingPacket<GbcPdu> m_packet;
MacAddress m_sender;
};
/**
* CbfPacketBuffer facilitates implementation of contention based forwarding
*/
class CbfPacketBuffer
{
public:
using TimerCallback = std::function<void(PendingPacket<GbcPdu>&&)>;
using Identifier = CbfPacketIdentifier;
/**
* Create CBF packet buffer with bounded capacity
* \param rt Runtime instance used for internal timers
* \param cb Callback invoked for each packet on expiry
* \param cnt CBF counter implementation
* \param bytes Buffer can hold at most this number of bytes
*/
CbfPacketBuffer(Runtime& rt, TimerCallback cb, std::unique_ptr<CbfCounter> cnt, std::size_t bytes);
~CbfPacketBuffer();
/**
* Enqueue a packet and start an associated timer expiring after timeout
* \param packet Buffer this packet
* \param timeout CBF timer expiration for this packet
*/
void add(CbfPacket&& packet, Clock::duration timeout);
/**
* Try to remove a packet from buffer.
* \param id packet identification
* \return true if packet existed before removal
*/
bool remove(const Identifier& id);
/**
* Update associated packet timer
* \param id packet identification
* \param timeout CBF timer expiration
*/
void update(const Identifier& id, Clock::duration timeout);
/**
* Fetch a packet from buffer.
*
* Associated timer is automatically stopped and packet removed from buffer.
* Packet lifetime is reduced by queueing time at return.
*
* \param id packet identification
* \return packet if found in buffer
*/
boost::optional<CbfPacket> fetch(const Identifier& id);
/**
* Find packet in buffer.
* \param id packet identification
* \return read-only pointer to packet, nullptr if not found
*/
const CbfPacket* find(const Identifier& id) const;
/**
* Get counter associated with given packet
* \note packet counter is incremented at each timer update
* \param id packet identification
* \return 0 if packet has never been buffered before
*/
std::size_t counter(const Identifier& packet) const;
private:
struct Timer
{
Timer(const Runtime&, Clock::duration timeout);
Timer(const Timer&) = default;
Timer& operator=(const Timer&) = default;
bool operator<(const Timer&) const;
Clock::time_point expiry;
Clock::time_point start;
};
using timer_bimap = boost::bimaps::bimap<
boost::bimaps::multiset_of<Timer>,
boost::bimaps::unordered_set_of<Identifier, std::hash<Identifier>>,
boost::bimaps::with_info<std::list<CbfPacket>::iterator>
>;
/**
* Flush all expired packets
*/
void flush();
/**
* Remove timer from map and reschedule timer event if necessary
*/
void remove_timer(typename timer_bimap::left_map::iterator);
/**
* Schedule next timer event at runtime
*/
void schedule_timer();
/**
* Reduce packet lifetime by queueing time
* \param timer contains queueing start time
* \param packet associated packet
* \return true if packet remains valid, false if end of lifetime is reached
*/
bool reduce_lifetime(const Timer&, CbfPacket&) const;
std::list<CbfPacket> m_packets;
timer_bimap m_timers;
Runtime& m_runtime;
std::unique_ptr<CbfCounter> m_counter;
const std::size_t m_capacity_bytes;
std::size_t m_stored_bytes;
TimerCallback m_timer_callback;
};
} // namespace geonet
} // namespace vanetza
#endif /* CBF_PACKET_BUFFER_HPP_MU3RK5V1 */