#ifndef CBF_PACKET_BUFFER_HPP_MU3RK5V1 #define CBF_PACKET_BUFFER_HPP_MU3RK5V1 #include #include #include #include #include #include #include #include #include #include #include #include // 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&&, const MacAddress& sender); CbfPacket(PendingPacket&&, 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 packet() && { return std::move(m_packet); } private: PendingPacket m_packet; MacAddress m_sender; }; /** * CbfPacketBuffer facilitates implementation of contention based forwarding */ class CbfPacketBuffer { public: using TimerCallback = std::function&&)>; 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 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 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, boost::bimaps::unordered_set_of>, boost::bimaps::with_info::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 m_packets; timer_bimap m_timers; Runtime& m_runtime; std::unique_ptr 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 */