Vanetza
Loading...
Searching...
No Matches
cam.ipp
1#include <vanetza/asn1/its/CAM.h>
2#include <vanetza/asn1/its/r2/CAM.h>
3#include <vanetza/facilities/detail/macros.ipp>
4#include <iostream>
5
6ASSERT_EQUAL_TYPE(AltitudeConfidence_t);
7ASSERT_EQUAL_ENUM(AltitudeConfidence_alt_000_01);
8ASSERT_EQUAL_ENUM(AltitudeConfidence_alt_200_00);
9ASSERT_EQUAL_ENUM(AltitudeConfidence_outOfRange);
10ASSERT_EQUAL_ENUM(AltitudeConfidence_unavailable);
11
12ASSERT_EQUAL_TYPE(AltitudeValue_t);
13ASSERT_EQUAL_ENUM(AltitudeValue_unavailable);
14
15ASSERT_EQUAL_TYPE(DeltaAltitude_t);
16ASSERT_EQUAL_ENUM(DeltaAltitude_unavailable);
17
18ASSERT_EQUAL_TYPE(DeltaLatitude_t);
19ASSERT_EQUAL_ENUM(DeltaLatitude_unavailable);
20
21ASSERT_EQUAL_TYPE(DeltaLongitude_t);
22ASSERT_EQUAL_ENUM(DeltaLongitude_unavailable);
23
24ASSERT_EQUAL_TYPE(Latitude_t);
25ASSERT_EQUAL_ENUM(Latitude_unavailable);
26
27ASSERT_EQUAL_TYPE(Longitude_t);
28ASSERT_EQUAL_ENUM(Longitude_unavailable);
29
30ASSERT_EQUAL_TYPE(PathDeltaTime_t);
31
32namespace vanetza
33{
34namespace facilities
35{
36
37bool check_service_specific_permissions(const ASN1_PREFIXED(CamParameters_t)& params, security::CamPermissions ssp)
38{
39 using security::CamPermission;
40 using security::CamPermissions;
41
42 CamPermissions required_permissions;
43
44 if (params.highFrequencyContainer.present == ASN1_PREFIXED(HighFrequencyContainer_PR_rsuContainerHighFrequency)) {
45 const ASN1_PREFIXED(RSUContainerHighFrequency_t)& rsu = params.highFrequencyContainer.choice.rsuContainerHighFrequency;
46 if (rsu.protectedCommunicationZonesRSU) {
47 required_permissions.add(CamPermission::CEN_DSRC_Tolling_Zone);
48 }
49 }
50
51 if (const ASN1_PREFIXED(SpecialVehicleContainer_t)* special = params.specialVehicleContainer) {
52 const ASN1_PREFIXED(EmergencyContainer_t)* emergency = nullptr;
53 const ASN1_PREFIXED(SafetyCarContainer_t)* safety = nullptr;
54 const ASN1_PREFIXED(RoadWorksContainerBasic_t)* roadworks = nullptr;
55
56 switch (special->present) {
57 case ASN1_PREFIXED(SpecialVehicleContainer_PR_publicTransportContainer):
58 required_permissions.add(CamPermission::Public_Transport);
59 break;
60 case ASN1_PREFIXED(SpecialVehicleContainer_PR_specialTransportContainer):
61 required_permissions.add(CamPermission::Special_Transport);
62 break;
63 case ASN1_PREFIXED(SpecialVehicleContainer_PR_dangerousGoodsContainer):
64 required_permissions.add(CamPermission::Dangerous_Goods);
65 break;
66 case ASN1_PREFIXED(SpecialVehicleContainer_PR_roadWorksContainerBasic):
67 required_permissions.add(CamPermission::Roadwork);
68 roadworks = &special->choice.roadWorksContainerBasic;
69 break;
70 case ASN1_PREFIXED(SpecialVehicleContainer_PR_rescueContainer):
71 required_permissions.add(CamPermission::Rescue);
72 break;
73 case ASN1_PREFIXED(SpecialVehicleContainer_PR_emergencyContainer):
74 required_permissions.add(CamPermission::Emergency);
75 emergency = &special->choice.emergencyContainer;
76 break;
77 case ASN1_PREFIXED(SpecialVehicleContainer_PR_safetyCarContainer):
78 required_permissions.add(CamPermission::Safety_Car);
79 safety = &special->choice.safetyCarContainer;
80 break;
81 default:
82 break;
83 }
84
85 if (emergency && emergency->emergencyPriority && emergency->emergencyPriority->size == 1) {
86 // testing bit strings from asn1c is such a mess...
87 assert(emergency->emergencyPriority->buf);
88 uint8_t bits = *emergency->emergencyPriority->buf;
89 if (bits & (1 << (7 - ASN1_PREFIXED(EmergencyPriority_requestForRightOfWay)))) {
90 required_permissions.add(CamPermission::Request_For_Right_Of_Way);
91 }
92 if (bits & (1 << (7 - ASN1_PREFIXED(EmergencyPriority_requestForFreeCrossingAtATrafficLight)))) {
93 required_permissions.add(CamPermission::Request_For_Free_Crossing_At_Traffic_Light);
94 }
95 }
96
97 if (roadworks && roadworks->closedLanes) {
98 required_permissions.add(CamPermission::Closed_Lanes);
99 }
100
101 if (safety && safety->trafficRule) {
102 switch (*safety->trafficRule) {
103 case ASN1_PREFIXED(TrafficRule_noPassing):
104 required_permissions.add(CamPermission::No_Passing);
105 break;
106 case ASN1_PREFIXED(TrafficRule_noPassingForTrucks):
107 required_permissions.add(CamPermission::No_Passing_For_Trucks);
108 break;
109 default:
110 break;
111 }
112 }
113
114 if (safety && safety->speedLimit) {
115 required_permissions.add(CamPermission::Speed_Limit);
116 }
117 }
118
119 return ssp.has(required_permissions);
120}
121
122void print_indented(std::ostream& os, const ASN1_PREFIXED(CAM_t)* message, const std::string& indent, unsigned level)
123{
124 auto prefix = [&](const char* field) -> std::ostream& {
125 for (unsigned i = 0; i < level; ++i) {
126 os << indent;
127 }
128 os << field << ": ";
129 return os;
130 };
131
132 const ASN1_PREFIXED(ItsPduHeader_t)& header = message->header;
133 prefix("ITS PDU Header") << "\n";
134 ++level;
135 prefix("Protocol Version") << header.protocolVersion << "\n";
136 #if ITS_RELEASE == 1
137 prefix("Message ID") << header.messageID << "\n";
138 prefix("Station ID") << header.stationID << "\n";
139 #else
140 prefix("Message ID") << header.messageId << "\n";
141 prefix("Station ID") << header.stationId << "\n";
142 #endif
143 --level;
144
145 #if ITS_RELEASE == 1
146 const ASN1_PREFIXED(CoopAwareness_t)& cam = message->cam;
147 #else
148 const ASN1_PREFIXED(CamPayload_t)& cam = message->cam;
149 #endif
150 prefix("CoopAwareness") << "\n";
151 ++level;
152 prefix("Generation Delta Time") << cam.generationDeltaTime << "\n";
153
154 prefix("Basic Container") << "\n";
155 ++level;
156 const ASN1_PREFIXED(BasicContainer_t)& basic = cam.camParameters.basicContainer;
157 prefix("Station Type") << basic.stationType << "\n";
158 prefix("Reference Position") << "\n";
159 ++level;
160 prefix("Longitude") << basic.referencePosition.longitude << "\n";
161 prefix("Latitude") << basic.referencePosition.latitude << "\n";
162 #if ITS_RELEASE == 1
163 prefix("Semi Major Orientation") << basic.referencePosition.positionConfidenceEllipse.semiMajorOrientation << "\n";
164 prefix("Semi Major Confidence") << basic.referencePosition.positionConfidenceEllipse.semiMajorConfidence << "\n";
165 prefix("Semi Minor Confidence") << basic.referencePosition.positionConfidenceEllipse.semiMinorConfidence << "\n";
166 #else
167 prefix("Semi Major Axis Orientation") << basic.referencePosition.positionConfidenceEllipse.semiMajorAxisOrientation << "\n";
168 prefix("Semi Major Axis Length") << basic.referencePosition.positionConfidenceEllipse.semiMajorAxisLength << "\n";
169 prefix("Semi Minor Axis Length") << basic.referencePosition.positionConfidenceEllipse.semiMinorAxisLength << "\n";
170 #endif
171
172 prefix("Altitude [Confidence]") << basic.referencePosition.altitude.altitudeValue
173 << " [" << basic.referencePosition.altitude.altitudeConfidence << "]\n";
174 --level;
175 --level;
176
177 if (cam.camParameters.highFrequencyContainer.present == ASN1_PREFIXED(HighFrequencyContainer_PR_basicVehicleContainerHighFrequency)) {
178 prefix("High Frequency Container [Basic Vehicle]") << "\n";
179 ++level;
180 const ASN1_PREFIXED(BasicVehicleContainerHighFrequency)& bvc =
181 cam.camParameters.highFrequencyContainer.choice.basicVehicleContainerHighFrequency;
182 prefix("Heading [Confidence]") << bvc.heading.headingValue
183 << " [" << bvc.heading.headingConfidence << "]\n";
184 prefix("Speed [Confidence]") << bvc.speed.speedValue
185 << " [" << bvc.speed.speedConfidence << "]\n";
186 prefix("Drive Direction") << bvc.driveDirection << "\n";
187 #if ITS_RELEASE == 1
188 prefix("Longitudinal Acceleration [Confidence]") << bvc.longitudinalAcceleration.longitudinalAccelerationValue
189 << " [" << bvc.longitudinalAcceleration.longitudinalAccelerationConfidence << "]\n";
190 #else
191 prefix("Longitudinal Acceleration [Confidence]") << bvc.longitudinalAcceleration.value
192 << " [" << bvc.longitudinalAcceleration.confidence << "]\n";
193 #endif
194 prefix("Vehicle Length [Confidence Indication]") << bvc.vehicleLength.vehicleLengthValue
195 << " [" << bvc.vehicleLength.vehicleLengthConfidenceIndication << "]\n";
196 prefix("Vehicle Width") << bvc.vehicleWidth << "\n";
197 prefix("Curvature [Confidence]") << bvc.curvature.curvatureValue
198 << " [" << bvc.curvature.curvatureConfidence << "]\n";
199 prefix("Curvature Calculation Mode") << bvc.curvatureCalculationMode << "\n";
200 prefix("Yaw Rate [Confidence]") << bvc.yawRate.yawRateValue
201 << " [" << bvc.yawRate.yawRateConfidence << "]\n";
202 --level;
203 } else if (cam.camParameters.highFrequencyContainer.present == ASN1_PREFIXED(HighFrequencyContainer_PR_rsuContainerHighFrequency)) {
204 prefix("High Frequency Container [RSU]") << "\n";
205 const ASN1_PREFIXED(RSUContainerHighFrequency_t)& rsu = cam.camParameters.highFrequencyContainer.choice.rsuContainerHighFrequency;
206 if (nullptr != rsu.protectedCommunicationZonesRSU && nullptr != rsu.protectedCommunicationZonesRSU->list.array) {
207 ++level;
208 int size = rsu.protectedCommunicationZonesRSU->list.count;
209 for (int i = 0; i < size; i++)
210 {
211 prefix("Protected Zone") << "\n";
212 ++level;
213 prefix("Type") << rsu.protectedCommunicationZonesRSU->list.array[i]->protectedZoneType << "\n";
214 if (rsu.protectedCommunicationZonesRSU->list.array[i]->expiryTime
215 && nullptr != rsu.protectedCommunicationZonesRSU->list.array[i]->expiryTime->buf
216 && rsu.protectedCommunicationZonesRSU->list.array[i]->expiryTime->size > 0)
217 prefix("Expiry Time") << (unsigned) rsu.protectedCommunicationZonesRSU->list.array[i]->expiryTime->buf[0] << "\n";
218 prefix("Latitude") << rsu.protectedCommunicationZonesRSU->list.array[i]->protectedZoneLatitude << "\n";
219 prefix("Longitude") << rsu.protectedCommunicationZonesRSU->list.array[i]->protectedZoneLongitude << "\n";
220 if (nullptr != rsu.protectedCommunicationZonesRSU->list.array[i]->protectedZoneRadius)
221 prefix("Radius") << *(rsu.protectedCommunicationZonesRSU->list.array[i]->protectedZoneRadius) << "\n";
222 if (nullptr != rsu.protectedCommunicationZonesRSU->list.array[i]->protectedZoneRadius)
223 #if ITS_RELEASE == 1
224 prefix("ID") << *(rsu.protectedCommunicationZonesRSU->list.array[i]->protectedZoneID) << "\n";
225 #else
226 prefix("ID") << *(rsu.protectedCommunicationZonesRSU->list.array[i]->protectedZoneId) << "\n";
227 #endif
228 --level;
229 }
230 --level;
231 }
232 } else {
233 prefix("High Frequency Container") << "empty\n";
234 }
235
236 if (nullptr != cam.camParameters.lowFrequencyContainer) {
237 if (cam.camParameters.lowFrequencyContainer->present == ASN1_PREFIXED(LowFrequencyContainer_PR_basicVehicleContainerLowFrequency)) {
238 prefix("Low Frequency Container") << "\n";
239 const ASN1_PREFIXED(BasicVehicleContainerLowFrequency_t)& lfc =
240 cam.camParameters.lowFrequencyContainer->choice.basicVehicleContainerLowFrequency;
241 ++level;
242 prefix("Vehicle Role") << (lfc.vehicleRole) << "\n";
243
244 if (nullptr != lfc.exteriorLights.buf && lfc.exteriorLights.size > 0)
245 prefix("Exterior Lights") << unsigned(*(lfc.exteriorLights.buf)) << "\n";
246 if (nullptr != lfc.pathHistory.list.array) {
247 int size = lfc.pathHistory.list.count;
248 for (int i = 0; i < size; i++)
249 {
250 prefix("Path history point") << "\n";
251 ++level;
252 prefix("Latitude") << (lfc.pathHistory.list.array[i]->pathPosition.deltaLatitude) << "\n";
253 prefix("Longitude") << (lfc.pathHistory.list.array[i]->pathPosition.deltaLongitude) << "\n";
254 prefix("Altitude") << (lfc.pathHistory.list.array[i]->pathPosition.deltaAltitude) << "\n";
255 if (lfc.pathHistory.list.array[i]->pathDeltaTime)
256 prefix("Delta time") << *(lfc.pathHistory.list.array[i]->pathDeltaTime) << "\n";
257 --level;
258 }
259 }
260 --level;
261 }
262 else // LowFrequencyContainer_PR_NOTHING
263 prefix("Low Frequency Container") << "present but empty" << "\n";
264 }
265 else
266 prefix("Low Frequency Container") << "not present" << "\n";
267
268 if (nullptr != cam.camParameters.specialVehicleContainer) {
269 if (cam.camParameters.specialVehicleContainer->present == ASN1_PREFIXED(SpecialVehicleContainer_PR_publicTransportContainer)) {
270 prefix("Special Vehicle Container [Public Transport]") << "\n";
271 ASN1_PREFIXED(PublicTransportContainer_t)& ptc = cam.camParameters.specialVehicleContainer->choice.publicTransportContainer;
272 ++level;
273 prefix("Embarkation Status") << ptc.embarkationStatus << "\n";
274 if (ptc.ptActivation) {
275 prefix("PT Activation Type") << ptc.ptActivation->ptActivationType << "\n";
276 if (0 != ptc.ptActivation->ptActivationData.size) {
277 int size = ptc.ptActivation->ptActivationData.size;
278 for (int i = 0; i < ptc.ptActivation->ptActivationData.size; i++)
279 prefix("PT Activation Data") << (unsigned) ptc.ptActivation->ptActivationData.buf[i] << "\n";
280 }
281 }
282 --level;
283 } else if (cam.camParameters.specialVehicleContainer->present == ASN1_PREFIXED(SpecialVehicleContainer_PR_specialTransportContainer)) {
284 prefix("Special Vehicle Container [Special Transport]") << "\n";
285 ASN1_PREFIXED(SpecialTransportContainer_t)& stc = cam.camParameters.specialVehicleContainer->choice.specialTransportContainer;
286 ++level;
287 if (nullptr != stc.specialTransportType.buf && stc.specialTransportType.size > 0)
288 prefix("Type") << (unsigned) stc.specialTransportType.buf[0] << "\n";
289 if (nullptr != stc.lightBarSirenInUse.buf && stc.lightBarSirenInUse.size > 0)
290 prefix("Light Bar Siren in Use") << (unsigned) stc.lightBarSirenInUse.buf[0] << "\n";
291 --level;
292 } else if (cam.camParameters.specialVehicleContainer->present == ASN1_PREFIXED(SpecialVehicleContainer_PR_dangerousGoodsContainer)) {
293 prefix("Special Vehicle Container [Dangerous Goods]") << "\n";
294 ASN1_PREFIXED(DangerousGoodsContainer_t)& dgc = cam.camParameters.specialVehicleContainer->choice.dangerousGoodsContainer;
295 ++level;
296 prefix("Dangerous Goods Basic Type") << (unsigned)dgc.dangerousGoodsBasic << "\n";
297 --level;
298 } else if (cam.camParameters.specialVehicleContainer->present == ASN1_PREFIXED(SpecialVehicleContainer_PR_roadWorksContainerBasic)) {
299 prefix("Special Vehicle Container [Road Works]") << "\n";
300 ASN1_PREFIXED(RoadWorksContainerBasic_t)& rwc = cam.camParameters.specialVehicleContainer->choice.roadWorksContainerBasic;
301 ++level;
302 if (nullptr != rwc.roadworksSubCauseCode)
303 prefix("Sub Cause Code") << *(rwc.roadworksSubCauseCode) << "\n";
304 if (nullptr != rwc.lightBarSirenInUse.buf && rwc.lightBarSirenInUse.size > 0)
305 prefix("Light Bar Siren in Use") << (unsigned) rwc.lightBarSirenInUse.buf[0] << "\n";
306 if (nullptr != rwc.closedLanes) {
307 if (rwc.closedLanes->innerhardShoulderStatus)
308 prefix("Inner Hard Shoulder Status") << *(rwc.closedLanes->innerhardShoulderStatus) << "\n";
309 if (rwc.closedLanes->outerhardShoulderStatus)
310 prefix("Outer Hard Shoulder Status") << *(rwc.closedLanes->outerhardShoulderStatus) << "\n";
311 if (rwc.closedLanes->drivingLaneStatus && nullptr != rwc.closedLanes->drivingLaneStatus->buf
312 && rwc.closedLanes->drivingLaneStatus->size > 0)
313 prefix("Driving Lane Status") << (unsigned) rwc.closedLanes->drivingLaneStatus->buf[0] << "\n";
314 }
315 --level;
316 } else if (cam.camParameters.specialVehicleContainer->present == ASN1_PREFIXED(SpecialVehicleContainer_PR_rescueContainer)) {
317 prefix("Special Vehicle Container [Rescue]") << "\n";
318 ASN1_PREFIXED(RescueContainer_t)& rc = cam.camParameters.specialVehicleContainer->choice.rescueContainer;
319 ++level;
320 if (nullptr != rc.lightBarSirenInUse.buf && rc.lightBarSirenInUse.size > 0)
321 prefix("Light Bar Siren in Use") << (unsigned) rc.lightBarSirenInUse.buf[0] << "\n";
322 --level;
323 } else if (cam.camParameters.specialVehicleContainer->present == ASN1_PREFIXED(SpecialVehicleContainer_PR_emergencyContainer)) {
324 prefix("Special Vehicle Container [Emergency]") << "\n";
325 ASN1_PREFIXED(EmergencyContainer_t)& ec = cam.camParameters.specialVehicleContainer->choice.emergencyContainer;
326 ++level;
327 if (nullptr != ec.lightBarSirenInUse.buf && ec.lightBarSirenInUse.size > 0)
328 prefix("Light Bar Siren in Use") << (unsigned) ec.lightBarSirenInUse.buf[0] << "\n";
329 if (nullptr != ec.incidentIndication) {
330 #if ITS_RELEASE == 1
331 prefix("Incident Indication Cause Code") << ec.incidentIndication->causeCode << "\n";
332 prefix("Incident Indication Sub Cause Code") << ec.incidentIndication->subCauseCode << "\n";
333 #else
334 prefix("Incident Indication Cause Code V2") << ec.incidentIndication->ccAndScc.present << "\n";
335 prefix("Incident Indication Sub Cause Code V2") << ec.incidentIndication->ccAndScc.choice.reserved0 << "\n";
336 #endif
337 }
338 if (nullptr != ec.emergencyPriority && nullptr != ec.emergencyPriority->buf
339 && ec.emergencyPriority->size > 0) {
340 prefix("Emergency Priority") << (unsigned) ec.emergencyPriority->buf[0] << "\n";
341 }
342 --level;
343 } else if (cam.camParameters.specialVehicleContainer->present == ASN1_PREFIXED(SpecialVehicleContainer_PR_safetyCarContainer)) {
344 prefix("Special Vehicle Container [Safety Car]") << "\n";
345 ASN1_PREFIXED(SafetyCarContainer_t)& sc = cam.camParameters.specialVehicleContainer->choice.safetyCarContainer;
346 ++level;
347 if (nullptr != sc.lightBarSirenInUse.buf && sc.lightBarSirenInUse.size > 0)
348 prefix("Light Bar Siren in Use") << (unsigned) sc.lightBarSirenInUse.buf[0] << "\n";
349 if (nullptr != sc.incidentIndication) {
350 #if ITS_RELEASE == 1
351 prefix("Incident Indication Cause Code") << sc.incidentIndication->causeCode << "\n";
352 prefix("Incident Indication Sub Cause Code") << sc.incidentIndication->subCauseCode << "\n";
353 #else
354 prefix("Incident Indication Cause Code V2") << sc.incidentIndication->ccAndScc.present << "\n";
355 prefix("Incident Indication Sub Cause Code V2") << sc.incidentIndication->ccAndScc.choice.reserved0 << "\n";
356 #endif
357 }
358 if (nullptr != sc.trafficRule) {
359 prefix("Traffic Rule") << *(sc.trafficRule) << "\n";
360 }
361 if (nullptr != sc.speedLimit) {
362 prefix("Speed Limit") << *(sc.speedLimit) << "\n";
363 }
364 --level;
365 }
366 else // SpecialVehicleContainer_PR_NOTHING
367 prefix("Special Vehicle Container") << ("present but empty") << "\n";
368 }
369 else
370 prefix("Special Vehicle Container") << "not present" << "\n";
371
372 --level;
373}
374
375} // namespace facilities
376} // namespace vanetza