Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,7 @@ private RsuContainerHighFrequency readRsuHF(JsonParser parser) throws IOExceptio
parser.skipChildren();
}
}
return new RsuContainerHighFrequency(
requireField(zones, "rsu_container_high_frequency.protected_communication_zones_rsu"));
return new RsuContainerHighFrequency(zones);
}

private List<ProtectedCommunicationZone> readProtectedZones(JsonParser parser) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,24 +189,26 @@ private void writeBasicVehicleHF(JsonGenerator gen, BasicVehicleContainerHighFre

private void writeRsuHF(JsonGenerator gen, RsuContainerHighFrequency container) throws IOException {
gen.writeStartObject();
gen.writeArrayFieldStart("protected_communication_zones_rsu");
for (ProtectedCommunicationZone zone : container.protectedCommunicationZonesRsu()) {
gen.writeStartObject();
gen.writeNumberField("protected_zone_type", zone.protectedZoneType());
if (zone.expiryTime() != null) {
gen.writeNumberField("expiry_time", zone.expiryTime());
}
gen.writeNumberField("protected_zone_latitude", zone.protectedZoneLatitude());
gen.writeNumberField("protected_zone_longitude", zone.protectedZoneLongitude());
if (zone.protectedZoneRadius() != null) {
gen.writeNumberField("protected_zone_radius", zone.protectedZoneRadius());
}
if (zone.protectedZoneId() != null) {
gen.writeNumberField("protected_zone_id", zone.protectedZoneId());
if (container.protectedCommunicationZonesRsu() != null) {
gen.writeArrayFieldStart("protected_communication_zones_rsu");
for (ProtectedCommunicationZone zone : container.protectedCommunicationZonesRsu()) {
gen.writeStartObject();
gen.writeNumberField("protected_zone_type", zone.protectedZoneType());
if (zone.expiryTime() != null) {
gen.writeNumberField("expiry_time", zone.expiryTime());
}
gen.writeNumberField("protected_zone_latitude", zone.protectedZoneLatitude());
gen.writeNumberField("protected_zone_longitude", zone.protectedZoneLongitude());
if (zone.protectedZoneRadius() != null) {
gen.writeNumberField("protected_zone_radius", zone.protectedZoneRadius());
}
if (zone.protectedZoneId() != null) {
gen.writeNumberField("protected_zone_id", zone.protectedZoneId());
}
gen.writeEndObject();
}
gen.writeEndObject();
gen.writeEndArray();
}
gen.writeEndArray();
gen.writeEndObject();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@
package com.orange.iot3mobility.messages.cam.v240.model.highfrequencycontainer;

import java.util.List;
import java.util.Objects;

/**
* RsuContainerHighFrequency v2.4.0
*
* @param protectedCommunicationZonesRsu List of RSU {@link ProtectedCommunicationZone}
* @param protectedCommunicationZonesRsu Optional list of RSU {@link ProtectedCommunicationZone}.
* May be {@code null} — the field is optional per the schema.
* When present, must contain between 1 and 16 entries.
*/
public record RsuContainerHighFrequency(
List<ProtectedCommunicationZone> protectedCommunicationZonesRsu) implements HighFrequencyContainer {
public RsuContainerHighFrequency {
protectedCommunicationZonesRsu = List.copyOf(Objects.requireNonNull(protectedCommunicationZonesRsu));
protectedCommunicationZonesRsu = protectedCommunicationZonesRsu != null
? List.copyOf(protectedCommunicationZonesRsu)
: null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,10 @@ private static void validateBasicVehicleHF(BasicVehicleContainerHighFrequency co
}

private static void validateRsuHF(RsuContainerHighFrequency container) {
List<ProtectedCommunicationZone> zones =
requireNonNull("rsu_container_high_frequency.protected_communication_zones_rsu",
container.protectedCommunicationZonesRsu());
List<ProtectedCommunicationZone> zones = container.protectedCommunicationZonesRsu();
if (zones == null) {
return;
}
int size = zones.size();
if (size < 1 || size > 16) {
throw new CamValidationException("protected_communication_zones_rsu size out of range [1,16]: " + size);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.orange.iot3mobility.messages.cam.v240.model.highfrequencycontainer.BasicVehicleContainerHighFrequency;
import com.orange.iot3mobility.messages.cam.v240.model.highfrequencycontainer.Curvature;
import com.orange.iot3mobility.messages.cam.v240.model.highfrequencycontainer.Heading;
import com.orange.iot3mobility.messages.cam.v240.model.highfrequencycontainer.RsuContainerHighFrequency;
import com.orange.iot3mobility.messages.cam.v240.model.highfrequencycontainer.Speed;
import com.orange.iot3mobility.messages.cam.v240.model.highfrequencycontainer.VehicleLength;
import com.orange.iot3mobility.messages.cam.v240.model.highfrequencycontainer.YawRate;
Expand Down Expand Up @@ -83,6 +84,24 @@ void writeRead240WithLinkedStationIdRoundTrip() throws Exception {
assertEquals(4294967295L, parsed.linkedStationId());
}

@Test
void writeRead240RsuWithoutZonesRoundTrip() throws Exception {
CamEnvelope240 envelope = validEnvelope240Rsu();
CamCodec codec = new CamCodec(new JsonFactory());

ByteArrayOutputStream out = new ByteArrayOutputStream();
codec.write(CamVersion.V2_4_0, envelope, out);

CamCodec.CamFrame<?> frame = codec.read(new ByteArrayInputStream(out.toByteArray()));
assertEquals(CamVersion.V2_4_0, frame.version());
assertTrue(frame.envelope() instanceof CamEnvelope240);
CamEnvelope240 parsed = (CamEnvelope240) frame.envelope();
assertEquals(envelope.sourceUuid(), parsed.sourceUuid());
CamStructuredData parsedMsg = (CamStructuredData) parsed.message();
assertTrue(parsedMsg.highFrequencyContainer() instanceof RsuContainerHighFrequency);
assertNull(((RsuContainerHighFrequency) parsedMsg.highFrequencyContainer()).protectedCommunicationZonesRsu());
}

@Test
void readRejectsMissingVersion() {
CamCodec codec = new CamCodec(new JsonFactory());
Expand Down Expand Up @@ -154,6 +173,37 @@ private static CamEnvelope240 validEnvelope240() {
.build();
}

private static CamEnvelope240 validEnvelope240Rsu() {
com.orange.iot3mobility.messages.cam.v240.model.basiccontainer.ReferencePosition reference =
com.orange.iot3mobility.messages.cam.v240.model.basiccontainer.ReferencePosition.builder()
.latitudeLongitude(0, 0)
.positionConfidenceEllipse(new PositionConfidenceEllipse(0, 0, 0))
.altitude(new Altitude(0, 0))
.build();

BasicContainer basic = BasicContainer.builder()
.stationType(15)
.referencePosition(reference)
.build();

RsuContainerHighFrequency rsu = new RsuContainerHighFrequency(null);

CamStructuredData message = CamStructuredData.builder()
.protocolVersion(1)
.stationId(99)
.generationDeltaTime(1)
.basicContainer(basic)
.highFrequencyContainer(rsu)
.build();

return CamEnvelope240.builder()
.messageFormat("json/raw")
.sourceUuid("com_rsu_99")
.timestamp(1514764800000L)
.message(message)
.build();
}

private static CamEnvelope240 validEnvelope240WithLinkedStationId() {
com.orange.iot3mobility.messages.cam.v240.model.basiccontainer.ReferencePosition reference =
com.orange.iot3mobility.messages.cam.v240.model.basiccontainer.ReferencePosition.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,28 @@ void validateEnvelopeRejectsAsn1InvalidBase64() {
assertThrows(CamValidationException.class, () -> CamValidator240.validateEnvelope(envelope));
}

@Test
void validateEnvelopeAcceptsRsuWithoutProtectedZones() {
RsuContainerHighFrequency rsu = new RsuContainerHighFrequency(null);

CamStructuredData message = CamStructuredData.builder()
.protocolVersion(1)
.stationId(42)
.generationDeltaTime(1)
.basicContainer(validBasicContainer())
.highFrequencyContainer(rsu)
.build();

CamEnvelope240 envelope = CamEnvelope240.builder()
.messageFormat("json/raw")
.sourceUuid("com_rsu_42")
.timestamp(1514764800000L)
.message(message)
.build();

CamValidator240.validateEnvelope(envelope);
}

@Test
void validateEnvelopeRejectsEmptyRsuZones() {
ReferencePosition reference = ReferencePosition.builder()
Expand Down
Loading