diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 963bfc84..d4d47cb9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -144,6 +144,7 @@ jobs: sonar.sourceEncoding=UTF-8 EOF - name: SonarScanner + if: github.event.pull_request.base.repo.owner.login == 'usdot-jpo-ode' uses: usdot-fhwa-stol/actions/sonar-scanner@main with: sonar-properties-path: /tmp/sonar-scanner.properties diff --git a/.gitmodules b/.gitmodules index 095c39fc..1a081437 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,4 +3,4 @@ url = https://github.com/zeux/pugixml.git [submodule "usdot-asn1c"] path = usdot-asn1c - url = https://github.com/usdot-fhwa-stol/usdot-asn1c + url = https://github.com/usdot-fhwa-stol/usdot-asn1c.git diff --git a/CMakeLists.txt b/CMakeLists.txt index faaeb02d..fc2da076 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,9 @@ link_directories("/usr/local/lib") # CPP Preprocessor variable PDU is used in the asn1-j2735-lib.h file to build a variable to a ASN.1 parsing structure. # This variable may need changing if we are parsing some other type of ASN.1 schema. -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPDU=MessageFrame") +# Define HAVE_TM_GMTOFF to allow compiling the generated code for GeneralizedTime types in Alpine +# Define ASN_PDU_COLLECTION to compile all PDUs that were generated. +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_TM_GMTOFF -DASN_PDU_COLLECTION") # Currently using boost/asio, not standalone asio. # If it were desired to use standalone asio, uncomment the following: diff --git a/README.md b/README.md index 6d81be94..c208f9fc 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,8 @@ consumers and producers do not run in this mode. **Other Documents** 1. [Installation](docs/installation.md) 2. [Configuration and Operation](docs/configuration.md) -2. [Interface](docs/interface.md) -3. [Testing](docs/testing.md) +3. [Interface](docs/interface.md) +4. [Testing](docs/testing.md) ## Release Notes The current version and release history of the asn1_codec: [asn1_codec Release Notes]() diff --git a/asn1c_combined/doIt.sh b/asn1c_combined/doIt.sh index 48ef6a56..414cd010 100755 --- a/asn1c_combined/doIt.sh +++ b/asn1c_combined/doIt.sh @@ -13,15 +13,21 @@ else year=$J2735_YEAR fi -# Copy generated files to for specified year to asn1c_combined & extract +# Copy generated files for specified year to asn1c_combined & extract echo "Extracting & copying generated files for $year" tar -xzf ./generated-files/$year.tar.gz cp ./generated-files/$year/* . # Compile example echo "Compiling example" -sed -i 's/\(-DASN_PDU_COLLECTION\)/-DPDU=MessageFrame \1/' ./converter-example.mk -make -f ./converter-example.mk + +# The HAVE_TM_GMTOFF flag needs to be set to compile GeneralizedTime.c on platforms including Alpine. +# Add it to ASN_MODULE_CFLAGS which gets added to CFLAGS in converter-example.mk +make ASN_MODULE_CFLAGS="-DHAVE_TM_GMTOFF" -f ./converter-example.mk + +# Verify that the converter example executable compiled and can run +./converter-example -p list + # Clean up echo "Cleaning up" diff --git a/asn1c_combined/generate-files.sh b/asn1c_combined/generate-files.sh index a3188e41..f38a6ce2 100644 --- a/asn1c_combined/generate-files.sh +++ b/asn1c_combined/generate-files.sh @@ -24,53 +24,24 @@ if [ ! -d "./generated-files/$year" ]; then mkdir ./generated-files/$year fi -# If 2024, apply .ASN file edits -if [ "$year" == "2024" ]; then - echo "Applying J2735 ASN Edits" - patch --binary --backup --forward --reject-file="-" \ - ./j2735-asn-files/2024/J2945-3-RoadWeatherMessage-2024-rel-v2.1.asn \ - ./j2735-asn-files/2024/asn-edits/RoadWeatherMessage.patch - patch --binary --backup --forward --reject-file="-" \ - ./j2735-asn-files/2024/J3217-R-RoadUserChargingReportMsg-2024-rel-v1.1.asn \ - ./j2735-asn-files/2024/asn-edits/RoadUserChargingReportMessage.patch - 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 - # Verify that the patches were applied correctly - if ! grep -q RwmSnapShot ./j2735-asn-files/2024/J2945-3-RoadWeatherMessage-2024-rel-v2.1.asn; then - echo "The patch for the Road Weather Message ASN file was not applied correctly." - exit 1 - fi - - if ! grep -q TumVehicleId ./j2735-asn-files/2024/J3217-R-RoadUserChargingReportMsg-2024-rel-v1.1.asn; then - echo "The patch for the Road User Charging Report Message ASN file was not applied correctly." - exit 1 - fi +# Patches to the ASN.1 files aren't needed. +# If any ASN.1 file edits are needed in the future, do them here. - if ! grep -q TumVehicleId ./j2735-asn-files/2024/J3217-TollUsageMsg-2024-rel-v1.1.asn; then - echo "The patch for the Toll Usage Message ASN file was not applied correctly." - exit 1 - fi -fi - - -asn1c -fcompound-names -gen-OER -fincludes-quoted -no-gen-JER -pdu=all \ +# - Use -fno-included-deps to avoid issue with circular references. +# - Use -fcase-insensitive-filenames for compiling the 2024 specification to work in case-insensitive filesystems such as +# Windows WSL. +asn1c -fno-include-deps -fcompound-names -fcase-insensitive-filenames -gen-OER -fincludes-quoted -no-gen-JER -pdu=all \ ./scms-asn-files/*.asn \ ./j2735-asn-files/$year/*.asn \ ./semi-asn-files/$year/SEMI*.asn \ -D ./generated-files/$year \ 2>&1 | tee compile.out - -# if 2020 or 2024, copy overrides -if [ "$year" == "2020" ] || [ "$year" = "2024" ]; then - echo "Copying overrides for $year" - cp ./j2735-asn-files/$year/overrides/*.h ./generated-files/$year - cp ./j2735-asn-files/$year/overrides/*.c ./generated-files/$year -fi +# C code overrides aren't needed. +# If any overrides are needed in the future, copy them to the generated code them here. # tar generated files and delete originals diff --git a/asn1c_combined/generated-files/2020.tar.gz b/asn1c_combined/generated-files/2020.tar.gz index 4de059a4..d6274e69 100644 Binary files a/asn1c_combined/generated-files/2020.tar.gz and b/asn1c_combined/generated-files/2020.tar.gz differ diff --git a/asn1c_combined/generated-files/2024.tar.gz b/asn1c_combined/generated-files/2024.tar.gz index abd116c6..b0c87e4e 100644 Binary files a/asn1c_combined/generated-files/2024.tar.gz and b/asn1c_combined/generated-files/2024.tar.gz differ diff --git a/asn1c_combined/j2735-asn-files/2020/overrides/NodeOffsetPointXY.h b/asn1c_combined/j2735-asn-files/2020/overrides/NodeOffsetPointXY.h deleted file mode 100644 index 9bef9379..00000000 --- a/asn1c_combined/j2735-asn-files/2020/overrides/NodeOffsetPointXY.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) - * From ASN.1 module "Common" - * found in "J2735-Common.asn" - * `asn1c -pdu=MessageFrame -fcompound-names -fincludes-quoted -no-gen-JER` - */ - -#ifndef _NodeOffsetPointXY_H_ -#define _NodeOffsetPointXY_H_ - - -#include "asn_application.h" - -/* Including external dependencies */ -#include "Node-XY-20b.h" -#include "Node-XY-22b.h" -#include "Node-XY-24b.h" -#include "Node-XY-26b.h" -#include "Node-XY-28b.h" -#include "Node-XY-32b.h" -#include "Node-LLmD-64b.h" -#include "constr_CHOICE.h" -#include "asn_SEQUENCE_OF.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Forward declarations */ -struct Reg_NodeOffsetPointXY; - -/* Dependencies */ -typedef enum NodeOffsetPointXY_PR { - NodeOffsetPointXY_PR_NOTHING, /* No components present */ - NodeOffsetPointXY_PR_node_XY1, - NodeOffsetPointXY_PR_node_XY2, - NodeOffsetPointXY_PR_node_XY3, - NodeOffsetPointXY_PR_node_XY4, - NodeOffsetPointXY_PR_node_XY5, - NodeOffsetPointXY_PR_node_XY6, - NodeOffsetPointXY_PR_node_LatLon, - NodeOffsetPointXY_PR_regional -} NodeOffsetPointXY_PR; - -/* NodeOffsetPointXY */ -typedef struct NodeOffsetPointXY { - NodeOffsetPointXY_PR present; - union NodeOffsetPointXY_u { - Node_XY_20b_t node_XY1; - Node_XY_22b_t node_XY2; - Node_XY_24b_t node_XY3; - Node_XY_26b_t node_XY4; - Node_XY_28b_t node_XY5; - Node_XY_32b_t node_XY6; - Node_LLmD_64b_t node_LatLon; - // Reg_NodeOffsetPointXY_t regional; - - struct NodeOffsetPointXY__regional { - A_SEQUENCE_OF(struct Reg_NodeOffsetPointXY) list; - - /* Context for parsing across buffer boundaries */ - asn_struct_ctx_t _asn_ctx; - } *regional; - - } choice; - - /* Context for parsing across buffer boundaries */ - asn_struct_ctx_t _asn_ctx; -} NodeOffsetPointXY_t; - -/* Implementation */ -extern asn_TYPE_descriptor_t asn_DEF_NodeOffsetPointXY; -extern asn_CHOICE_specifics_t asn_SPC_NodeOffsetPointXY_specs_1; -extern asn_TYPE_member_t asn_MBR_NodeOffsetPointXY_1[8]; -extern asn_per_constraints_t asn_PER_type_NodeOffsetPointXY_constr_1; - -#ifdef __cplusplus -} -#endif - -/* Referred external types */ -#include "RegionalExtension.h" - -#endif /* _NodeOffsetPointXY_H_ */ -#include "asn_internal.h" diff --git a/asn1c_combined/j2735-asn-files/2024/.gitignore b/asn1c_combined/j2735-asn-files/2024/.gitignore index 2096ffba..c767f352 100644 --- a/asn1c_combined/j2735-asn-files/2024/.gitignore +++ b/asn1c_combined/j2735-asn-files/2024/.gitignore @@ -1,4 +1,4 @@ **/*.asn **/*.ASN **/*.asn.orig -**/*.asn.EDITED \ No newline at end of file +**/*.asn.edited \ No newline at end of file diff --git a/asn1c_combined/j2735-asn-files/2024/asn-edits/.gitattributes b/asn1c_combined/j2735-asn-files/2024/asn-edits/.gitattributes deleted file mode 100644 index 2fcec5da..00000000 --- a/asn1c_combined/j2735-asn-files/2024/asn-edits/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -*.patch text -*.patch eol=crlf \ No newline at end of file diff --git a/asn1c_combined/j2735-asn-files/2024/asn-edits/RoadUserChargingReportMessage.patch b/asn1c_combined/j2735-asn-files/2024/asn-edits/RoadUserChargingReportMessage.patch deleted file mode 100644 index 987f260f..00000000 --- a/asn1c_combined/j2735-asn-files/2024/asn-edits/RoadUserChargingReportMessage.patch +++ /dev/null @@ -1,9 +0,0 @@ ---- J3217-R-RoadUserChargingReportMsg-2024-rel-v1.1.asn 2024-02-22 14:49:42.000000000 -0700 -+++ J3217-R-RoadUserChargingReportMsg-2024-rel-v1.1.asn.EDITED 2024-11-17 00:19:57.157916800 -0700 -@@ -98 +98,2 @@ -- VehicleId -+ -- EDITED -+ TumVehicleId -@@ -144 +145 @@ -- vehicleID VehicleId, -- From J3217 TUM -+ vehicleID TumVehicleId, -- From J3217 TUM, EDITED diff --git a/asn1c_combined/j2735-asn-files/2024/asn-edits/RoadWeatherMessage.patch b/asn1c_combined/j2735-asn-files/2024/asn-edits/RoadWeatherMessage.patch deleted file mode 100644 index dcf4229e..00000000 --- a/asn1c_combined/j2735-asn-files/2024/asn-edits/RoadWeatherMessage.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- J2945-3-RoadWeatherMessage-2024-rel-v2.1.asn 2024-03-25 13:58:52.000000000 -0600 -+++ J2945-3-RoadWeatherMessage-2024-rel-v2.1.asn.EDITED 2024-11-17 00:22:05.128855100 -0700 -@@ -136 +136 @@ -- citizenReport SnapShot, -+ citizenReport RwmSnapShot, -- EDITED -@@ -141 +141 @@ -- snapShot SnapShot, -+ snapShot RwmSnapShot, -- EDITED -@@ -222,2 +222,4 @@ -- --SnapShot ::= SEQUENCE { -+-- EDITED -+-- Name changed to avoid conflict with "Snapshot", lowercase S, in module ProveVehicleData per -+-- this https://github.com/vlm/asn1c/issues/420 -+RwmSnapShot ::= SEQUENCE { diff --git a/asn1c_combined/j2735-asn-files/2024/asn-edits/TollUsageMessage.patch b/asn1c_combined/j2735-asn-files/2024/asn-edits/TollUsageMessage.patch deleted file mode 100644 index f7a29999..00000000 --- a/asn1c_combined/j2735-asn-files/2024/asn-edits/TollUsageMessage.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- J3217-TollUsageMsg-2024-rel-v1.1.asn 2024-02-21 17:09:52.000000000 -0700 -+++ J3217-TollUsageMsg-2024-rel-v1.1.asn.EDITED 2024-11-17 00:18:53.773971300 -0700 -@@ -157 +157 @@ -- vehicleId VehicleId, -+ vehicleId TumVehicleId, -@@ -184 +184,3 @@ --VehicleId ::= SEQUENCE { -+-- EDITED to avoid conflict with "VehicleID" in "Common" module. -+-- Name changed VehicleId -> TumVehicleId -+TumVehicleId ::= SEQUENCE { diff --git a/asn1c_combined/j2735-asn-files/2024/overrides/GeneralizedTime.c b/asn1c_combined/j2735-asn-files/2024/overrides/GeneralizedTime.c deleted file mode 100644 index 9b7517b1..00000000 --- a/asn1c_combined/j2735-asn-files/2024/overrides/GeneralizedTime.c +++ /dev/null @@ -1,748 +0,0 @@ -/*- - * Copyright (c) 2003-2019 Lev Walkin . All rights reserved. - * Redistribution and modifications are permitted subject to BSD license. - */ -#define _POSIX_PTHREAD_SEMANTICS /* for Sun */ -#define _REENTRANT /* for Sun */ -#define __EXTENSIONS__ /* for Sun */ -#ifndef _BSD_SOURCE -#define _BSD_SOURCE /* for timegm(3) */ -#endif -#include -#include - -#ifdef __CYGWIN__ -#include "/usr/include/time.h" -#else -#include -#endif /* __CYGWIN__ */ - -#include - - -#if defined(_WIN32) -#pragma message( "PLEASE STOP AND READ!") -#pragma message( " localtime_r is implemented via localtime(), which may be not thread-safe.") -#pragma message( " gmtime_r is implemented via gmtime(), which may be not thread-safe.") -#pragma message( " ") -#pragma message( " You must fix the code by inserting appropriate locking") -#pragma message( " if you want to use asn_GT2time() or asn_UT2time().") -#pragma message( "PLEASE STOP AND READ!") - -static struct tm *localtime_r(const time_t *tloc, struct tm *result) { - struct tm *tm; - if((tm = localtime(tloc))) - return memcpy(result, tm, sizeof(struct tm)); - return 0; -} - -static struct tm *gmtime_r(const time_t *tloc, struct tm *result) { - struct tm *tm; - if((tm = gmtime(tloc))) - return memcpy(result, tm, sizeof(struct tm)); - return 0; -} - -#define tzset() _tzset() -#define putenv(c) _putenv(c) -#define _EMULATE_TIMEGM - -#endif /* _WIN32 */ - -#if defined(sun) || defined(__sun) || defined(__solaris__) -#define _EMULATE_TIMEGM -#endif - -/* - * Where to look for offset from GMT, Phase I. - * Several platforms are known. - */ -#if defined(__FreeBSD__) || defined(__OpenBSD__) \ - || (defined(__GNUC__) && defined(__APPLE_CC__)) \ - || (defined __GLIBC__ && __GLIBC__ >= 2) -#undef HAVE_TM_GMTOFF -#define HAVE_TM_GMTOFF -#endif /* BSDs and newer glibc */ - -/* - * Where to look for offset from GMT, Phase II. - */ -/* HACK for Alpine */ -// #ifdef HAVE_TM_GMTOFF -#define GMTOFF(tm) ((tm).tm_gmtoff) -// #else /* HAVE_TM_GMTOFF */ -// #define GMTOFF(tm) (_timezone) -// #endif /* HAVE_TM_GMTOFF */ -/* END HACK */ - -#if defined(_WIN32) -#pragma message( "PLEASE STOP AND READ!") -#pragma message( " timegm() is implemented via getenv(\"TZ\")/setenv(\"TZ\"), which may be not thread-safe.") -#pragma message( " ") -#pragma message( " You must fix the code by inserting appropriate locking") -#pragma message( " if you want to use asn_GT2time() or asn_UT2time().") -#pragma message( "PLEASE STOP AND READ!") -#else -#if (defined(_EMULATE_TIMEGM) || !defined(HAVE_TM_GMTOFF)) -#warning "PLEASE STOP AND READ!" -#warning " timegm() is implemented via getenv(\"TZ\")/setenv(\"TZ\"), which may be not thread-safe." -#warning " " -#warning " You must fix the code by inserting appropriate locking" -#warning " if you want to use asn_GT2time() or asn_UT2time()." -#warning "PLEASE STOP AND READ!" -#endif /* _EMULATE_TIMEGM */ -#endif - -/* - * Override our GMTOFF decision for other known platforms. - */ -#ifdef __CYGWIN__ -#undef GMTOFF -static long GMTOFF(struct tm a){ - struct tm *lt; - time_t local_time, gmt_time; - long zone; - - tzset(); - gmt_time = time (NULL); - - lt = gmtime(&gmt_time); - - local_time = mktime(lt); - return (gmt_time - local_time); -} -#define _EMULATE_TIMEGM - -#endif /* __CYGWIN__ */ - -#define ATZVARS do { \ - char tzoldbuf[64]; \ - char *tzold -#define ATZSAVETZ do { \ - tzold = getenv("TZ"); \ - if(tzold) { \ - size_t tzlen = strlen(tzold); \ - if(tzlen < sizeof(tzoldbuf)) { \ - tzold = memcpy(tzoldbuf, tzold, tzlen + 1); \ - } else { \ - char *dupptr = tzold; \ - tzold = MALLOC(tzlen + 1); \ - if(tzold) memcpy(tzold, dupptr, tzlen + 1); \ - } \ - setenv("TZ", "UTC", 1); \ - } \ - tzset(); \ -} while(0) -#define ATZOLDTZ do { \ - if (tzold) { \ - setenv("TZ", tzold, 1); \ - *tzoldbuf = 0; \ - if(tzold != tzoldbuf) \ - FREEMEM(tzold); \ - } else { \ - unsetenv("TZ"); \ - } \ - tzset(); \ -} while(0); } while(0); - -#ifndef HAVE_TIMEGM -#ifdef _EMULATE_TIMEGM -#include -static time_t timegm(struct tm *tm) { - time_t tloc; - ATZVARS; - ATZSAVETZ; - tloc = mktime(tm); - ATZOLDTZ; - return tloc; -} -#endif /* _EMULATE_TIMEGM */ -#endif - - -#ifndef ASN___INTERNAL_TEST_MODE - -/* - * GeneralizedTime basic type description. - */ -static const ber_tlv_tag_t asn_DEF_GeneralizedTime_tags[] = { - (ASN_TAG_CLASS_UNIVERSAL | (24 << 2)), /* [UNIVERSAL 24] IMPLICIT ...*/ - (ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), /* [UNIVERSAL 26] IMPLICIT ...*/ - (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */ -}; -#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) -static asn_per_constraints_t asn_DEF_GeneralizedTime_per_constraints = { - { APC_CONSTRAINED, 7, 7, 0x20, 0x7e }, /* Value */ - { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */ - 0, 0 -}; -#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */ -asn_TYPE_operation_t asn_OP_GeneralizedTime = { - OCTET_STRING_free, -#if !defined(ASN_DISABLE_PRINT_SUPPORT) - GeneralizedTime_print, -#else - 0, -#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ - GeneralizedTime_compare, -#if !defined(ASN_DISABLE_BER_SUPPORT) - OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ - GeneralizedTime_encode_der, -#else - 0, - 0, -#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */ -#if !defined(ASN_DISABLE_XER_SUPPORT) - OCTET_STRING_decode_xer_utf8, - GeneralizedTime_encode_xer, -#else - 0, - 0, -#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */ -#if !defined(ASN_DISABLE_JER_SUPPORT) - OCTET_STRING_decode_jer_utf8, - GeneralizedTime_encode_jer, -#else - 0, - 0, -#endif /* !defined(ASN_DISABLE_JER_SUPPORT) */ -#if !defined(ASN_DISABLE_OER_SUPPORT) - OCTET_STRING_decode_oer, - OCTET_STRING_encode_oer, -#else - 0, - 0, -#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */ -#if !defined(ASN_DISABLE_UPER_SUPPORT) - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -#else - 0, - 0, -#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */ -#if !defined(ASN_DISABLE_APER_SUPPORT) - OCTET_STRING_decode_aper, - OCTET_STRING_encode_aper, -#else - 0, - 0, -#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */ -#if !defined(ASN_DISABLE_RFILL_SUPPORT) - GeneralizedTime_random_fill, -#else - 0, -#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */ - 0 /* Use generic outmost tag fetcher */ -}; -asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = { - "GeneralizedTime", - "GeneralizedTime", - &asn_OP_GeneralizedTime, - asn_DEF_GeneralizedTime_tags, - sizeof(asn_DEF_GeneralizedTime_tags) - / sizeof(asn_DEF_GeneralizedTime_tags[0]) - 2, - asn_DEF_GeneralizedTime_tags, - sizeof(asn_DEF_GeneralizedTime_tags) - / sizeof(asn_DEF_GeneralizedTime_tags[0]), - { -#if !defined(ASN_DISABLE_OER_SUPPORT) - 0, -#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */ -#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) - &asn_DEF_GeneralizedTime_per_constraints, -#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */ - GeneralizedTime_constraint - }, - 0, 0, /* No members */ - 0 /* No specifics */ -}; - -#endif /* ASN___INTERNAL_TEST_MODE */ - -/* - * Check that the time looks like the time. - */ -int -GeneralizedTime_constraint(const asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, - void *app_key) { - const GeneralizedTime_t *st = (const GeneralizedTime_t *)sptr; - time_t tloc; - - errno = EPERM; /* Just an unlikely error code */ - tloc = asn_GT2time(st, 0, 0); - if(tloc == -1 && errno != EPERM) { - ASN__CTFAIL(app_key, td, sptr, - "%s: Invalid time format: %s (%s:%d)", - td->name, strerror(errno), __FILE__, __LINE__); - return -1; - } - - return 0; -} - -time_t -asn_GT2time(const GeneralizedTime_t *st, struct tm *ret_tm, int as_gmt) { - return asn_GT2time_frac(st, 0, 0, ret_tm, as_gmt); -} - -time_t -asn_GT2time_prec(const GeneralizedTime_t *st, int *frac_value, int frac_digits, struct tm *ret_tm, int as_gmt) { - time_t tloc; - int fv, fd = 0; - - if(frac_value) - tloc = asn_GT2time_frac(st, &fv, &fd, ret_tm, as_gmt); - else - return asn_GT2time_frac(st, 0, 0, ret_tm, as_gmt); - if(fd == 0 || frac_digits <= 0) { - *frac_value = 0; - } else { - while(fd > frac_digits) - fv /= 10, fd--; - while(fd < frac_digits) { - if(fv < INT_MAX / 10) { - fv *= 10; - fd++; - } else { - /* Too long precision request */ - fv = 0; - break; - } - } - - *frac_value = fv; - } - - return tloc; -} - -time_t -asn_GT2time_frac(const GeneralizedTime_t *st, int *frac_value, int *frac_digits, struct tm *ret_tm, int as_gmt) { - struct tm tm_s; - uint8_t *buf; - uint8_t *end; - int gmtoff_h = 0; - int gmtoff_m = 0; - int gmtoff = 0; /* h + m */ - int offset_specified = 0; - int fvalue = 0; - int fdigits = 0; - time_t tloc; - - if(!st || !st->buf) { - errno = EINVAL; - return -1; - } else { - buf = st->buf; - end = buf + st->size; - } - - if(st->size < 10) { - errno = EINVAL; - return -1; - } - - /* - * Decode first 10 bytes: "AAAAMMJJhh" - */ - memset(&tm_s, 0, sizeof(tm_s)); -#undef B2F -#undef B2T -#define B2F(var) do { \ - unsigned ch = *buf; \ - if(ch < 0x30 || ch > 0x39) { \ - errno = EINVAL; \ - return -1; \ - } else { \ - var = var * 10 + (ch - 0x30); \ - buf++; \ - } \ - } while(0) -#define B2T(var) B2F(tm_s.var) - - B2T(tm_year); /* 1: A */ - B2T(tm_year); /* 2: A */ - B2T(tm_year); /* 3: A */ - B2T(tm_year); /* 4: A */ - B2T(tm_mon); /* 5: M */ - B2T(tm_mon); /* 6: M */ - B2T(tm_mday); /* 7: J */ - B2T(tm_mday); /* 8: J */ - B2T(tm_hour); /* 9: h */ - B2T(tm_hour); /* 0: h */ - - if(buf == end) goto local_finish; - - /* - * Parse [mm[ss[(.|,)ffff]]] - * ^^ - */ - switch(*buf) { - case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: - case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: - tm_s.tm_min = (*buf++) - 0x30; - if(buf == end) { errno = EINVAL; return -1; } - B2T(tm_min); - break; - case 0x2B: case 0x2D: /* +, - */ - goto offset; - case 0x5A: /* Z */ - goto utc_finish; - default: - errno = EINVAL; - return -1; - } - - if(buf == end) goto local_finish; - - /* - * Parse [mm[ss[(.|,)ffff]]] - * ^^ - */ - switch(*buf) { - case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: - case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: - tm_s.tm_sec = (*buf++) - 0x30; - if(buf == end) { errno = EINVAL; return -1; } - B2T(tm_sec); - break; - case 0x2B: case 0x2D: /* +, - */ - goto offset; - case 0x5A: /* Z */ - goto utc_finish; - default: - errno = EINVAL; - return -1; - } - - if(buf == end) goto local_finish; - - /* - * Parse [mm[ss[(.|,)ffff]]] - * ^ ^ - */ - switch(*buf) { - case 0x2C: case 0x2E: /* (.|,) */ - /* - * Process fractions of seconds. - */ - for(buf++; buf < end; buf++) { - int v = *buf; - /* GCC 4.x is being too smart without volatile */ - switch(v) { - case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: - case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: - if(fvalue < INT_MAX/10) { - fvalue = fvalue * 10 + (v - 0x30); - fdigits++; - } else { - /* Not enough precision, ignore */ - } - continue; - default: - break; - } - break; - } - } - - if(buf == end) goto local_finish; - - switch(*buf) { - case 0x2B: case 0x2D: /* +, - */ - goto offset; - case 0x5A: /* Z */ - goto utc_finish; - default: - errno = EINVAL; - return -1; - } - - -offset: - - if(end - buf < 3) { - errno = EINVAL; - return -1; - } - buf++; - B2F(gmtoff_h); - B2F(gmtoff_h); - if(buf[-3] == 0x2D) /* Negative */ - gmtoff = -1; - else - gmtoff = 1; - - if((end - buf) == 2) { - B2F(gmtoff_m); - B2F(gmtoff_m); - } else if(end != buf) { - errno = EINVAL; - return -1; - } - - gmtoff = gmtoff * (3600 * gmtoff_h + 60 * gmtoff_m); - - /* Fall through */ -utc_finish: - - offset_specified = 1; - - /* Fall through */ -local_finish: - - /* - * Validation. - */ - if((tm_s.tm_mon > 12 || tm_s.tm_mon < 1) - || (tm_s.tm_mday > 31 || tm_s.tm_mday < 1) - || (tm_s.tm_hour > 23) - || (tm_s.tm_sec > 60) - ) { - errno = EINVAL; - return -1; - } - - /* Canonicalize */ - tm_s.tm_mon -= 1; /* 0 - 11 */ - tm_s.tm_year -= 1900; - tm_s.tm_isdst = -1; - - tm_s.tm_sec -= gmtoff; - - /*** AT THIS POINT tm_s is either GMT or local (unknown) ****/ - - if(offset_specified) { - tloc = timegm(&tm_s); - } else { - /* - * Without an offset (or "Z"), - * we can only guess that it is a local zone. - * Interpret it in this fashion. - */ - tloc = mktime(&tm_s); - } - if(tloc == -1) { - errno = EINVAL; - return -1; - } - - if(ret_tm) { - if(as_gmt) { - if(offset_specified) { - *ret_tm = tm_s; - } else { - if(gmtime_r(&tloc, ret_tm) == 0) { - errno = EINVAL; - return -1; - } - } - } else { - if(localtime_r(&tloc, ret_tm) == 0) { - errno = EINVAL; - return -1; - } - } - } - - /* Fractions of seconds */ - if(frac_value) *frac_value = fvalue; - if(frac_digits) *frac_digits = fdigits; - - return tloc; -} - -GeneralizedTime_t * -asn_time2GT(GeneralizedTime_t *opt_gt, const struct tm *tm, int force_gmt) { - return asn_time2GT_frac(opt_gt, tm, 0, 0, force_gmt); -} - -GeneralizedTime_t * -asn_time2GT_frac(GeneralizedTime_t *opt_gt, const struct tm *tm, int frac_value, int frac_digits, int force_gmt) { - struct tm tm_s; - long gmtoff = 0; - const unsigned int buf_size = - 4 + 2 + 2 /* yyyymmdd */ - + 2 + 2 + 2 /* hhmmss */ - + 1 + 9 /* .fffffffff */ - + 1 + 4 /* +hhmm */ - + 1 /* '\0' */ - ; - char *buf = NULL; - char *p = NULL; - int size = 0; - - /* Check arguments */ - if(!tm) { - errno = EINVAL; - return 0; - } - - /* Pre-allocate a buffer of sufficient yet small length */ - buf = (char *)MALLOC(buf_size); - if(!buf) return 0; - - gmtoff = GMTOFF(*tm); - - if(force_gmt && gmtoff) { - tm_s = *tm; - tm_s.tm_sec -= gmtoff; - timegm(&tm_s); /* Fix the time */ - tm = &tm_s; -#ifdef HAVE_TM_GMTOFF - assert(!GMTOFF(tm_s)); /* Will fix itself */ -#else /* !HAVE_TM_GMTOFF */ - gmtoff = 0; -#endif - } - - size = snprintf(buf, buf_size, "%04d%02d%02d%02d%02d%02d", - tm->tm_year + 1900, - tm->tm_mon + 1, - tm->tm_mday, - tm->tm_hour, - tm->tm_min, - tm->tm_sec - ); - if(size != 14) { - /* Could be assert(size == 14); */ - FREEMEM(buf); - errno = EINVAL; - return 0; - } - - p = buf + size; - - /* - * Deal with fractions. - */ - if(frac_value > 0 && frac_digits > 0) { - char *end = p + 1 + 9; /* '.' + maximum 9 digits */ - char *z = p; - long fbase; - *z++ = '.'; - - /* Place bounds on precision */ - while(frac_digits-- > 9) - frac_value /= 10; - - /* emulate fbase = pow(10, frac_digits) */ - for(fbase = 1; frac_digits--;) - fbase *= 10; - - do { - int digit = frac_value / fbase; - if(digit > 9) { z = 0; break; } - *z++ = digit + 0x30; - frac_value %= fbase; - fbase /= 10; - } while(fbase > 0 && frac_value > 0 && z < end); - if(z) { - for(--z; *z == 0x30; --z); /* Strip zeroes */ - p = z + (*z != '.'); - size = p - buf; - } - } - - if(force_gmt) { - *p++ = 0x5a; /* "Z" */ - *p++ = 0; - size++; - } else { - int ret; - gmtoff %= 86400; - ret = snprintf(p, buf_size - size, "%+03ld%02ld", - gmtoff / 3600, labs(gmtoff % 3600) / 60); - if(ret != 5) { - FREEMEM(buf); - errno = EINVAL; - return 0; - } - size += ret; - } - - if(opt_gt) { - if(opt_gt->buf) - FREEMEM(opt_gt->buf); - } else { - opt_gt = (GeneralizedTime_t *)CALLOC(1, sizeof *opt_gt); - if(!opt_gt) { FREEMEM(buf); return 0; } - } - - opt_gt->buf = (unsigned char *)buf; - opt_gt->size = size; - - return opt_gt; -} - -int -GeneralizedTime_compare(const asn_TYPE_descriptor_t *td, const void *aptr, - const void *bptr) { - const GeneralizedTime_t *a = aptr; - const GeneralizedTime_t *b = bptr; - - (void)td; - - if(a && b) { - int afrac_value, afrac_digits; - int bfrac_value, bfrac_digits; - int aerr, berr; - time_t at, bt; - - errno = EPERM; - at = asn_GT2time_frac(a, &afrac_value, &afrac_digits, 0, 0); - aerr = errno; - errno = EPERM; - bt = asn_GT2time_frac(b, &bfrac_value, &bfrac_digits, 0, 0); - berr = errno; - - if(at == -1 && aerr != EPERM) { - if(bt == -1 && berr != EPERM) { - return OCTET_STRING_compare(td, aptr, bptr); - } else { - return -1; - } - } else if(bt == -1 && berr != EPERM) { - return 1; - } else { - /* Both values are valid. */ - } - - if(at < bt) { - return -1; - } else if(at > bt) { - return 1; - } else if(afrac_digits == bfrac_digits) { - if(afrac_value == bfrac_value) { - return 0; - } - if(afrac_value < bfrac_value) { - return -1; - } else { - return 1; - } - } else if(afrac_digits == 0) { - return -1; - } else if(bfrac_digits == 0) { - return 1; - } else { - double afrac = (double)afrac_value / afrac_digits; - double bfrac = (double)bfrac_value / bfrac_digits; - if(afrac < bfrac) { - return -1; - } else if(afrac > bfrac) { - return 1; - } else { - return 0; - } - } - } else if(!a && !b) { - return 0; - } else if(!a) { - return -1; - } else { - return 1; - } - -} diff --git a/asn1c_combined/j2735-asn-files/2024/overrides/NodeOffsetPointXY.h b/asn1c_combined/j2735-asn-files/2024/overrides/NodeOffsetPointXY.h deleted file mode 100644 index f0efe855..00000000 --- a/asn1c_combined/j2735-asn-files/2024/overrides/NodeOffsetPointXY.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) - * From ASN.1 module "Common" - * found in "asn/J2735-Common-2024-rel-v1.1.2.asn" - * `asn1c -fcompound-names -fincludes-quoted -pdu=all` - */ - -#ifndef _NodeOffsetPointXY_H_ -#define _NodeOffsetPointXY_H_ - - -#include "asn_application.h" - -/* Including external dependencies */ -#include "Node-XY-20b.h" -#include "Node-XY-22b.h" -#include "Node-XY-24b.h" -#include "Node-XY-26b.h" -#include "Node-XY-28b.h" -#include "Node-XY-32b.h" -#include "Node-LLmD-64b.h" - -/* HACK */ -/* Ref: https://github.com/usdot-fhwa-stol/usdot-asn1c/issues/1 */ -//#include "RegionalExtension.h" -#include "RegionId.h" -/* END HACK */ - -#include "constr_CHOICE.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* HACK */ -/* Forward declarations */ -struct Reg_NodeOffsetPointXY; -/* END HACK */ - -/* Dependencies */ -typedef enum NodeOffsetPointXY_PR { - NodeOffsetPointXY_PR_NOTHING, /* No components present */ - NodeOffsetPointXY_PR_node_XY1, - NodeOffsetPointXY_PR_node_XY2, - NodeOffsetPointXY_PR_node_XY3, - NodeOffsetPointXY_PR_node_XY4, - NodeOffsetPointXY_PR_node_XY5, - NodeOffsetPointXY_PR_node_XY6, - NodeOffsetPointXY_PR_node_LatLon, - NodeOffsetPointXY_PR_regional -} NodeOffsetPointXY_PR; - -/* HACK */ -typedef struct NodeOffsetPointXY__regional { - RegionId_t regionId; - - /* Note that this is a stub. There is no payload.. - It would not actually work as intended if the 'regional' - alternative were used in the CHOICE. */ - - /* Context for parsing across buffer boundaries */ - asn_struct_ctx_t _asn_ctx; -} NodeOffsetPointXY__regional_t; -/* END HACK */ - -/* NodeOffsetPointXY */ -typedef struct NodeOffsetPointXY { - NodeOffsetPointXY_PR present; - union NodeOffsetPointXY_u { - Node_XY_20b_t node_XY1; - Node_XY_22b_t node_XY2; - Node_XY_24b_t node_XY3; - Node_XY_26b_t node_XY4; - Node_XY_28b_t node_XY5; - Node_XY_32b_t node_XY6; - Node_LLmD_64b_t node_LatLon; - - /* HACK */ - //Reg_NodeOffsetPointXY_t regional; - NodeOffsetPointXY__regional_t regional; - /* END HACK */ - - } choice; - - /* Context for parsing across buffer boundaries */ - asn_struct_ctx_t _asn_ctx; -} NodeOffsetPointXY_t; - -/* Implementation */ -extern asn_TYPE_descriptor_t asn_DEF_NodeOffsetPointXY; -extern asn_CHOICE_specifics_t asn_SPC_NodeOffsetPointXY_specs_1; -extern asn_TYPE_member_t asn_MBR_NodeOffsetPointXY_1[8]; -extern asn_per_constraints_t asn_PER_type_NodeOffsetPointXY_constr_1; - -#ifdef __cplusplus -} -#endif - -/* HACK */ -#include "RegionalExtension.h" -/* END HACK*/ - -#endif /* _NodeOffsetPointXY_H_ */ -#include "asn_internal.h" diff --git a/asn1c_combined/j2735-asn-files/2024/overrides/VehicleEventFlags.c b/asn1c_combined/j2735-asn-files/2024/overrides/VehicleEventFlags.c deleted file mode 100644 index b033b602..00000000 --- a/asn1c_combined/j2735-asn-files/2024/overrides/VehicleEventFlags.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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 */ -}; - diff --git a/docs/Release_notes.md b/docs/Release_notes.md index d0b2f6ae..5f4026dc 100644 --- a/docs/Release_notes.md +++ b/docs/Release_notes.md @@ -1,6 +1,17 @@ asn1_codec Release Notes ---------------------------- +Version 3.1.0, released May 2025 +---------------------------------------- +### **Summary** +This release introduces an HTTP server to the asn1_codec module, enabling decoding of J2735 ASN.1 messages via a request-response interface. This enhancement adds batch decoding support for the Conflict Visualizer GUI (CVManager Intersection API), allowing it to process and display PCAP files without relying on embedded Kafka infrastructure. Additionally, it fixes the encoding for the eventJackKnife extension in the VehicleEventFlags BIT STRING, per the 2024 J2735 update. Instead of removing the extension as previously done, the generated C code was corrected to properly handle UPER encoding, with compatibility verified against multiple ASN.1 compilers. + +Enhancements in this release: +- [CDOT PR 41](https://github.com/CDOT-CV/asn1_codec/pull/41): Http server +- [CDOT PR 42](https://github.com/CDOT-CV/asn1_codec/pull/42): Fix VehicleEventFlags Jackknife Event Extension +- [CDOT PR 43](https://github.com/CDOT-CV/asn1_codec/pull/43): Set up CI with Azure Pipelines + + Version 3.0.0, released January 2025 ---------------------------------------- ### **Summary** diff --git a/fedora.repo b/fedora.repo index 372ff0e6..8aaf5f31 100644 --- a/fedora.repo +++ b/fedora.repo @@ -2,12 +2,12 @@ # Ref: https://repost.aws/questions/QUjUfu4DY4SjSRPeXLG_rQxg/how-to-install-asio-devel-glpk-devel-packages-on-amazon-linux-2023 name=Fedora 42 - x86_64 #metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-42&arch=x86_64 -baseurl=https://dl.fedoraproject.org/pub/fedora/linux/development/42/Everything/x86_64/os/ +baseurl=https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/x86_64/os/ enabled=0 countme=1 metadata_expire=7d repo_gpgcheck=0 type=rpm -gpgcheck=1 -gpgkey=https://getfedora.org/static/fedora.gpg +gpgcheck=0 +#gpgkey=https://getfedora.org/static/fedora.gpg skip_if_unavailable=False \ No newline at end of file diff --git a/include/acm.hpp b/include/acm.hpp index 5452a54b..7f827b50 100644 --- a/include/acm.hpp +++ b/include/acm.hpp @@ -311,8 +311,6 @@ class ASN1_Codec : public tool::Tool { bool bytes_to_hex_(buffer_structure_t* buf_struct, std::string& payload_hex ); // ASN.1 Compiler - //char errbuf[max_errbuf_size]; - // TODO: A byte flag word is needed here since we will set multiple decode / encoders. uint32_t opsflag; bool decode_1609dot2; diff --git a/usdot-asn1c b/usdot-asn1c index e74487cd..3f3311ec 160000 --- a/usdot-asn1c +++ b/usdot-asn1c @@ -1 +1 @@ -Subproject commit e74487cd9b585d19f2c15ece949f754e3733cb59 +Subproject commit 3f3311ece454bc51496c2481ce6f809271405c86