Vanetza
 
Loading...
Searching...
No Matches
indication_context.cpp
1#include <vanetza/geonet/indication_context.hpp>
2#include <vanetza/geonet/pdu_conversion.hpp>
3#include <vanetza/geonet/secured_pdu.hpp>
4
5namespace vanetza
6{
7namespace geonet
8{
9
10IndicationContextDeserialize::IndicationContextDeserialize(UpPacketPtr packet, CohesivePacket& cohesive, const LinkLayer& ll) :
11 IndicationContextBasic(ll),
12 m_packet(std::move(packet)), m_cohesive_packet(cohesive),
13 m_parser(cohesive[OsiLayer::Network])
14{
15}
16
17const BasicHeader* IndicationContextDeserialize::parse_basic()
18{
19 auto bytes = m_parser.parse_basic(pdu().basic());
20 return bytes > 0 ? &pdu().basic() : nullptr;
21}
22
23const CommonHeader* IndicationContextDeserialize::parse_common()
24{
25 auto bytes = m_parser.parse_common(pdu().common());
26 return bytes > 0 ? &pdu().common() : nullptr;
27}
28
29const IndicationContext::SecuredMessage* IndicationContextDeserialize::parse_secured()
30{
31 boost::optional<IndicationContext::SecuredMessage> tmp;
32 auto bytes = m_parser.parse_secured(tmp);
33 if (bytes > 0 && tmp) {
34 pdu().secured(std::move(*tmp));
35 return pdu().secured();
36 } else {
37 return nullptr;
38 }
39}
40
41boost::optional<HeaderConstRefVariant> IndicationContextDeserialize::parse_extended(HeaderType ht)
42{
43 auto bytes = m_parser.parse_extended(pdu().extended_variant(), ht);
44 return boost::optional<HeaderConstRefVariant>(bytes > 0, pdu().extended_variant());
45}
46
47IndicationContext::UpPacketPtr IndicationContextDeserialize::finish()
48{
49 m_cohesive_packet.set_boundary(OsiLayer::Network, m_parser.parsed_bytes());
50 m_cohesive_packet.trim(OsiLayer::Transport, pdu().common().payload);
51 return std::move(m_packet);
52}
53
54
55IndicationContextCast::IndicationContextCast(UpPacketPtr packet, ChunkPacket& chunk, const LinkLayer& ll) :
56 IndicationContextBasic(ll), m_packet(std::move(packet))
57{
58 Pdu* casted_pdu = pdu_cast(chunk.layer(OsiLayer::Network));
59 if (casted_pdu) {
60 pdu() = *casted_pdu;
61 } else {
62 throw std::runtime_error("Casting to Pdu failed");
63 }
64}
65
66const BasicHeader* IndicationContextCast::parse_basic()
67{
68 return &pdu().basic();
69}
70
71const CommonHeader* IndicationContextCast::parse_common()
72{
73 return &pdu().common();
74}
75
76const IndicationContext::SecuredMessage* IndicationContextCast::parse_secured()
77{
78 return pdu().secured();
79}
80
81boost::optional<HeaderConstRefVariant> IndicationContextCast::parse_extended(HeaderType)
82{
83 return boost::optional<HeaderConstRefVariant> { pdu().extended_variant() };
84}
85
86IndicationContext::UpPacketPtr IndicationContextCast::finish()
87{
88 // payload should be already in place (if any)
89 return std::move(m_packet);
90}
91
92
93IndicationContextSecuredDeserialize::IndicationContextSecuredDeserialize(IndicationContextBasic& parent, CohesivePacket& payload) :
95 m_packet(payload),
96 m_parser(payload[OsiLayer::Network])
97{
98}
99
100const CommonHeader* IndicationContextSecuredDeserialize::parse_common()
101{
102 auto bytes = m_parser.parse_common(pdu().common());
103 return bytes > 0 ? &pdu().common() : nullptr;
104}
105
106boost::optional<HeaderConstRefVariant> IndicationContextSecuredDeserialize::parse_extended(HeaderType ht)
107{
108 auto bytes = m_parser.parse_extended(pdu().extended_variant(), ht);
109 return boost::optional<HeaderConstRefVariant>(bytes > 0, pdu().extended_variant());
110}
111
112IndicationContext::UpPacketPtr IndicationContextSecuredDeserialize::finish()
113{
114 m_packet.set_boundary(OsiLayer::Network, m_parser.parsed_bytes());
115 auto packet = m_parent.finish();
116 (*packet) = m_packet;
117 return packet;
118}
119
120
121IndicationContextSecuredCast::IndicationContextSecuredCast(IndicationContextBasic& parent, ChunkPacket& packet) :
123 m_packet(parent.finish())
124{
125 SecuredPdu* secured_pdu = secured_pdu_cast(packet.layer(OsiLayer::Network));
126 if (secured_pdu) {
127 pdu().common() = secured_pdu->common;
128 pdu().extended_variant() = secured_pdu->extended;
129 } else {
130 throw std::runtime_error("Casting to SecuredPdu failed");
131 }
132
133 struct parent_packet_visitor : public boost::static_visitor<>
134 {
135 parent_packet_visitor(ChunkPacket& _secured_payload) : secured_payload(_secured_payload) {}
136
137 void operator()(ChunkPacket& packet)
138 {
139 packet.merge(secured_payload, OsiLayer::Transport, max_osi_layer());
140 }
141
142 void operator()(CohesivePacket& packet)
143 {
144 // CohesivePacket and casting PDUs will probably never happen...
145 ByteBuffer buffer(secured_payload.size());
146 for (auto layer : osi_layer_range(OsiLayer::Transport, max_osi_layer())) {
147 ByteBuffer layer_buffer;
148 secured_payload.layer(layer).convert(layer_buffer);
149 buffer.insert(buffer.end(), layer_buffer.begin(), layer_buffer.end());
150 }
151 packet = CohesivePacket(std::move(buffer), OsiLayer::Transport);
152 }
153
154 ChunkPacket& secured_payload;
155 };
156
157 parent_packet_visitor visitor(packet);
158 boost::apply_visitor(visitor, *m_packet);
159}
160
161const CommonHeader* IndicationContextSecuredCast::parse_common()
162{
163 return &pdu().common();
164}
165
166boost::optional<HeaderConstRefVariant> IndicationContextSecuredCast::parse_extended(HeaderType)
167{
168 return boost::optional<HeaderConstRefVariant> { pdu().extended_variant() };
169}
170
171IndicationContext::UpPacketPtr IndicationContextSecuredCast::finish()
172{
173 return std::move(m_packet);
174}
175
176} // namespace geonet
177} // namespace vanetza
ChunckPacket is a packet consisting of several memory chunks.
ByteBufferConvertible & layer(OsiLayer ol)
void set_boundary(OsiLayer, unsigned bytes)
virtual UpPacketPtr finish()=0
STL namespace.