Vanetza
 
Loading...
Searching...
No Matches
packet_visitor.hpp
1#ifndef PACKET_VISITOR_HPP_UYSI8HXZ
2#define PACKET_VISITOR_HPP_UYSI8HXZ
3
4#include <vanetza/asn1/asn1c_conversion.hpp>
5#include <vanetza/common/byte_buffer.hpp>
6#include <vanetza/net/chunk_packet.hpp>
7#include <vanetza/net/cohesive_packet.hpp>
8#include <vanetza/net/osi_layer.hpp>
9#include <vanetza/net/packet_variant.hpp>
10#include <boost/variant/static_visitor.hpp>
11#include <memory>
12
13namespace vanetza
14{
15namespace asn1
16{
17
18/**
19 * PacketVisitor is a helper to extract the ASN.1 wrapper object from a packet's application layer.
20 * This is a generalised version of the implementation found in Artery before.
21 *
22 * ChunkPacket's application layer is simply casted for the sake of speed whenever possible.
23 * When casting fails, this helper can fall back to deserialization, see allow_chunk_deserialization.
24 * Deserialization is the only option for CohesivePacket's application layer.
25 *
26 * \param T is the asn1c_wrapper<> type, e.g. Cam or Denm
27 */
28template<typename T>
29class PacketVisitor : public boost::static_visitor<std::shared_ptr<const T>>
30{
31 public:
32 std::shared_ptr<const T> operator()(const ChunkPacket& packet)
33 {
34 using byte_buffer_impl = convertible::byte_buffer_impl<T>;
35 auto impl = dynamic_cast<const byte_buffer_impl*>(packet[OsiLayer::Application].ptr());
36 if (impl) {
37 m_wrapper = impl->wrapper();
38 } else if (m_deserialize_chunk) {
39 deserialize(create_byte_view(packet, m_start_layer, OsiLayer::Application));
40 } else {
41 m_wrapper.reset();
42 }
43 return m_wrapper;
44 }
45
46 std::shared_ptr<const T> operator()(const CohesivePacket& packet)
47 {
48 deserialize(create_byte_view(packet, m_start_layer, OsiLayer::Application));
49 return m_wrapper;
50 }
51
52 std::shared_ptr<const T> get_shared_wrapper() const { return m_wrapper; }
53
54 /**
55 * Allow deserialization attempt of ChunkPacket when casting failed.
56 * \param flag true allows deserialization
57 */
59 {
60 m_deserialize_chunk = flag;
61 }
62
63 /**
64 * Set OSI layer where deserialization shall start, it always stops at end of OsiLayer::Application.
65 * By default, PacketVisitors starts at OsiLayer::Session for compatibility with BTP parser functions.
66 * \param start OSI layer
67 */
68 void start_deserialization_at(OsiLayer start)
69 {
70 m_start_layer = start;
71 }
72
73 private:
74 void deserialize(const byte_view_range& range)
75 {
76 auto tmp = std::make_shared<T>();
77 bool decoded = tmp->decode(range.begin().raw(), range.size());
78 m_wrapper = decoded ? tmp : nullptr;
79 }
80
81 std::shared_ptr<const T> m_wrapper;
82 bool m_deserialize_chunk = true;
83 OsiLayer m_start_layer = OsiLayer::Session;
84};
85
86} // namespace asn1
87} // namespace vanetza
88
89#endif /* PACKET_VISITOR_HPP_UYSI8HXZ */
90
ChunckPacket is a packet consisting of several memory chunks.
void start_deserialization_at(OsiLayer start)
void allow_chunk_deserialization(bool flag)