Vanetza
 
Loading...
Searching...
No Matches
validity_restriction.cpp
1#include <vanetza/security/exception.hpp>
2#include <vanetza/security/v2/validity_restriction.hpp>
3
4namespace vanetza
5{
6namespace security
7{
8namespace v2
9{
10
11Duration::Duration() : m_raw(0)
12{
13}
14
15Duration::Duration(BitNumber<uint16_t, 13> value, Units unit) :
16 m_raw(static_cast<decltype(m_raw)>(unit))
17{
18 m_raw <<= 13;
19 m_raw |= value.raw();
20}
21
22Duration::Duration(uint16_t raw) : m_raw(raw)
23{
24}
25
26std::chrono::seconds Duration::to_seconds() const
27{
28 using std::chrono::seconds;
29
30 // see section 4.2.17 of TS 103 097 v1.2.1 for conversion factors
31 switch (unit()) {
32 case Units::Seconds:
33 return seconds(value());
34
35 case Units::Minutes:
36 return seconds(value() * 60U);
37
38 case Units::Hours:
39 return seconds(value() * 3600U);
40
41 case Units::Sixty_Hour_Blocks:
42 return seconds(value() * 216000U);
43
44 case Units::Years:
45 return seconds(value() * 31556925ULL);
46
47 default:
48 // undefined, let's interpret it as minimal duration, which will fail during validation
49 return std::chrono::seconds::min();
50 }
51}
52
53StartAndEndValidity::StartAndEndValidity(Time32 start, Time32 end) :
54 start_validity(start), end_validity(end) {}
55
56StartAndDurationValidity::StartAndDurationValidity(Time32 start, Duration dur) :
57 start_validity(start), duration(dur) {}
58
59ValidityRestrictionType get_type(const ValidityRestriction& restriction)
60{
61 struct validity_restriction_visitor : public boost::static_visitor<ValidityRestrictionType>
62 {
63 ValidityRestrictionType operator()(const EndValidity& validity)
64 {
65 return ValidityRestrictionType::Time_End;
66 }
67 ValidityRestrictionType operator()(const StartAndEndValidity& validity)
68 {
69 return ValidityRestrictionType::Time_Start_And_End;
70 }
71 ValidityRestrictionType operator()(const StartAndDurationValidity& validity)
72 {
73 return ValidityRestrictionType::Time_Start_And_Duration;
74 }
75 ValidityRestrictionType operator()(const GeographicRegion& region)
76 {
77 return ValidityRestrictionType::Region;
78 }
79 };
80
81 validity_restriction_visitor visit;
82 return boost::apply_visitor(visit, restriction);
83}
84
85size_t get_size(const Time32& time)
86{
87 return sizeof(Time32);
88}
89
90size_t get_size(const Time64& time)
91{
92 return sizeof(Time64);
93}
94
95size_t get_size(const Duration& duration)
96{
97 return sizeof(uint16_t);
98}
99
100size_t get_size(const StartAndEndValidity& validity)
101{
102 size_t size = sizeof(validity.end_validity);
103 size += sizeof(validity.start_validity);
104 return size;
105}
106
107size_t get_size(const StartAndDurationValidity& validity)
108{
109 size_t size = sizeof(validity.start_validity);
110 size += get_size(validity.duration);
111 return size;
112}
113
114size_t get_size(const ValidityRestriction& restriction)
115{
116 size_t size = sizeof(ValidityRestrictionType);
117 struct validity_restriction_visitor : public boost::static_visitor<size_t>
118 {
119 size_t operator()(const EndValidity& validity)
120 {
121 return sizeof(validity);
122 }
123 size_t operator()(const StartAndEndValidity& validity)
124 {
125 return get_size(validity);
126 }
127 size_t operator()(const StartAndDurationValidity& validity)
128 {
129 return get_size(validity);
130 }
131 size_t operator()(const GeographicRegion& region)
132 {
133 return get_size(region);
134 }
135 };
136
137 validity_restriction_visitor visit;
138 size += boost::apply_visitor(visit, restriction);
139 return size;
140}
141
142size_t deserialize(InputArchive& ar, ValidityRestriction& restriction)
143{
144 size_t size = 0;
145 ValidityRestrictionType type;
146 deserialize(ar, type);
147 size += sizeof(ValidityRestrictionType);
148 switch (type) {
149 case ValidityRestrictionType::Time_End: {
150 EndValidity end;
151 deserialize(ar, end);
152 size += sizeof(end);
153 restriction = end;
154 break;
155 }
156 case ValidityRestrictionType::Time_Start_And_Duration: {
157 StartAndDurationValidity validity;
158 deserialize(ar, validity.start_validity);
159 uint16_t duration;
160 deserialize(ar, duration);
161 validity.duration = Duration(duration);
162 size += get_size(validity);
163 restriction = validity;
164 break;
165 }
166 case ValidityRestrictionType::Time_Start_And_End: {
167 StartAndEndValidity validity;
168 deserialize(ar, validity.start_validity);
169 deserialize(ar, validity.end_validity);
170 restriction = validity;
171 size += get_size(validity);
172 break;
173 }
174 case ValidityRestrictionType::Region: {
175 GeographicRegion region;
176 size += deserialize(ar, region);
177 restriction = region;
178 break;
179 }
180 default:
181 throw deserialization_error("Unknown ValidityRestrictionType");
182 }
183 return size;
184}
185
186void serialize(OutputArchive& ar, const ValidityRestriction& restriction)
187{
188 struct validity_restriction_visitor : public boost::static_visitor<>
189 {
190 validity_restriction_visitor(OutputArchive& ar) :
191 m_archive(ar)
192 {
193 }
194 void operator()(const EndValidity& validity)
195 {
196 serialize(m_archive, host_cast(validity));
197 }
198 void operator()(const StartAndEndValidity& validity)
199 {
200 serialize(m_archive, host_cast(validity.start_validity));
201 serialize(m_archive, host_cast(validity.end_validity));
202 }
203 void operator()(const StartAndDurationValidity& validity)
204 {
205 serialize(m_archive, host_cast(validity.start_validity));
206 serialize(m_archive, host_cast(validity.duration.raw()));
207 }
208 void operator()(const GeographicRegion& region)
209 {
210 serialize(m_archive, region);
211 }
212 OutputArchive& m_archive;
213 };
214
215 ValidityRestrictionType type = get_type(restriction);
216 serialize(ar, type);
217 validity_restriction_visitor visit(ar);
218 boost::apply_visitor(visit, restriction);
219}
220
221} // namespace v2
222} // namespace security
223} // namespace vanetza