Open Thiesius opened 2 years ago
Could you post the ASN.1 snippit with the problem?
ASN.1 descriptions: https://forge.etsi.org/rep/ITS/asn1/cdd_ts102894_2/blob/master/ITS-Container.asn https://forge.etsi.org/rep/ITS/asn1/cam_en302637_2/blob/master/CAM-PDU-Descriptions.asn
I used sample from ASN.1 Playground as a baseline:
value1 CAM ::= {
header {
protocolVersion 1,
messageID cam,
stationID 1234567
},
cam {
generationDeltaTime 11409,
camParameters {
basicContainer {
stationType passengerCar,
referencePosition {
latitude 40487111,
longitude 79494789,
positionConfidenceEllipse {
semiMajorConfidence 500,
semiMinorConfidence 400,
semiMajorOrientation wgs84North
},
altitude {
altitudeValue 2000,
altitudeConfidence alt-000-02
}
}
},
highFrequencyContainer basicVehicleContainerHighFrequency : {
heading {
headingValue wgs84North,
headingConfidence equalOrWithinZeroPointOneDegree
},
speed {
speedValue 2000,
speedConfidence equalOrWithinOneCentimeterPerSec
},
driveDirection forward,
vehicleLength {
vehicleLengthValue 35,
vehicleLengthConfidenceIndication noTrailerPresent
},
vehicleWidth 20,
longitudinalAcceleration {
longitudinalAccelerationValue 10,
longitudinalAccelerationConfidence pointOneMeterPerSecSquared
},
curvature {
curvatureValue straight,
curvatureConfidence onePerMeter-0-00002
},
curvatureCalculationMode yawRateUsed,
yawRate {
yawRateValue straight,
yawRateConfidence degSec-000-01
},
accelerationControl '0100000'B,
steeringWheelAngle {
steeringWheelAngleValue 30,
steeringWheelAngleConfidence equalOrWithinOnePointFiveDegree
},
lateralAcceleration {
lateralAccelerationValue -2,
lateralAccelerationConfidence pointOneMeterPerSecSquared
},
verticalAcceleration {
verticalAccelerationValue pointOneMeterPerSecSquaredUp,
verticalAccelerationConfidence pointOneMeterPerSecSquared
}
},
specialVehicleContainer publicTransportContainer : {
embarkationStatus FALSE,
ptActivation {
ptActivationType undefinedCodingType,
ptActivationData '001122334455'H
}
}
}
}
}
Message on above rewritten in code I used to test it.
fast_ber::CAM_PDU_Descriptions::CAM msg{};
msg.header.messageID = 2;
msg.header.protocolVersion = 1;
msg.header.stationID = 1234567;
msg.cam.generationDeltaTime = 11409;
auto& bc = msg.cam.camParameters.basicContainer;
bc.stationType = 5;
bc.referencePosition.latitude = 40487111;
bc.referencePosition.longitude = 79494789;
bc.referencePosition.positionConfidenceEllipse.semiMajorConfidence = 500;
bc.referencePosition.positionConfidenceEllipse.semiMinorConfidence = 400;
bc.referencePosition.positionConfidenceEllipse.semiMajorOrientation = 0;
bc.referencePosition.altitude.altitudeValue = 2000;
bc.referencePosition.altitude.altitudeConfidence = fast_ber::ITS_Container::AltitudeConfidenceValues::alt_000_02;
fast_ber::CAM_PDU_Descriptions::BasicVehicleContainerHighFrequency basicVehContHF{};
basicVehContHF.heading.headingValue = 0;
basicVehContHF.heading.headingConfidence = 1;
basicVehContHF.speed.speedValue = 2000;
basicVehContHF.speed.speedConfidence = 1;
basicVehContHF.driveDirection = fast_ber::ITS_Container::DriveDirectionValues::forward;
basicVehContHF.vehicleLength.vehicleLengthValue = 35;
basicVehContHF.vehicleLength.vehicleLengthConfidenceIndication = fast_ber::ITS_Container::VehicleLengthConfidenceIndicationValues::noTrailerPresent;
basicVehContHF.vehicleWidth = 20;
basicVehContHF.longitudinalAcceleration.longitudinalAccelerationValue = 10;
basicVehContHF.longitudinalAcceleration.longitudinalAccelerationConfidence = 1;
basicVehContHF.curvature.curvatureValue = 0;
basicVehContHF.curvature.curvatureConfidence = fast_ber::ITS_Container::CurvatureConfidenceValues::onePerMeter_0_00002;
basicVehContHF.curvatureCalculationMode = fast_ber::ITS_Container::CurvatureCalculationModeValues::yawRateUsed;
basicVehContHF.yawRate.yawRateValue = 0;
basicVehContHF.yawRate.yawRateConfidence = fast_ber::ITS_Container::YawRateConfidenceValues::degSec_000_01;
std::array<uint8_t, 2> accelControl = {0x01, 0x40};
basicVehContHF.accelerationControl = std::span(accelControl);
fast_ber::ITS_Container::SteeringWheelAngle steeringWheelAngle{};
steeringWheelAngle.steeringWheelAngleValue = 30;
steeringWheelAngle.steeringWheelAngleConfidence = 1;
basicVehContHF.steeringWheelAngle = steeringWheelAngle;
fast_ber::ITS_Container::LateralAcceleration latAcc{};
latAcc.lateralAccelerationValue = -2;
latAcc.lateralAccelerationConfidence = 1;
basicVehContHF.lateralAcceleration = latAcc;
fast_ber::ITS_Container::VerticalAcceleration vertiAcc{};
vertiAcc.verticalAccelerationValue = 1;
vertiAcc.verticalAccelerationConfidence = 1;
basicVehContHF.verticalAcceleration = vertiAcc;
fast_ber::CAM_PDU_Descriptions::BasicVehicleContainerLowFrequency basicVehContLF{};
basicVehContLF.vehicleRole = fast_ber::ITS_Container::VehicleRoleValues::default_;
std::array<uint8_t, 2> exterLights = {0x00, 0xA8};
basicVehContLF.exteriorLights = std::span(exterLights);
fast_ber::ITS_Container::PathPoint pp{};
pp.pathDeltaTime = 1000;
pp.pathPosition.deltaLatitude = 10000;
pp.pathPosition.deltaLongitude = 5000;
pp.pathPosition.deltaAltitude = 12800;
basicVehContLF.pathHistory.emplace_back(std::move(pp));
fast_ber::CAM_PDU_Descriptions::PublicTransportContainer pubTransportCont{};
pubTransportCont.embarkationStatus = false;
fast_ber::ITS_Container::PtActivation ptAct{};
std::array<uint8_t, 6> testData = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
ptAct.ptActivationData = std::span(testData);
ptAct.ptActivationType = 0;
pubTransportCont.ptActivation = std::move(ptAct);
msg.cam.camParameters.highFrequencyContainer = std::move(basicVehContHF);
msg.cam.camParameters.lowFrequencyContainer = std::move(basicVehContLF);
msg.cam.camParameters.specialVehicleContainer = std::move(pubTransportCont);
My blanket fix I did yesterday (prepare the bucket :D ): https://github.com/Roboauto/fast_ber/commit/089d3a2dfb3c8b14da066791f578fbec86dcf6c6
I used https://lapo.it/asn1js/ to compare the results
Thanks I will take a look
Using ETSI CAM 1.4.1 the Automatic tags are not respected (context_specific class is not used) and the message fails to validate against ASN1 Playground
Please note that I have no real understanding of ASN.1 and BER encoding. So my fixes might seem naive. Anyways:
I have managed in somewhat uneducated way fix the encoder with generating context_specific id when the tagging_mode is automatic and the component in collection / choice is a SequenceType or ChoiceType. This "fix" somehow broke encoded_size as the returned value is 204 and real message size is actually 210. This encoding might also work only for my use case as I haven't tested anything else. However the generated bytes are same as the message from ASN1 Playground.
I also fixed the decoder in similar way as the encoder. "create_collection_decode_functions" for optional types is another sort of hack by collecting all ids from all components and generating that huge "if" statement for them. I only tested that on decoding the message I previously encoded.