#ifndef PACKET_VISITOR_HPP_UYSI8HXZ #define PACKET_VISITOR_HPP_UYSI8HXZ #include #include #include #include #include #include #include #include namespace vanetza { namespace asn1 { /** * PacketVisitor is a helper to extract the ASN.1 wrapper object from a packet's application layer. * This is a generalised version of the implementation found in Artery before. * * ChunkPacket's application layer is simply casted for the sake of speed whenever possible. * When casting fails, this helper can fall back to deserialization, see allow_chunk_deserialization. * Deserialization is the only option for CohesivePacket's application layer. * * \param T is the asn1c_wrapper<> type, e.g. Cam or Denm */ template class PacketVisitor : public boost::static_visitor> { public: std::shared_ptr operator()(const ChunkPacket& packet) { using byte_buffer_impl = convertible::byte_buffer_impl; auto impl = dynamic_cast(packet[OsiLayer::Application].ptr()); if (impl) { m_wrapper = impl->wrapper(); } else if (m_deserialize_chunk) { deserialize(create_byte_view(packet, m_start_layer, OsiLayer::Application)); } else { m_wrapper.reset(); } return m_wrapper; } std::shared_ptr operator()(const CohesivePacket& packet) { deserialize(create_byte_view(packet, m_start_layer, OsiLayer::Application)); return m_wrapper; } std::shared_ptr get_shared_wrapper() const { return m_wrapper; } /** * Allow deserialization attempt of ChunkPacket when casting failed. * \param flag true allows deserialization */ void allow_chunk_deserialization(bool flag) { m_deserialize_chunk = flag; } /** * Set OSI layer where deserialization shall start, it always stops at end of OsiLayer::Application. * By default, PacketVisitors starts at OsiLayer::Session for compatibility with BTP parser functions. * \param start OSI layer */ void start_deserialization_at(OsiLayer start) { m_start_layer = start; } private: void deserialize(const byte_view_range& range) { auto tmp = std::make_shared(); bool decoded = tmp->decode(range.begin().raw(), range.size()); m_wrapper = decoded ? tmp : nullptr; } std::shared_ptr m_wrapper; bool m_deserialize_chunk = true; OsiLayer m_start_layer = OsiLayer::Session; }; } // namespace asn1 } // namespace vanetza #endif /* PACKET_VISITOR_HPP_UYSI8HXZ */