Skip to content

Commit

Permalink
Merge pull request #42 from iyourshaw/fix-vehicle-event-flags-jackknife
Browse files Browse the repository at this point in the history
Fix VehicleEventFlaga Jackknife Event Extension
  • Loading branch information
drewjj authored Feb 25, 2025
2 parents 8817c29 + 606dfd4 commit 0511993
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 29 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ settings.json
asn1c_combined/compile.out
asn1c_combined/converter-example
asn1c_combined/converter-example.mk
asn1c_combined/libasncodec.a
asn1c_combined/libasncodec.a

.idea/
cmake-build-*/
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.1)
project(ACM)

# need to set these prior to setting any targets.
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_VERBOSE_MAKEFILE ON)
Expand Down
7 changes: 0 additions & 7 deletions asn1c_combined/generate-files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ if [ "$year" == "2024" ]; then
patch --binary --backup --forward --reject-file="-" \
./j2735-asn-files/2024/J3217-TollUsageMsg-2024-rel-v1.1.asn \
./j2735-asn-files/2024/asn-edits/TollUsageMessage.patch
patch --binary --backup --forward --reject-file="-" \
./j2735-asn-files/2024/J2735-Common-2024-rel-v1.1.2.asn \
./j2735-asn-files/2024/asn-edits/Common.patch

# Verify that the patches were applied correctly
if ! grep -q RwmSnapShot ./j2735-asn-files/2024/J2945-3-RoadWeatherMessage-2024-rel-v2.1.asn; then
Expand All @@ -56,10 +53,6 @@ if [ "$year" == "2024" ]; then
exit 1
fi

if grep -q " eventJackKnife " ./j2735-asn-files/2024/J2735-Common-2024-rel-v1.1.2.asn; then
echo "The patch for the Common ASN file was not applied correctly."
exit 1
fi
fi


Expand Down
Binary file modified asn1c_combined/generated-files/2024.tar.gz
Binary file not shown.
17 changes: 0 additions & 17 deletions asn1c_combined/j2735-asn-files/2024/asn-edits/Common.patch

This file was deleted.

95 changes: 95 additions & 0 deletions asn1c_combined/j2735-asn-files/2024/overrides/VehicleEventFlags.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
* From ASN.1 module "Common"
* found in "./j2735-asn-files/2024/J2735-Common-2024-rel-v1.1.2.asn"
* `asn1c -fcompound-names -gen-OER -fincludes-quoted -no-gen-JER -pdu=all -D ./generated-files/2024`
*/

#include "VehicleEventFlags.h"

int
VehicleEventFlags_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
asn_app_constraint_failed_f *ctfailcb, void *app_key) {
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
size_t size;

if(!sptr) {
ASN__CTFAIL(app_key, td, sptr,
"%s: value not given (%s:%d)",
td->name, __FILE__, __LINE__);
return -1;
}

if(st->size > 0) {
/* Size in bits */
size = 8 * st->size - (st->bits_unused & 0x07);
} else {
size = 0;
}

/*
* NOT edited. Keep the size constraint including extension in this check.
*/
if((size >= 13UL && size <= 14UL)) {
/* Constraint check succeeded */
return 0;
} else {
ASN__CTFAIL(app_key, td, sptr,
"%s: constraint failed (%s:%d)",
td->name, __FILE__, __LINE__);
return -1;
}
}

/*
* This type is implemented using BIT_STRING,
* so here we adjust the DEF accordingly.
*/
#if !defined(ASN_DISABLE_OER_SUPPORT)
static asn_oer_constraints_t asn_OER_type_VehicleEventFlags_constr_1 CC_NOTUSED = {
{ 0, 0 },
-1 /* (SIZE(0..MAX)) */};
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */

/*
* EDITED PER size constraint
* originally: (SIZE(13..14,...))
* changed to: (SIZE(13,...))
*/
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
asn_per_constraints_t asn_PER_type_VehicleEventFlags_constr_1 CC_NOTUSED = {
{ APC_UNCONSTRAINED, -1, -1, 0, 0 },
{ APC_CONSTRAINED | APC_EXTENSIBLE, 0, 0, 13, 13 },
0, 0 /* No PER value map */
};
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */

static const ber_tlv_tag_t asn_DEF_VehicleEventFlags_tags_1[] = {
(ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
};
asn_TYPE_descriptor_t asn_DEF_VehicleEventFlags = {
"VehicleEventFlags",
"VehicleEventFlags",
&asn_OP_BIT_STRING,
asn_DEF_VehicleEventFlags_tags_1,
sizeof(asn_DEF_VehicleEventFlags_tags_1)
/sizeof(asn_DEF_VehicleEventFlags_tags_1[0]), /* 1 */
asn_DEF_VehicleEventFlags_tags_1, /* Same as above */
sizeof(asn_DEF_VehicleEventFlags_tags_1)
/sizeof(asn_DEF_VehicleEventFlags_tags_1[0]), /* 1 */
{
#if !defined(ASN_DISABLE_OER_SUPPORT)
&asn_OER_type_VehicleEventFlags_constr_1,
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
&asn_PER_type_VehicleEventFlags_constr_1,
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
#if !defined(ASN_DISABLE_JER_SUPPORT)
0,
#endif /* !defined(ASN_DISABLE_JER_SUPPORT) */
VehicleEventFlags_constraint
},
0, 0, /* Defined elsewhere */
&asn_SPC_BIT_STRING_specs /* Additional specs */
};

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<OdeAsn1Data><metadata><bsmSource>RV</bsmSource><logFileName/><recordType>bsmTx</recordType><securityResultCode>success</securityResultCode><receivedMessageDetails><locationData><latitude/><longitude/><elevation/><speed/><heading/></locationData><rxSource>RV</rxSource></receivedMessageDetails><encodings><encodings><elementName>unsecuredData</elementName><elementType>MessageFrame</elementType><encodingRule>UPER</encodingRule></encodings></encodings><payloadType>us.dot.its.jpo.ode.model.OdeAsn1Payload</payloadType><serialId><streamId>bee2fd4f-f2e4-4a91-a35c-dabf83f22dec</streamId><bundleSize>1</bundleSize><bundleId>0</bundleId><recordId>0</recordId><serialNumber>0</serialNumber></serialId><odeReceivedAt>2023-02-21T21:08:03.588646Z</odeReceivedAt><schemaVersion>6</schemaVersion><maxDurationTime>0</maxDurationTime><recordGeneratedAt/><recordGeneratedBy/><sanitized>false</sanitized><odePacketID/><odeTimStartDateTime/><originIp>10.10.10.10</originIp></metadata><payload><dataType>us.dot.its.jpo.ode.model.OdeHexByteArray</dataType><data><bytes>0014515767567EDDDFA3E68037E116658105B0DA9414000070F402B0FD630FA1007F82800000000000A9D0E00040C227738206DF900A482429E82C7DF900F4C268B282DE5F7015602B18982B1DED82000D50F680</bytes></data></payload></OdeAsn1Data>
161 changes: 158 additions & 3 deletions src/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "acm.hpp"
#include "utilities.hpp"


bool loadTestCases( const std::string& case_file, StrVector& case_data ) {

std::string line;
Expand All @@ -26,6 +27,7 @@ bool loadTestCases( const std::string& case_file, StrVector& case_data ) {
}

pugi::xpath_query ode_payload_query("OdeAsn1Data/payload/data");
pugi::xpath_query bsm_vehicle_event_flags_query("MessageFrame/value/BasicSafetyMessage/partII/BSMpartIIExtension/partII-Value/VehicleSafetyExtensions/events");
pugi::xml_document output_doc;
pugi::xml_parse_result parse_result;
pugi::xml_node payload_node;
Expand Down Expand Up @@ -222,8 +224,8 @@ TEST_CASE("Decode BSM", "[decoding]") {
CHECK(payload_node);
}

TEST_CASE("Decode BSM with VehicleEventFlags", "[decoding]") {
std::cout << "=== Decode BSM with VehicleEventFlags ===" << std::endl;
TEST_CASE("Decode BSM with VehicleEventFlags (hard braking event)", "[decoding]") {
std::cout << "=== Decode BSM with VehicleEventFlags (hard braking event) ===" << std::endl;

// prepare
asn1_codec.setup_logger_for_testing();
Expand All @@ -234,4 +236,157 @@ TEST_CASE("Decode BSM with VehicleEventFlags", "[decoding]") {
CHECK(parse_result);
payload_node = ode_payload_query.evaluate_node(output_doc).node();
CHECK(payload_node);
}
pugi::xml_node event_flags_node = bsm_vehicle_event_flags_query.evaluate_node(payload_node).node();
CHECK(event_flags_node);
std::string bitstring(event_flags_node.text().get());
std::cout << "VehicleEventFlags: " << bitstring << std::endl;
std::string expected_bitstring("0000000100000");
CHECK(bitstring == expected_bitstring);
}

TEST_CASE("Decode BSM with VehicleEventFlags (jackknife event)", "[decoding]") {
std::cout << "=== Decode BSM with VehicleEventFlags (jackknife event) ===" << std::endl;

// prepare
asn1_codec.setup_logger_for_testing();

std::stringstream out9;
CHECK(asn1_codec.file_test("data/InputData.decoding.bsm.with.VehicleEventFlags.eventJackKnife.xml", out9, false) == EXIT_SUCCESS);
parse_result = output_doc.load(out9, pugi::parse_default | pugi::parse_declaration | pugi::parse_doctype | pugi::parse_trim_pcdata);
CHECK(parse_result);
payload_node = ode_payload_query.evaluate_node(output_doc).node();
CHECK(payload_node);
pugi::xml_node event_flags_node = bsm_vehicle_event_flags_query.evaluate_node(payload_node).node();
CHECK(event_flags_node);
std::string bitstring(event_flags_node.text().get());
std::cout << "VehicleEventFlags: " << bitstring << std::endl;
std::string expected_bitstring("00000000000001");
CHECK(bitstring == expected_bitstring);
}

/*
* Utilities for VehicleEventFlags tests
*/

void print_bits(const void * buf, const ssize_t num_bytes) {
std::cout << "uper: ";
for (int i = 0; i < num_bytes; i++) {
uint8_t abyte = *((uint8_t *)buf + i);
std::cout << std::bitset<8>(abyte) << " ";
}
std::cout << std::endl;
}

void test_encode_VehicleEventFlags_to_uper(const uint16_t bitstring, const uint8_t *expected_uper, const ssize_t expected_byte_len) {
std::cout << "bitstring: " << std::bitset<16>(bitstring) << std::endl;
const uint8_t buf[] = { static_cast<uint8_t>(bitstring >> 8), static_cast<uint8_t>(bitstring & 0xFF) };
const size_t size = sizeof(buf);
uint8_t *ptr_buf = (uint8_t *)&buf;
const int bits_unused = __builtin_ctz(bitstring);
asn_struct_ctx_t asn_ctx = {};
VehicleEventFlags_t vef = {ptr_buf, size, bits_unused, asn_ctx};
VehicleEventFlags_t* ptr_vef = &vef;
asn_TYPE_descriptor_t *vef_type = &asn_DEF_VehicleEventFlags;
asn_encode_to_new_buffer_result_t res
= asn_encode_to_new_buffer(0, ATS_UNALIGNED_BASIC_PER, vef_type, ptr_vef);
if (res.buffer) {
printf("Successfully encoded %ld bytes to uper\n", res.result.encoded);
print_bits(res.buffer, res.result.encoded);
} else {
FAIL("Error encoding vef");
return;
}
if (res.result.encoded != expected_byte_len) {
fprintf(stderr, "Error, expected %ld bytes but got %ld", expected_byte_len, res.result.encoded);
FAIL("Wrong number of bytes");
}
if (memcmp(expected_uper, (uint8_t *)res.buffer, res.result.encoded) != 0) {
FAIL("Error, Uper doesn't match expected");
}
free(res.buffer);
}

void test_decode_VehicleEventFlags_from_uper(const uint8_t * uper, const ssize_t uper_len, const uint16_t expected_bitstring,
const int expect_constraint_to_fail) {
print_bits(uper, uper_len);
VehicleEventFlags_t * ptr_vef = 0;
asn_dec_rval_t rval
= asn_decode(0, ATS_UNALIGNED_BASIC_PER, &asn_DEF_VehicleEventFlags, (void **)&ptr_vef, uper, uper_len);
if (rval.code != RC_OK) {
FAIL("Error decoding");
return;
}
printf("Successfully decoded %ld bytes\n", rval.consumed);
printf("bitstring size: %ld, bits_unused: %d\n", ptr_vef->size, ptr_vef->bits_unused);

if (ptr_vef->size != 2) {
FAIL("Error, expected bitstring to be 2 bytes");
}
uint16_t actual_bitstring = (ptr_vef->buf[0] << 8) | ptr_vef->buf[1];
std::cout << "bitstring: " << std::bitset<16>(actual_bitstring) << std::endl;
if (actual_bitstring != expected_bitstring) {
std::cout << "Error, expected bitstring: " << std::bitset<16>(expected_bitstring)
<< " but got: " << std::bitset<16>(actual_bitstring) << std::endl;
FAIL("Bitstring mismatch");
}

// Check constraints
char errbuf[128];
size_t errlen = sizeof(errbuf);
int cons_ret = asn_check_constraints(&asn_DEF_VehicleEventFlags, ptr_vef, errbuf, &errlen);
if (cons_ret && !expect_constraint_to_fail) {
fprintf(stderr, "Constraint check failed: %s\n", errbuf);
FAIL("Unexpected constraint check fail");
}

ASN_STRUCT_FREE(asn_DEF_VehicleEventFlags, ptr_vef);
}

/*
* Data for VehicleEventFlags tests
*/
constexpr uint16_t bitstring_root = (0x8000 >> VehicleEventFlags_eventHazardLights)
| (0x8000 >> VehicleEventFlags_eventAirBagDeployment);
constexpr uint8_t uper_root[2] = { 0b01000000, 0b00000100 };

constexpr uint16_t bitstring_with_ext = (0x8000 >> VehicleEventFlags_eventHazardLights)
| (0x8000 >> VehicleEventFlags_eventAirBagDeployment)
| (0x8000 >> VehicleEventFlags_eventJackKnife);

constexpr uint8_t uper_with_ext[3] = { 0b10000111, 0b01000000, 0b00000110 };

constexpr uint16_t bitstring_15bits = (0x8000 >> VehicleEventFlags_eventHazardLights)
| (0x8000 >> VehicleEventFlags_eventAirBagDeployment)
| (0x8000 >> VehicleEventFlags_eventJackKnife)
| (0x8000 >> 14);
constexpr uint8_t uper_15bits[3] = {0b10000111, 0b11000000, 0b00000111 };

TEST_CASE("Encode VehicleEventFlags root, from struct to UPER, 13 bits", "[encoding]") {
std::cout << "=== Encode VehicleEventFlags root, from struct to UPER, 13 bits ===" << std::endl;
test_encode_VehicleEventFlags_to_uper(bitstring_root, uper_root, 2);
}

TEST_CASE("Encode VehicleEventFlags with 2024 extension, from struct to UPER, 14 bits", "[encoding]") {
std::cout << "=== Encode VehicleEventFlags with 2024 extension to UPER, 14 bits ===" << std::endl;
test_encode_VehicleEventFlags_to_uper(bitstring_with_ext, uper_with_ext, 3);
}

TEST_CASE("Encode VehicleEventFlags with unknown future extension, from struct to UPER, 15 bits", "[encoding]") {
std::cout << "=== Encode VehicleEventFlags with unknown future extension, from struct to UPER, 15 bits ===" << std::endl;
test_encode_VehicleEventFlags_to_uper(bitstring_15bits, uper_15bits, 3);
}

TEST_CASE("Decode VehicleEventFlags root, from UPER to struct, 13 bits", "[decoding]") {
std::cout << "=== Decode VehicleEventFlags root, from UPER to struct, 13 bits ===" << std::endl;
test_decode_VehicleEventFlags_from_uper(uper_root, 2, bitstring_root, 0);
}

TEST_CASE("Decode VehicleEventFlags with 2024 extension, from UPER to struct, 14 bits", "[decoding]") {
std::cout << "=== Decode VehicleEventFlags with 2024 extension, from UPER to struct, 14 bits ===" << std::endl;
test_decode_VehicleEventFlags_from_uper(uper_with_ext, 3, bitstring_with_ext, 0);
}

TEST_CASE("Decode VehicleEventFlags with unknown future extension, from UPER to struct, 15 bits", "[decoding]") {
std::cout << "=== Decode VehicleEventFlags with unknown future extension, from UPER to struct, 15 bits ===" << std::endl;
test_decode_VehicleEventFlags_from_uper(uper_15bits, 3, bitstring_15bits, 1);
}

0 comments on commit 0511993

Please sign in to comment.