#include #include #include namespace vanetza { namespace geonet { IndicationContextDeserialize::IndicationContextDeserialize(UpPacketPtr packet, CohesivePacket& cohesive, const LinkLayer& ll) : IndicationContextBasic(ll), m_packet(std::move(packet)), m_cohesive_packet(cohesive), m_parser(cohesive[OsiLayer::Network]) { } const BasicHeader* IndicationContextDeserialize::parse_basic() { auto bytes = m_parser.parse_basic(pdu().basic()); return bytes > 0 ? &pdu().basic() : nullptr; } const CommonHeader* IndicationContextDeserialize::parse_common() { auto bytes = m_parser.parse_common(pdu().common()); return bytes > 0 ? &pdu().common() : nullptr; } const IndicationContext::SecuredMessage* IndicationContextDeserialize::parse_secured() { IndicationContext::SecuredMessage tmp; auto bytes = m_parser.parse_secured(tmp); if (bytes > 0) { pdu().secured(std::move(tmp)); return pdu().secured(); } else { return nullptr; } } boost::optional IndicationContextDeserialize::parse_extended(HeaderType ht) { auto bytes = m_parser.parse_extended(pdu().extended_variant(), ht); return boost::optional(bytes > 0, pdu().extended_variant()); } IndicationContext::UpPacketPtr IndicationContextDeserialize::finish() { m_cohesive_packet.set_boundary(OsiLayer::Network, m_parser.parsed_bytes()); m_cohesive_packet.trim(OsiLayer::Transport, pdu().common().payload); return std::move(m_packet); } IndicationContextCast::IndicationContextCast(UpPacketPtr packet, ChunkPacket& chunk, const LinkLayer& ll) : IndicationContextBasic(ll), m_packet(std::move(packet)) { Pdu* casted_pdu = pdu_cast(chunk.layer(OsiLayer::Network)); if (casted_pdu) { pdu() = *casted_pdu; } else { throw std::runtime_error("Casting to Pdu failed"); } } const BasicHeader* IndicationContextCast::parse_basic() { return &pdu().basic(); } const CommonHeader* IndicationContextCast::parse_common() { return &pdu().common(); } const IndicationContext::SecuredMessage* IndicationContextCast::parse_secured() { return pdu().secured(); } boost::optional IndicationContextCast::parse_extended(HeaderType) { return boost::optional { pdu().extended_variant() }; } IndicationContext::UpPacketPtr IndicationContextCast::finish() { // payload should be already in place (if any) return std::move(m_packet); } IndicationContextSecuredDeserialize::IndicationContextSecuredDeserialize(IndicationContextBasic& parent, CohesivePacket& payload) : IndicationContextSecured(parent), m_packet(payload), m_parser(payload[OsiLayer::Network]) { } const CommonHeader* IndicationContextSecuredDeserialize::parse_common() { auto bytes = m_parser.parse_common(pdu().common()); return bytes > 0 ? &pdu().common() : nullptr; } boost::optional IndicationContextSecuredDeserialize::parse_extended(HeaderType ht) { auto bytes = m_parser.parse_extended(pdu().extended_variant(), ht); return boost::optional(bytes > 0, pdu().extended_variant()); } IndicationContext::UpPacketPtr IndicationContextSecuredDeserialize::finish() { m_packet.set_boundary(OsiLayer::Network, m_parser.parsed_bytes()); auto packet = m_parent.finish(); (*packet) = m_packet; return packet; } IndicationContextSecuredCast::IndicationContextSecuredCast(IndicationContextBasic& parent, ChunkPacket& packet) : IndicationContextSecured(parent), m_packet(parent.finish()) { SecuredPdu* secured_pdu = secured_pdu_cast(packet.layer(OsiLayer::Network)); if (secured_pdu) { pdu().common() = secured_pdu->common; pdu().extended_variant() = secured_pdu->extended; } else { throw std::runtime_error("Casting to SecuredPdu failed"); } struct parent_packet_visitor : public boost::static_visitor<> { parent_packet_visitor(ChunkPacket& _secured_payload) : secured_payload(_secured_payload) {} void operator()(ChunkPacket& packet) { packet.merge(secured_payload, OsiLayer::Transport, max_osi_layer()); } void operator()(CohesivePacket& packet) { // CohesivePacket and casting PDUs will probably never happen... ByteBuffer buffer(secured_payload.size()); for (auto layer : osi_layer_range(OsiLayer::Transport, max_osi_layer())) { ByteBuffer layer_buffer; secured_payload.layer(layer).convert(layer_buffer); buffer.insert(buffer.end(), layer_buffer.begin(), layer_buffer.end()); } packet = CohesivePacket(std::move(buffer), OsiLayer::Transport); } ChunkPacket& secured_payload; }; parent_packet_visitor visitor(packet); boost::apply_visitor(visitor, *m_packet); } const CommonHeader* IndicationContextSecuredCast::parse_common() { return &pdu().common(); } boost::optional IndicationContextSecuredCast::parse_extended(HeaderType) { return boost::optional { pdu().extended_variant() }; } IndicationContext::UpPacketPtr IndicationContextSecuredCast::finish() { return std::move(m_packet); } } // namespace geonet } // namespace vanetza