diff --git a/.github/instructions/python_development.instructions.md b/.github/instructions/python_development.instructions.md index 862e634..6eb9475 100644 --- a/.github/instructions/python_development.instructions.md +++ b/.github/instructions/python_development.instructions.md @@ -13,7 +13,7 @@ After creating or modifying any Python file, run these checks: 1. **Formatting**: `black tools/ --config tools/pyproject.toml` 2. **Style (ruff)**: `ruff check tools/ --fix --config tools/pyproject.toml` 3. **Type checking**: `python -m mypy tools/ --strict` -4. **Linting**: `python -m pylint tools/` +4. **Linting**: `python -m pylint tools/ --rcfile=tools/pyproject.toml` 5. **Style (flake8)**: `python -m flake8 tools/ --config tools/.flake8` 6. **Spelling**: `codespell tools/ --toml tools/pyproject.toml` 7. **Tests**: `python -m tools.run_tests` diff --git a/src/J2735_internal_DE_AllowedManeuvers.h b/src/J2735_internal_DE_AllowedManeuvers.h index ad6ff12..f854ca4 100644 --- a/src/J2735_internal_DE_AllowedManeuvers.h +++ b/src/J2735_internal_DE_AllowedManeuvers.h @@ -64,6 +64,9 @@ #include "J2735_internal_common.h" +_Static_assert(J2735_BW_ALLOWED_MANEUVERS <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -153,7 +156,7 @@ /* PUBLIC API: AllowedManeuvers Accessors */ /* ============================================================================================== */ /** - * @brief Check if AllowedManeuvers is in extended form. + * @brief Check if AllowedManeuvers has an extension. * * AllowedManeuvers is a fixed-size BIT STRING with 12 bits. * It does not have an extension marker, so this always returns 0 (false). @@ -161,7 +164,7 @@ * @param[in] buf Pointer to the start of the AllowedManeuvers UPER encoding (const uint8_t*). * @return Always 0 (false) - this type is not extensible. */ -#define J2735_ALLOWED_MANEUVERS_IS_EXTENDED(buf) ((void)(buf), 0) +#define J2735_ALLOWED_MANEUVERS_HAS_EXTENSION(buf) ((void)(buf), 0) /** * @brief Get wire size of AllowedManeuvers in bits. diff --git a/src/J2735_internal_DE_BrakeAppliedStatus.h b/src/J2735_internal_DE_BrakeAppliedStatus.h index ba76d99..3f84ed5 100644 --- a/src/J2735_internal_DE_BrakeAppliedStatus.h +++ b/src/J2735_internal_DE_BrakeAppliedStatus.h @@ -57,6 +57,9 @@ #include "J2735_internal_common.h" +_Static_assert(J2735_BW_BRAKE_APPLIED_STATUS <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -139,7 +142,7 @@ /* PUBLIC API: BrakeAppliedStatus Accessors */ /* ============================================================================================== */ /** - * @brief Check if BrakeAppliedStatus is in extended form. + * @brief Check if BrakeAppliedStatus has an extension. * * BrakeAppliedStatus is a fixed-size BIT STRING with 5 bits. * It does not have an extension marker, so this always returns 0 (false). @@ -147,7 +150,7 @@ * @param[in] buf Pointer to the start of the BrakeAppliedStatus UPER encoding (const uint8_t*). * @return Always 0 (false) - this type is not extensible. */ -#define J2735_BRAKE_APPLIED_STATUS_IS_EXTENDED(buf) ((void)(buf), 0) +#define J2735_BRAKE_APPLIED_STATUS_HAS_EXTENSION(buf) ((void)(buf), 0) /** * @brief Get wire size of BrakeAppliedStatus in bits. diff --git a/src/J2735_internal_DE_ExteriorLights.h b/src/J2735_internal_DE_ExteriorLights.h index 18084ed..83eeae3 100644 --- a/src/J2735_internal_DE_ExteriorLights.h +++ b/src/J2735_internal_DE_ExteriorLights.h @@ -81,7 +81,7 @@ * @internal * @brief Root size of ExteriorLights in bits. */ -#define J2735_INTERNAL_ROOT_SIZE_EXTERIOR_LIGHTS 9U +#define J2735_INTERNAL_ROOT_SIZE_BITS_EXTERIOR_LIGHTS 9U /** * @internal @@ -103,6 +103,9 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_EXTERIOR_LIGHTS == J2735_INTERNAL_EXT_SIZE_EXTERIOR_LIGHTS), "MAX_WIRE_BITS must equal ext_marker + nsnnwn + ext_size"); +_Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_EXTERIOR_LIGHTS <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -157,7 +160,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_EXTERIOR_LIGHTS == * * @param[in] raw17 Value previously returned by J2735_INTERNAL_RAW_READ_EXTERIOR_LIGHTS(). * @return Non-zero (true) if extended form, zero (false) if root form. - * @note Internal use only. Use J2735_EXTERIOR_LIGHTS_IS_EXTENDED() for public API. + * @note Internal use only. Use J2735_EXTERIOR_LIGHTS_HAS_EXTENSION() for public API. */ #define J2735_INTERNAL_IS_EXTENSION_EXTERIOR_LIGHTS(raw17) \ (((raw17) >> (J2735_INTERNAL_MAX_WIRE_BITS_EXTERIOR_LIGHTS - 1U)) != 0U) @@ -194,8 +197,8 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_EXTERIOR_LIGHTS == ((uint16_t)((raw17) & ((1ULL << J2735_INTERNAL_EXT_SIZE_EXTERIOR_LIGHTS) - 1ULL))) \ : /* Non-ext: bits 15..7 = 9 bits */ \ ((uint16_t)(((raw17) >> (J2735_INTERNAL_MAX_WIRE_BITS_EXTERIOR_LIGHTS - 1U - \ - J2735_INTERNAL_ROOT_SIZE_EXTERIOR_LIGHTS)) & \ - ((1ULL << J2735_INTERNAL_ROOT_SIZE_EXTERIOR_LIGHTS) - 1ULL)))) + J2735_INTERNAL_ROOT_SIZE_BITS_EXTERIOR_LIGHTS)) & \ + ((1ULL << J2735_INTERNAL_ROOT_SIZE_BITS_EXTERIOR_LIGHTS) - 1ULL)))) /** * @internal @@ -217,7 +220,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_EXTERIOR_LIGHTS == * constants. * @return 0 or 1 as uint8_t. * @warning For non-extended messages, bit_pos >= 9 reads undefined garbage bits. - * Caller should verify IS_EXTENDED before accessing extension-only flags. + * Caller should verify HAS_EXTENSION before accessing extension-only flags. * @note Internal use only. Use J2735_EXTERIOR_LIGHTS_GET_*() accessors for public API. */ #define J2735_INTERNAL_GET_ONE_EXTERIOR_LIGHTS(raw17, bit_pos) \ @@ -231,7 +234,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_EXTERIOR_LIGHTS == /* PUBLIC API: ExteriorLights Accessors */ /* ============================================================================================== */ /** - * @brief Check if ExteriorLights is in extended form. + * @brief Check if ExteriorLights has an extension. * * Extended form includes 9 flags (bits 0-8). * Root form has only 9 flags (bits 0-8). @@ -240,7 +243,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_EXTERIOR_LIGHTS == * @pre @p buf must point to valid ExteriorLights encoding with +7 byte padding. * @return Non-zero (true) if extended (9 flags), zero (false) if root (9 flags). */ -#define J2735_EXTERIOR_LIGHTS_IS_EXTENDED(buf) \ +#define J2735_EXTERIOR_LIGHTS_HAS_EXTENSION(buf) \ J2735_INTERNAL_IS_EXTENSION_EXTERIOR_LIGHTS(J2735_INTERNAL_RAW_READ_EXTERIOR_LIGHTS(buf)) /** @@ -255,7 +258,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_EXTERIOR_LIGHTS == #define J2735_EXTERIOR_LIGHTS_SIZE(buf) \ (J2735_INTERNAL_IS_EXTENSION_EXTERIOR_LIGHTS(J2735_INTERNAL_RAW_READ_EXTERIOR_LIGHTS(buf)) \ ? J2735_INTERNAL_MAX_WIRE_BITS_EXTERIOR_LIGHTS \ - : (J2735_INTERNAL_EXTENSION_MARKER_BITS + J2735_INTERNAL_ROOT_SIZE_EXTERIOR_LIGHTS)) + : (J2735_INTERNAL_EXTENSION_MARKER_BITS + J2735_INTERNAL_ROOT_SIZE_BITS_EXTERIOR_LIGHTS)) /** * @brief Get all ExteriorLights as a single uint16_t value. @@ -268,7 +271,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_EXTERIOR_LIGHTS == * @param[in] buf Pointer to the start of the ExteriorLights UPER encoding (const uint8_t*). * @pre @p buf must point to valid ExteriorLights encoding with +7 byte padding. * @return Right-aligned flag value (uint16_t). Bit 0 of result = first named bit. - * @note Use J2735_EXTERIOR_LIGHTS_IS_EXTENDED() to determine if bit 9 is meaningful. + * @note Use J2735_EXTERIOR_LIGHTS_HAS_EXTENSION() to determine if bit 9 is meaningful. */ #define J2735_EXTERIOR_LIGHTS_GET(buf) \ J2735_INTERNAL_GET_ALL_EXTERIOR_LIGHTS(J2735_INTERNAL_RAW_READ_EXTERIOR_LIGHTS(buf)) diff --git a/src/J2735_internal_DE_GNSSstatus.h b/src/J2735_internal_DE_GNSSstatus.h index b8d4e34..e9b096c 100644 --- a/src/J2735_internal_DE_GNSSstatus.h +++ b/src/J2735_internal_DE_GNSSstatus.h @@ -60,6 +60,9 @@ #include "J2735_internal_common.h" +_Static_assert(J2735_BW_GNSS_STATUS <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -144,7 +147,7 @@ /* PUBLIC API: GNSSstatus Accessors */ /* ============================================================================================== */ /** - * @brief Check if GNSSstatus is in extended form. + * @brief Check if GNSSstatus has an extension. * * GNSSstatus is a fixed-size BIT STRING with 8 bits. * It does not have an extension marker, so this always returns 0 (false). @@ -152,7 +155,7 @@ * @param[in] buf Pointer to the start of the GNSSstatus UPER encoding (const uint8_t*). * @return Always 0 (false) - this type is not extensible. */ -#define J2735_GNSS_STATUS_IS_EXTENDED(buf) ((void)(buf), 0) +#define J2735_GNSS_STATUS_HAS_EXTENSION(buf) ((void)(buf), 0) /** * @brief Get wire size of GNSSstatus in bits. diff --git a/src/J2735_internal_DE_LaneDirection.h b/src/J2735_internal_DE_LaneDirection.h index c9a9117..c69d091 100644 --- a/src/J2735_internal_DE_LaneDirection.h +++ b/src/J2735_internal_DE_LaneDirection.h @@ -54,6 +54,9 @@ #include "J2735_internal_common.h" +_Static_assert(J2735_BW_LANE_DIRECTION <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -133,7 +136,7 @@ /* PUBLIC API: LaneDirection Accessors */ /* ============================================================================================== */ /** - * @brief Check if LaneDirection is in extended form. + * @brief Check if LaneDirection has an extension. * * LaneDirection is a fixed-size BIT STRING with 2 bits. * It does not have an extension marker, so this always returns 0 (false). @@ -141,7 +144,7 @@ * @param[in] buf Pointer to the start of the LaneDirection UPER encoding (const uint8_t*). * @return Always 0 (false) - this type is not extensible. */ -#define J2735_LANE_DIRECTION_IS_EXTENDED(buf) ((void)(buf), 0) +#define J2735_LANE_DIRECTION_HAS_EXTENSION(buf) ((void)(buf), 0) /** * @brief Get wire size of LaneDirection in bits. diff --git a/src/J2735_internal_DE_LaneSharing.h b/src/J2735_internal_DE_LaneSharing.h index 3ce8511..8a5af99 100644 --- a/src/J2735_internal_DE_LaneSharing.h +++ b/src/J2735_internal_DE_LaneSharing.h @@ -62,6 +62,9 @@ #include "J2735_internal_common.h" +_Static_assert(J2735_BW_LANE_SHARING <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -148,7 +151,7 @@ /* PUBLIC API: LaneSharing Accessors */ /* ============================================================================================== */ /** - * @brief Check if LaneSharing is in extended form. + * @brief Check if LaneSharing has an extension. * * LaneSharing is a fixed-size BIT STRING with 10 bits. * It does not have an extension marker, so this always returns 0 (false). @@ -156,7 +159,7 @@ * @param[in] buf Pointer to the start of the LaneSharing UPER encoding (const uint8_t*). * @return Always 0 (false) - this type is not extensible. */ -#define J2735_LANE_SHARING_IS_EXTENDED(buf) ((void)(buf), 0) +#define J2735_LANE_SHARING_HAS_EXTENSION(buf) ((void)(buf), 0) /** * @brief Get wire size of LaneSharing in bits. diff --git a/src/J2735_internal_DE_PersonalAssistive.h b/src/J2735_internal_DE_PersonalAssistive.h index 9284d96..ebbfc5d 100644 --- a/src/J2735_internal_DE_PersonalAssistive.h +++ b/src/J2735_internal_DE_PersonalAssistive.h @@ -78,7 +78,7 @@ * @internal * @brief Root size of PersonalAssistive in bits. */ -#define J2735_INTERNAL_ROOT_SIZE_PERSONAL_ASSISTIVE 6U +#define J2735_INTERNAL_ROOT_SIZE_BITS_PERSONAL_ASSISTIVE 6U /** * @internal @@ -100,6 +100,9 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_ASSISTIVE == J2735_INTERNAL_EXT_SIZE_PERSONAL_ASSISTIVE), "MAX_WIRE_BITS must equal ext_marker + nsnnwn + ext_size"); +_Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_ASSISTIVE <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -151,7 +154,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_ASSISTIVE == * * @param[in] raw14 Value previously returned by J2735_INTERNAL_RAW_READ_PERSONAL_ASSISTIVE(). * @return Non-zero (true) if extended form, zero (false) if root form. - * @note Internal use only. Use J2735_PERSONAL_ASSISTIVE_IS_EXTENDED() for public API. + * @note Internal use only. Use J2735_PERSONAL_ASSISTIVE_HAS_EXTENSION() for public API. */ #define J2735_INTERNAL_IS_EXTENSION_PERSONAL_ASSISTIVE(raw14) \ (((raw14) >> (J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_ASSISTIVE - 1U)) != 0U) @@ -188,8 +191,8 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_ASSISTIVE == ((uint8_t)((raw14) & ((1ULL << J2735_INTERNAL_EXT_SIZE_PERSONAL_ASSISTIVE) - 1ULL))) \ : /* Non-ext: bits 12..7 = 6 bits */ \ ((uint8_t)(((raw14) >> (J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_ASSISTIVE - 1U - \ - J2735_INTERNAL_ROOT_SIZE_PERSONAL_ASSISTIVE)) & \ - ((1ULL << J2735_INTERNAL_ROOT_SIZE_PERSONAL_ASSISTIVE) - 1ULL)))) + J2735_INTERNAL_ROOT_SIZE_BITS_PERSONAL_ASSISTIVE)) & \ + ((1ULL << J2735_INTERNAL_ROOT_SIZE_BITS_PERSONAL_ASSISTIVE) - 1ULL)))) /** * @internal @@ -211,7 +214,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_ASSISTIVE == * constants. * @return 0 or 1 as uint8_t. * @warning For non-extended messages, bit_pos >= 6 reads undefined garbage bits. - * Caller should verify IS_EXTENDED before accessing extension-only flags. + * Caller should verify HAS_EXTENSION before accessing extension-only flags. * @note Internal use only. Use J2735_PERSONAL_ASSISTIVE_GET_*() accessors for public API. */ #define J2735_INTERNAL_GET_ONE_PERSONAL_ASSISTIVE(raw14, bit_pos) \ @@ -227,7 +230,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_ASSISTIVE == /* PUBLIC API: PersonalAssistive Accessors */ /* ============================================================================================== */ /** - * @brief Check if PersonalAssistive is in extended form. + * @brief Check if PersonalAssistive has an extension. * * Extended form includes 6 flags (bits 0-5). * Root form has only 6 flags (bits 0-5). @@ -236,7 +239,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_ASSISTIVE == * @pre @p buf must point to valid PersonalAssistive encoding with +7 byte padding. * @return Non-zero (true) if extended (6 flags), zero (false) if root (6 flags). */ -#define J2735_PERSONAL_ASSISTIVE_IS_EXTENDED(buf) \ +#define J2735_PERSONAL_ASSISTIVE_HAS_EXTENSION(buf) \ J2735_INTERNAL_IS_EXTENSION_PERSONAL_ASSISTIVE(J2735_INTERNAL_RAW_READ_PERSONAL_ASSISTIVE(buf)) /** @@ -251,7 +254,8 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_ASSISTIVE == #define J2735_PERSONAL_ASSISTIVE_SIZE(buf) \ (J2735_INTERNAL_IS_EXTENSION_PERSONAL_ASSISTIVE(J2735_INTERNAL_RAW_READ_PERSONAL_ASSISTIVE(buf)) \ ? J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_ASSISTIVE \ - : (J2735_INTERNAL_EXTENSION_MARKER_BITS + J2735_INTERNAL_ROOT_SIZE_PERSONAL_ASSISTIVE)) + : (J2735_INTERNAL_EXTENSION_MARKER_BITS + \ + J2735_INTERNAL_ROOT_SIZE_BITS_PERSONAL_ASSISTIVE)) /** * @brief Get all PersonalAssistive as a single uint8_t value. @@ -264,7 +268,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_ASSISTIVE == * @param[in] buf Pointer to the start of the PersonalAssistive UPER encoding (const uint8_t*). * @pre @p buf must point to valid PersonalAssistive encoding with +7 byte padding. * @return Right-aligned flag value (uint8_t). Bit 0 of result = first named bit. - * @note Use J2735_PERSONAL_ASSISTIVE_IS_EXTENDED() to determine if bit 6 is meaningful. + * @note Use J2735_PERSONAL_ASSISTIVE_HAS_EXTENSION() to determine if bit 6 is meaningful. */ #define J2735_PERSONAL_ASSISTIVE_GET(buf) \ J2735_INTERNAL_GET_ALL_PERSONAL_ASSISTIVE(J2735_INTERNAL_RAW_READ_PERSONAL_ASSISTIVE(buf)) diff --git a/src/J2735_internal_DE_PersonalDeviceUsageState.h b/src/J2735_internal_DE_PersonalDeviceUsageState.h index 77ea283..03e3cca 100644 --- a/src/J2735_internal_DE_PersonalDeviceUsageState.h +++ b/src/J2735_internal_DE_PersonalDeviceUsageState.h @@ -81,7 +81,7 @@ * @internal * @brief Root size of PersonalDeviceUsageState in bits. */ -#define J2735_INTERNAL_ROOT_SIZE_PERSONAL_DEVICE_USAGE_STATE 9U +#define J2735_INTERNAL_ROOT_SIZE_BITS_PERSONAL_DEVICE_USAGE_STATE 9U /** * @internal @@ -103,6 +103,9 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_DEVICE_USAGE_STATE == J2735_INTERNAL_EXT_SIZE_PERSONAL_DEVICE_USAGE_STATE), "MAX_WIRE_BITS must equal ext_marker + nsnnwn + ext_size"); +_Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_DEVICE_USAGE_STATE <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -158,7 +161,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_DEVICE_USAGE_STATE == * @param[in] raw17 Value previously returned by * J2735_INTERNAL_RAW_READ_PERSONAL_DEVICE_USAGE_STATE(). * @return Non-zero (true) if extended form, zero (false) if root form. - * @note Internal use only. Use J2735_PERSONAL_DEVICE_USAGE_STATE_IS_EXTENDED() for public API. + * @note Internal use only. Use J2735_PERSONAL_DEVICE_USAGE_STATE_HAS_EXTENSION() for public API. */ #define J2735_INTERNAL_IS_EXTENSION_PERSONAL_DEVICE_USAGE_STATE(raw17) \ (((raw17) >> (J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_DEVICE_USAGE_STATE - 1U)) != 0U) @@ -198,8 +201,8 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_DEVICE_USAGE_STATE == ((1ULL << J2735_INTERNAL_EXT_SIZE_PERSONAL_DEVICE_USAGE_STATE) - 1ULL))) \ : /* Non-ext: bits 15..7 = 9 bits */ \ ((uint16_t)(((raw17) >> (J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_DEVICE_USAGE_STATE - 1U - \ - J2735_INTERNAL_ROOT_SIZE_PERSONAL_DEVICE_USAGE_STATE)) & \ - ((1ULL << J2735_INTERNAL_ROOT_SIZE_PERSONAL_DEVICE_USAGE_STATE) - 1ULL)))) + J2735_INTERNAL_ROOT_SIZE_BITS_PERSONAL_DEVICE_USAGE_STATE)) & \ + ((1ULL << J2735_INTERNAL_ROOT_SIZE_BITS_PERSONAL_DEVICE_USAGE_STATE) - 1ULL)))) /** * @internal @@ -221,7 +224,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_DEVICE_USAGE_STATE == * constants. * @return 0 or 1 as uint8_t. * @warning For non-extended messages, bit_pos >= 9 reads undefined garbage bits. - * Caller should verify IS_EXTENDED before accessing extension-only flags. + * Caller should verify HAS_EXTENSION before accessing extension-only flags. * @note Internal use only. Use J2735_PERSONAL_DEVICE_USAGE_STATE_GET_*() accessors for public API. */ #define J2735_INTERNAL_GET_ONE_PERSONAL_DEVICE_USAGE_STATE(raw17, bit_pos) \ @@ -239,7 +242,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_DEVICE_USAGE_STATE == /* PUBLIC API: PersonalDeviceUsageState Accessors */ /* ============================================================================================== */ /** - * @brief Check if PersonalDeviceUsageState is in extended form. + * @brief Check if PersonalDeviceUsageState has an extension. * * Extended form includes 9 flags (bits 0-8). * Root form has only 9 flags (bits 0-8). @@ -249,7 +252,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_DEVICE_USAGE_STATE == * @pre @p buf must point to valid PersonalDeviceUsageState encoding with +7 byte padding. * @return Non-zero (true) if extended (9 flags), zero (false) if root (9 flags). */ -#define J2735_PERSONAL_DEVICE_USAGE_STATE_IS_EXTENDED(buf) \ +#define J2735_PERSONAL_DEVICE_USAGE_STATE_HAS_EXTENSION(buf) \ J2735_INTERNAL_IS_EXTENSION_PERSONAL_DEVICE_USAGE_STATE( \ J2735_INTERNAL_RAW_READ_PERSONAL_DEVICE_USAGE_STATE(buf)) @@ -268,7 +271,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_DEVICE_USAGE_STATE == J2735_INTERNAL_RAW_READ_PERSONAL_DEVICE_USAGE_STATE(buf)) \ ? J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_DEVICE_USAGE_STATE \ : (J2735_INTERNAL_EXTENSION_MARKER_BITS + \ - J2735_INTERNAL_ROOT_SIZE_PERSONAL_DEVICE_USAGE_STATE)) + J2735_INTERNAL_ROOT_SIZE_BITS_PERSONAL_DEVICE_USAGE_STATE)) /** * @brief Get all PersonalDeviceUsageState as a single uint16_t value. @@ -282,7 +285,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PERSONAL_DEVICE_USAGE_STATE == * uint8_t*). * @pre @p buf must point to valid PersonalDeviceUsageState encoding with +7 byte padding. * @return Right-aligned flag value (uint16_t). Bit 0 of result = first named bit. - * @note Use J2735_PERSONAL_DEVICE_USAGE_STATE_IS_EXTENDED() to determine if bit 9 is meaningful. + * @note Use J2735_PERSONAL_DEVICE_USAGE_STATE_HAS_EXTENSION() to determine if bit 9 is meaningful. */ #define J2735_PERSONAL_DEVICE_USAGE_STATE_GET(buf) \ J2735_INTERNAL_GET_ALL_PERSONAL_DEVICE_USAGE_STATE( \ diff --git a/src/J2735_internal_DE_PublicSafetyAndRoadWorkerActivity.h b/src/J2735_internal_DE_PublicSafetyAndRoadWorkerActivity.h index 16f7fa5..86273e8 100644 --- a/src/J2735_internal_DE_PublicSafetyAndRoadWorkerActivity.h +++ b/src/J2735_internal_DE_PublicSafetyAndRoadWorkerActivity.h @@ -78,7 +78,7 @@ * @internal * @brief Root size of PublicSafetyAndRoadWorkerActivity in bits. */ -#define J2735_INTERNAL_ROOT_SIZE_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY 6U +#define J2735_INTERNAL_ROOT_SIZE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY 6U /** * @internal @@ -100,6 +100,9 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVI J2735_INTERNAL_EXT_SIZE_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY), "MAX_WIRE_BITS must equal ext_marker + nsnnwn + ext_size"); +_Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -153,7 +156,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVI * @param[in] raw14 Value previously returned by * J2735_INTERNAL_RAW_READ_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY(). * @return Non-zero (true) if extended form, zero (false) if root form. - * @note Internal use only. Use J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_IS_EXTENDED() for + * @note Internal use only. Use J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_HAS_EXTENSION() for * public API. */ #define J2735_INTERNAL_IS_EXTENSION_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY(raw14) \ @@ -196,8 +199,9 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVI : /* Non-ext: bits 12..7 = 6 bits */ \ ((uint8_t)(((raw14) >> \ (J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY - 1U - \ - J2735_INTERNAL_ROOT_SIZE_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY)) & \ - ((1ULL << J2735_INTERNAL_ROOT_SIZE_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY) - \ + J2735_INTERNAL_ROOT_SIZE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY)) & \ + ((1ULL \ + << J2735_INTERNAL_ROOT_SIZE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY) - \ 1ULL)))) /** @@ -220,7 +224,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVI * J2735_INTERNAL_BIT_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_* constants. * @return 0 or 1 as uint8_t. * @warning For non-extended messages, bit_pos >= 6 reads undefined garbage bits. - * Caller should verify IS_EXTENDED before accessing extension-only flags. + * Caller should verify HAS_EXTENSION before accessing extension-only flags. * @note Internal use only. Use J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_GET_*() accessors for * public API. */ @@ -241,7 +245,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVI /* PUBLIC API: PublicSafetyAndRoadWorkerActivity Accessors */ /* ============================================================================================== */ /** - * @brief Check if PublicSafetyAndRoadWorkerActivity is in extended form. + * @brief Check if PublicSafetyAndRoadWorkerActivity has an extension. * * Extended form includes 6 flags (bits 0-5). * Root form has only 6 flags (bits 0-5). @@ -251,7 +255,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVI * @pre @p buf must point to valid PublicSafetyAndRoadWorkerActivity encoding with +7 byte padding. * @return Non-zero (true) if extended (6 flags), zero (false) if root (6 flags). */ -#define J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_IS_EXTENDED(buf) \ +#define J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_HAS_EXTENSION(buf) \ J2735_INTERNAL_IS_EXTENSION_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY( \ J2735_INTERNAL_RAW_READ_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY(buf)) @@ -270,7 +274,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVI J2735_INTERNAL_RAW_READ_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY(buf)) \ ? J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY \ : (J2735_INTERNAL_EXTENSION_MARKER_BITS + \ - J2735_INTERNAL_ROOT_SIZE_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY)) + J2735_INTERNAL_ROOT_SIZE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY)) /** * @brief Get all PublicSafetyAndRoadWorkerActivity as a single uint8_t value. @@ -284,7 +288,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVI * uint8_t*). * @pre @p buf must point to valid PublicSafetyAndRoadWorkerActivity encoding with +7 byte padding. * @return Right-aligned flag value (uint8_t). Bit 0 of result = first named bit. - * @note Use J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_IS_EXTENDED() to determine if bit 6 is + * @note Use J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_HAS_EXTENSION() to determine if bit 6 is * meaningful. */ #define J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_GET(buf) \ diff --git a/src/J2735_internal_DE_PublicSafetyDirectingTrafficSubType.h b/src/J2735_internal_DE_PublicSafetyDirectingTrafficSubType.h index a042cd3..38b18b6 100644 --- a/src/J2735_internal_DE_PublicSafetyDirectingTrafficSubType.h +++ b/src/J2735_internal_DE_PublicSafetyDirectingTrafficSubType.h @@ -79,7 +79,7 @@ * @internal * @brief Root size of PublicSafetyDirectingTrafficSubType in bits. */ -#define J2735_INTERNAL_ROOT_SIZE_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE 7U +#define J2735_INTERNAL_ROOT_SIZE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE 7U /** * @internal @@ -101,6 +101,9 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_ J2735_INTERNAL_EXT_SIZE_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE), "MAX_WIRE_BITS must equal ext_marker + nsnnwn + ext_size"); +_Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -158,7 +161,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_ * @param[in] raw15 Value previously returned by * J2735_INTERNAL_RAW_READ_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE(). * @return Non-zero (true) if extended form, zero (false) if root form. - * @note Internal use only. Use J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_IS_EXTENDED() for + * @note Internal use only. Use J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_HAS_EXTENSION() for * public API. */ #define J2735_INTERNAL_IS_EXTENSION_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE(raw15) \ @@ -201,8 +204,9 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_ : /* Non-ext: bits 13..7 = 7 bits */ \ ((uint8_t)(((raw15) >> \ (J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE - 1U - \ - J2735_INTERNAL_ROOT_SIZE_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE)) & \ - ((1ULL << J2735_INTERNAL_ROOT_SIZE_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE) - \ + J2735_INTERNAL_ROOT_SIZE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE)) & \ + ((1ULL \ + << J2735_INTERNAL_ROOT_SIZE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE) - \ 1ULL)))) /** @@ -225,7 +229,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_ * J2735_INTERNAL_BIT_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_* constants. * @return 0 or 1 as uint8_t. * @warning For non-extended messages, bit_pos >= 7 reads undefined garbage bits. - * Caller should verify IS_EXTENDED before accessing extension-only flags. + * Caller should verify HAS_EXTENSION before accessing extension-only flags. * @note Internal use only. Use J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_GET_*() accessors for * public API. */ @@ -246,7 +250,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_ /* PUBLIC API: PublicSafetyDirectingTrafficSubType Accessors */ /* ============================================================================================== */ /** - * @brief Check if PublicSafetyDirectingTrafficSubType is in extended form. + * @brief Check if PublicSafetyDirectingTrafficSubType has an extension. * * Extended form includes 7 flags (bits 0-6). * Root form has only 7 flags (bits 0-6). @@ -257,7 +261,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_ * padding. * @return Non-zero (true) if extended (7 flags), zero (false) if root (7 flags). */ -#define J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_IS_EXTENDED(buf) \ +#define J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_HAS_EXTENSION(buf) \ J2735_INTERNAL_IS_EXTENSION_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE( \ J2735_INTERNAL_RAW_READ_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE(buf)) @@ -277,7 +281,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_ J2735_INTERNAL_RAW_READ_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE(buf)) \ ? J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE \ : (J2735_INTERNAL_EXTENSION_MARKER_BITS + \ - J2735_INTERNAL_ROOT_SIZE_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE)) + J2735_INTERNAL_ROOT_SIZE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE)) /** * @brief Get all PublicSafetyDirectingTrafficSubType as a single uint8_t value. @@ -292,7 +296,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_ * @pre @p buf must point to valid PublicSafetyDirectingTrafficSubType encoding with +7 byte * padding. * @return Right-aligned flag value (uint8_t). Bit 0 of result = first named bit. - * @note Use J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_IS_EXTENDED() to determine if bit 7 is + * @note Use J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_HAS_EXTENSION() to determine if bit 7 is * meaningful. */ #define J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_GET(buf) \ diff --git a/src/J2735_internal_DE_TrafficLightOperationStatus.h b/src/J2735_internal_DE_TrafficLightOperationStatus.h index ffe0455..96be2e5 100644 --- a/src/J2735_internal_DE_TrafficLightOperationStatus.h +++ b/src/J2735_internal_DE_TrafficLightOperationStatus.h @@ -80,7 +80,7 @@ * @internal * @brief Root size of TrafficLightOperationStatus in bits. */ -#define J2735_INTERNAL_ROOT_SIZE_TRAFFIC_LIGHT_OPERATION_STATUS 8U +#define J2735_INTERNAL_ROOT_SIZE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS 8U /** * @internal @@ -102,6 +102,9 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS == J2735_INTERNAL_EXT_SIZE_TRAFFIC_LIGHT_OPERATION_STATUS), "MAX_WIRE_BITS must equal ext_marker + nsnnwn + ext_size"); +_Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -156,7 +159,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS == * @param[in] raw16 Value previously returned by * J2735_INTERNAL_RAW_READ_TRAFFIC_LIGHT_OPERATION_STATUS(). * @return Non-zero (true) if extended form, zero (false) if root form. - * @note Internal use only. Use J2735_TRAFFIC_LIGHT_OPERATION_STATUS_IS_EXTENDED() for public API. + * @note Internal use only. Use J2735_TRAFFIC_LIGHT_OPERATION_STATUS_HAS_EXTENSION() for public API. */ #define J2735_INTERNAL_IS_EXTENSION_TRAFFIC_LIGHT_OPERATION_STATUS(raw16) \ (((raw16) >> (J2735_INTERNAL_MAX_WIRE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS - 1U)) != 0U) @@ -196,8 +199,9 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS == ((1ULL << J2735_INTERNAL_EXT_SIZE_TRAFFIC_LIGHT_OPERATION_STATUS) - 1ULL))) \ : /* Non-ext: bits 14..7 = 8 bits */ \ ((uint8_t)(((raw16) >> (J2735_INTERNAL_MAX_WIRE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS - 1U - \ - J2735_INTERNAL_ROOT_SIZE_TRAFFIC_LIGHT_OPERATION_STATUS)) & \ - ((1ULL << J2735_INTERNAL_ROOT_SIZE_TRAFFIC_LIGHT_OPERATION_STATUS) - 1ULL)))) + J2735_INTERNAL_ROOT_SIZE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS)) & \ + ((1ULL << J2735_INTERNAL_ROOT_SIZE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS) - \ + 1ULL)))) /** * @internal @@ -219,7 +223,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS == * J2735_INTERNAL_BIT_TRAFFIC_LIGHT_OPERATION_STATUS_* constants. * @return 0 or 1 as uint8_t. * @warning For non-extended messages, bit_pos >= 8 reads undefined garbage bits. - * Caller should verify IS_EXTENDED before accessing extension-only flags. + * Caller should verify HAS_EXTENSION before accessing extension-only flags. * @note Internal use only. Use J2735_TRAFFIC_LIGHT_OPERATION_STATUS_GET_*() accessors for public * API. */ @@ -239,7 +243,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS == /* PUBLIC API: TrafficLightOperationStatus Accessors */ /* ============================================================================================== */ /** - * @brief Check if TrafficLightOperationStatus is in extended form. + * @brief Check if TrafficLightOperationStatus has an extension. * * Extended form includes 8 flags (bits 0-7). * Root form has only 8 flags (bits 0-7). @@ -249,7 +253,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS == * @pre @p buf must point to valid TrafficLightOperationStatus encoding with +7 byte padding. * @return Non-zero (true) if extended (8 flags), zero (false) if root (8 flags). */ -#define J2735_TRAFFIC_LIGHT_OPERATION_STATUS_IS_EXTENDED(buf) \ +#define J2735_TRAFFIC_LIGHT_OPERATION_STATUS_HAS_EXTENSION(buf) \ J2735_INTERNAL_IS_EXTENSION_TRAFFIC_LIGHT_OPERATION_STATUS( \ J2735_INTERNAL_RAW_READ_TRAFFIC_LIGHT_OPERATION_STATUS(buf)) @@ -268,7 +272,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS == J2735_INTERNAL_RAW_READ_TRAFFIC_LIGHT_OPERATION_STATUS(buf)) \ ? J2735_INTERNAL_MAX_WIRE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS \ : (J2735_INTERNAL_EXTENSION_MARKER_BITS + \ - J2735_INTERNAL_ROOT_SIZE_TRAFFIC_LIGHT_OPERATION_STATUS)) + J2735_INTERNAL_ROOT_SIZE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS)) /** * @brief Get all TrafficLightOperationStatus as a single uint8_t value. @@ -282,7 +286,8 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_TRAFFIC_LIGHT_OPERATION_STATUS == * uint8_t*). * @pre @p buf must point to valid TrafficLightOperationStatus encoding with +7 byte padding. * @return Right-aligned flag value (uint8_t). Bit 0 of result = first named bit. - * @note Use J2735_TRAFFIC_LIGHT_OPERATION_STATUS_IS_EXTENDED() to determine if bit 8 is meaningful. + * @note Use J2735_TRAFFIC_LIGHT_OPERATION_STATUS_HAS_EXTENSION() to determine if bit 8 is + * meaningful. */ #define J2735_TRAFFIC_LIGHT_OPERATION_STATUS_GET(buf) \ J2735_INTERNAL_GET_ALL_TRAFFIC_LIGHT_OPERATION_STATUS( \ diff --git a/src/J2735_internal_DE_TransitStatus.h b/src/J2735_internal_DE_TransitStatus.h index 681532b..843069f 100644 --- a/src/J2735_internal_DE_TransitStatus.h +++ b/src/J2735_internal_DE_TransitStatus.h @@ -58,6 +58,9 @@ #include "J2735_internal_common.h" +_Static_assert(J2735_BW_TRANSIT_STATUS <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -141,7 +144,7 @@ /* PUBLIC API: TransitStatus Accessors */ /* ============================================================================================== */ /** - * @brief Check if TransitStatus is in extended form. + * @brief Check if TransitStatus has an extension. * * TransitStatus is a fixed-size BIT STRING with 6 bits. * It does not have an extension marker, so this always returns 0 (false). @@ -149,7 +152,7 @@ * @param[in] buf Pointer to the start of the TransitStatus UPER encoding (const uint8_t*). * @return Always 0 (false) - this type is not extensible. */ -#define J2735_TRANSIT_STATUS_IS_EXTENDED(buf) ((void)(buf), 0) +#define J2735_TRANSIT_STATUS_HAS_EXTENSION(buf) ((void)(buf), 0) /** * @brief Get wire size of TransitStatus in bits. diff --git a/src/J2735_internal_DE_UserSizeAndBehaviour.h b/src/J2735_internal_DE_UserSizeAndBehaviour.h index eb2bd2e..e94248a 100644 --- a/src/J2735_internal_DE_UserSizeAndBehaviour.h +++ b/src/J2735_internal_DE_UserSizeAndBehaviour.h @@ -77,7 +77,7 @@ * @internal * @brief Root size of UserSizeAndBehaviour in bits. */ -#define J2735_INTERNAL_ROOT_SIZE_USER_SIZE_AND_BEHAVIOUR 5U +#define J2735_INTERNAL_ROOT_SIZE_BITS_USER_SIZE_AND_BEHAVIOUR 5U /** * @internal @@ -99,6 +99,9 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_USER_SIZE_AND_BEHAVIOUR == J2735_INTERNAL_EXT_SIZE_USER_SIZE_AND_BEHAVIOUR), "MAX_WIRE_BITS must equal ext_marker + nsnnwn + ext_size"); +_Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_USER_SIZE_AND_BEHAVIOUR <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -149,7 +152,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_USER_SIZE_AND_BEHAVIOUR == * * @param[in] raw13 Value previously returned by J2735_INTERNAL_RAW_READ_USER_SIZE_AND_BEHAVIOUR(). * @return Non-zero (true) if extended form, zero (false) if root form. - * @note Internal use only. Use J2735_USER_SIZE_AND_BEHAVIOUR_IS_EXTENDED() for public API. + * @note Internal use only. Use J2735_USER_SIZE_AND_BEHAVIOUR_HAS_EXTENSION() for public API. */ #define J2735_INTERNAL_IS_EXTENSION_USER_SIZE_AND_BEHAVIOUR(raw13) \ (((raw13) >> (J2735_INTERNAL_MAX_WIRE_BITS_USER_SIZE_AND_BEHAVIOUR - 1U)) != 0U) @@ -186,8 +189,8 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_USER_SIZE_AND_BEHAVIOUR == ((uint8_t)((raw13) & ((1ULL << J2735_INTERNAL_EXT_SIZE_USER_SIZE_AND_BEHAVIOUR) - 1ULL))) \ : /* Non-ext: bits 11..7 = 5 bits */ \ ((uint8_t)(((raw13) >> (J2735_INTERNAL_MAX_WIRE_BITS_USER_SIZE_AND_BEHAVIOUR - 1U - \ - J2735_INTERNAL_ROOT_SIZE_USER_SIZE_AND_BEHAVIOUR)) & \ - ((1ULL << J2735_INTERNAL_ROOT_SIZE_USER_SIZE_AND_BEHAVIOUR) - 1ULL)))) + J2735_INTERNAL_ROOT_SIZE_BITS_USER_SIZE_AND_BEHAVIOUR)) & \ + ((1ULL << J2735_INTERNAL_ROOT_SIZE_BITS_USER_SIZE_AND_BEHAVIOUR) - 1ULL)))) /** * @internal @@ -209,7 +212,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_USER_SIZE_AND_BEHAVIOUR == * constants. * @return 0 or 1 as uint8_t. * @warning For non-extended messages, bit_pos >= 5 reads undefined garbage bits. - * Caller should verify IS_EXTENDED before accessing extension-only flags. + * Caller should verify HAS_EXTENSION before accessing extension-only flags. * @note Internal use only. Use J2735_USER_SIZE_AND_BEHAVIOUR_GET_*() accessors for public API. */ #define J2735_INTERNAL_GET_ONE_USER_SIZE_AND_BEHAVIOUR(raw13, bit_pos) \ @@ -227,7 +230,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_USER_SIZE_AND_BEHAVIOUR == /* PUBLIC API: UserSizeAndBehaviour Accessors */ /* ============================================================================================== */ /** - * @brief Check if UserSizeAndBehaviour is in extended form. + * @brief Check if UserSizeAndBehaviour has an extension. * * Extended form includes 5 flags (bits 0-4). * Root form has only 5 flags (bits 0-4). @@ -236,7 +239,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_USER_SIZE_AND_BEHAVIOUR == * @pre @p buf must point to valid UserSizeAndBehaviour encoding with +7 byte padding. * @return Non-zero (true) if extended (5 flags), zero (false) if root (5 flags). */ -#define J2735_USER_SIZE_AND_BEHAVIOUR_IS_EXTENDED(buf) \ +#define J2735_USER_SIZE_AND_BEHAVIOUR_HAS_EXTENSION(buf) \ J2735_INTERNAL_IS_EXTENSION_USER_SIZE_AND_BEHAVIOUR( \ J2735_INTERNAL_RAW_READ_USER_SIZE_AND_BEHAVIOUR(buf)) @@ -254,7 +257,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_USER_SIZE_AND_BEHAVIOUR == J2735_INTERNAL_RAW_READ_USER_SIZE_AND_BEHAVIOUR(buf)) \ ? J2735_INTERNAL_MAX_WIRE_BITS_USER_SIZE_AND_BEHAVIOUR \ : (J2735_INTERNAL_EXTENSION_MARKER_BITS + \ - J2735_INTERNAL_ROOT_SIZE_USER_SIZE_AND_BEHAVIOUR)) + J2735_INTERNAL_ROOT_SIZE_BITS_USER_SIZE_AND_BEHAVIOUR)) /** * @brief Get all UserSizeAndBehaviour as a single uint8_t value. @@ -267,7 +270,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_USER_SIZE_AND_BEHAVIOUR == * @param[in] buf Pointer to the start of the UserSizeAndBehaviour UPER encoding (const uint8_t*). * @pre @p buf must point to valid UserSizeAndBehaviour encoding with +7 byte padding. * @return Right-aligned flag value (uint8_t). Bit 0 of result = first named bit. - * @note Use J2735_USER_SIZE_AND_BEHAVIOUR_IS_EXTENDED() to determine if bit 5 is meaningful. + * @note Use J2735_USER_SIZE_AND_BEHAVIOUR_HAS_EXTENSION() to determine if bit 5 is meaningful. */ #define J2735_USER_SIZE_AND_BEHAVIOUR_GET(buf) \ J2735_INTERNAL_GET_ALL_USER_SIZE_AND_BEHAVIOUR( \ diff --git a/src/J2735_internal_DE_VehicleEventFlags.h b/src/J2735_internal_DE_VehicleEventFlags.h index 68717b4..27a1376 100644 --- a/src/J2735_internal_DE_VehicleEventFlags.h +++ b/src/J2735_internal_DE_VehicleEventFlags.h @@ -86,7 +86,7 @@ * @internal * @brief Root size of VehicleEventFlags in bits. */ -#define J2735_INTERNAL_ROOT_SIZE_VEHICLE_EVENT_FLAGS 13U +#define J2735_INTERNAL_ROOT_SIZE_BITS_VEHICLE_EVENT_FLAGS 13U /** * @internal @@ -108,6 +108,9 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_VEHICLE_EVENT_FLAGS == J2735_INTERNAL_EXT_SIZE_VEHICLE_EVENT_FLAGS), "MAX_WIRE_BITS must equal ext_marker + nsnnwn + ext_size"); +_Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_VEHICLE_EVENT_FLAGS <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -167,7 +170,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_VEHICLE_EVENT_FLAGS == * * @param[in] raw22 Value previously returned by J2735_INTERNAL_RAW_READ_VEHICLE_EVENT_FLAGS(). * @return Non-zero (true) if extended form, zero (false) if root form. - * @note Internal use only. Use J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED() for public API. + * @note Internal use only. Use J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION() for public API. */ #define J2735_INTERNAL_IS_EXTENSION_VEHICLE_EVENT_FLAGS(raw22) \ (((raw22) >> (J2735_INTERNAL_MAX_WIRE_BITS_VEHICLE_EVENT_FLAGS - 1U)) != 0U) @@ -204,8 +207,8 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_VEHICLE_EVENT_FLAGS == ((uint16_t)((raw22) & ((1ULL << J2735_INTERNAL_EXT_SIZE_VEHICLE_EVENT_FLAGS) - 1ULL))) \ : /* Non-ext: bits 20..8 = 13 bits */ \ ((uint16_t)(((raw22) >> (J2735_INTERNAL_MAX_WIRE_BITS_VEHICLE_EVENT_FLAGS - 1U - \ - J2735_INTERNAL_ROOT_SIZE_VEHICLE_EVENT_FLAGS)) & \ - ((1ULL << J2735_INTERNAL_ROOT_SIZE_VEHICLE_EVENT_FLAGS) - 1ULL)))) + J2735_INTERNAL_ROOT_SIZE_BITS_VEHICLE_EVENT_FLAGS)) & \ + ((1ULL << J2735_INTERNAL_ROOT_SIZE_BITS_VEHICLE_EVENT_FLAGS) - 1ULL)))) /** * @internal @@ -227,7 +230,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_VEHICLE_EVENT_FLAGS == * constants. * @return 0 or 1 as uint8_t. * @warning For non-extended messages, bit_pos >= 13 reads undefined garbage bits. - * Caller should verify IS_EXTENDED before accessing extension-only flags. + * Caller should verify HAS_EXTENSION before accessing extension-only flags. * @note Internal use only. Use J2735_VEHICLE_EVENT_FLAGS_GET_*() accessors for public API. */ #define J2735_INTERNAL_GET_ONE_VEHICLE_EVENT_FLAGS(raw22, bit_pos) \ @@ -243,7 +246,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_VEHICLE_EVENT_FLAGS == /* PUBLIC API: VehicleEventFlags Accessors */ /* ============================================================================================== */ /** - * @brief Check if VehicleEventFlags is in extended form. + * @brief Check if VehicleEventFlags has an extension. * * Extended form includes 14 flags (bits 0-13). * Root form has only 13 flags (bits 0-12). @@ -252,7 +255,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_VEHICLE_EVENT_FLAGS == * @pre @p buf must point to valid VehicleEventFlags encoding with +7 byte padding. * @return Non-zero (true) if extended (14 flags), zero (false) if root (13 flags). */ -#define J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED(buf) \ +#define J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION(buf) \ J2735_INTERNAL_IS_EXTENSION_VEHICLE_EVENT_FLAGS(J2735_INTERNAL_RAW_READ_VEHICLE_EVENT_FLAGS(buf)) /** @@ -268,7 +271,8 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_VEHICLE_EVENT_FLAGS == (J2735_INTERNAL_IS_EXTENSION_VEHICLE_EVENT_FLAGS( \ J2735_INTERNAL_RAW_READ_VEHICLE_EVENT_FLAGS(buf)) \ ? J2735_INTERNAL_MAX_WIRE_BITS_VEHICLE_EVENT_FLAGS \ - : (J2735_INTERNAL_EXTENSION_MARKER_BITS + J2735_INTERNAL_ROOT_SIZE_VEHICLE_EVENT_FLAGS)) + : (J2735_INTERNAL_EXTENSION_MARKER_BITS + \ + J2735_INTERNAL_ROOT_SIZE_BITS_VEHICLE_EVENT_FLAGS)) /** * @brief Get all VehicleEventFlags as a single uint16_t value. @@ -281,7 +285,7 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_VEHICLE_EVENT_FLAGS == * @param[in] buf Pointer to the start of the VehicleEventFlags UPER encoding (const uint8_t*). * @pre @p buf must point to valid VehicleEventFlags encoding with +7 byte padding. * @return Right-aligned flag value (uint16_t). Bit 0 of result = first named bit. - * @note Use J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED() to determine if bit 13 is meaningful. + * @note Use J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION() to determine if bit 13 is meaningful. */ #define J2735_VEHICLE_EVENT_FLAGS_GET(buf) \ J2735_INTERNAL_GET_ALL_VEHICLE_EVENT_FLAGS(J2735_INTERNAL_RAW_READ_VEHICLE_EVENT_FLAGS(buf)) @@ -436,9 +440,9 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_VEHICLE_EVENT_FLAGS == * * @param[in] buf Pointer to VehicleEventFlags UPER encoding (const uint8_t*). * @pre @p buf must point to valid encoding with +7 byte padding. - * @pre Caller should verify J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED(buf) returns true. + * @pre Caller should verify J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION(buf) returns true. * @return 0 or 1. - * @warning Returns garbage (0 or 1) for non-extended messages. Always check IS_EXTENDED first. + * @warning Returns garbage (0 or 1) for non-extended messages. Always check HAS_EXTENSION first. */ #define J2735_VEHICLE_EVENT_FLAGS_GET_EVENT_JACK_KNIFE(buf) \ J2735_INTERNAL_GET_ONE_VEHICLE_EVENT_FLAGS( \ diff --git a/src/J2735_internal_DE_VerticalAccelerationThreshold.h b/src/J2735_internal_DE_VerticalAccelerationThreshold.h index 33d7db5..a0d2c0c 100644 --- a/src/J2735_internal_DE_VerticalAccelerationThreshold.h +++ b/src/J2735_internal_DE_VerticalAccelerationThreshold.h @@ -57,6 +57,9 @@ #include "J2735_internal_common.h" +_Static_assert(J2735_BW_VERTICAL_ACCELERATION_THRESHOLD <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); + /* ============================================================================================== */ /* INTERNAL: Bit Position Constants */ /* */ @@ -143,7 +146,7 @@ /* PUBLIC API: VerticalAccelerationThreshold Accessors */ /* ============================================================================================== */ /** - * @brief Check if VerticalAccelerationThreshold is in extended form. + * @brief Check if VerticalAccelerationThreshold has an extension. * * VerticalAccelerationThreshold is a fixed-size BIT STRING with 5 bits. * It does not have an extension marker, so this always returns 0 (false). @@ -152,7 +155,7 @@ * uint8_t*). * @return Always 0 (false) - this type is not extensible. */ -#define J2735_VERTICAL_ACCELERATION_THRESHOLD_IS_EXTENDED(buf) ((void)(buf), 0) +#define J2735_VERTICAL_ACCELERATION_THRESHOLD_HAS_EXTENSION(buf) ((void)(buf), 0) /** * @brief Get wire size of VerticalAccelerationThreshold in bits. diff --git a/src/J2735_internal_DF_BSMcoreData.h b/src/J2735_internal_DF_BSMcoreData.h index dd18e4a..4ded4b7 100644 --- a/src/J2735_internal_DF_BSMcoreData.h +++ b/src/J2735_internal_DF_BSMcoreData.h @@ -112,7 +112,7 @@ * @brief Bit offset of field 'lat' within BSMcoreData. */ #define J2735_INTERNAL_OFF_BSM_CORE_DATA_LAT(buf) \ - (J2735_INTERNAL_OFF_BSM_CORE_DATA_SEC_MARK(buf) + J2735_BW_DS_ECOND) /* 55 */ + (J2735_INTERNAL_OFF_BSM_CORE_DATA_SEC_MARK(buf) + J2735_BW_D_SECOND) /* 55 */ /** * @internal @@ -216,7 +216,7 @@ _Static_assert((J2735_INTERNAL_OFF_BSM_CORE_DATA_SIZE(0) + J2735_BW_VEHICLE_SIZE */ #define J2735_BSM_CORE_DATA_GET_SEC_MARK(buf) \ ((uint16_t)J2735_READ_BITS((buf), J2735_INTERNAL_OFF_BSM_CORE_DATA_SEC_MARK(buf), \ - J2735_BW_DS_ECOND)) + J2735_BW_D_SECOND)) /** * @brief Get 'lat' (Latitude, signed 31 bits). diff --git a/src/J2735_internal_constants.h b/src/J2735_internal_constants.h index a5356ae..6dc80b4 100644 --- a/src/J2735_internal_constants.h +++ b/src/J2735_internal_constants.h @@ -182,7 +182,6 @@ _Static_assert(J2735_INTERNAL_NSNNWN_SMALL_BITS == /* Required for O(1) bit-stream navigation. */ /* Constraint: All bit-widths must satisfy 1 <= width <= 56 for use with J2735_READ_BITS. */ /* ============================================================================================== */ -#define J2735_BW_64_B 63U /* 64b: SEQUENCE (2 fields) */ #define J2735_BW_ACCEL_STEER_YAW_RATE_CONFIDENCE \ 8U /* AccelSteerYawRateConfidence: SEQUENCE (3 fields) */ #define J2735_BW_ACCELERATION 12U /* Acceleration: INTEGER (-2000..2001) */ @@ -196,6 +195,7 @@ _Static_assert(J2735_INTERNAL_NSNNWN_SMALL_BITS == #define J2735_BW_ANGLE 15U /* Angle: INTEGER (0..28800) */ #define J2735_BW_ANIMAL_PROPELLED_TYPE 2U /* AnimalPropelledType: ENUMERATED (4 values) */ #define J2735_BW_ANIMAL_TYPE 2U /* AnimalType: ENUMERATED (4 values) */ +#define J2735_BW_ANTENNA_OFFSET_SET 31U /* AntennaOffsetSet: SEQUENCE (3 fields) */ #define J2735_BW_ANTI_LOCK_BRAKE_STATUS 2U /* AntiLockBrakeStatus: ENUMERATED (4 values) */ #define J2735_BW_APPROACH_ID 4U /* ApproachID: INTEGER (0..15) */ #define J2735_BW_APPROACH_OR_LANE 1U /* ApproachOrLane: CHOICE (2 alternatives) */ @@ -223,22 +223,21 @@ _Static_assert(J2735_INTERNAL_NSNNWN_SMALL_BITS == #define J2735_BW_CONFIDENCE 8U /* Confidence: INTEGER (0..200) */ #define J2735_BW_CONSECUTIVE_TRAFFIC_LIGHT 2U /* ConsecutiveTrafficLight: ENUMERATED (3 values) */ #define J2735_BW_COUNT 6U /* Count: INTEGER (0..32) */ -#define J2735_BW_DD_ATE 21U /* DDate: SEQUENCE (3 fields) */ -#define J2735_BW_DD_AY 5U /* DDay: INTEGER (0..31) */ -#define J2735_BW_DF_ULL_TIME 32U /* DFullTime: SEQUENCE (5 fields) */ -#define J2735_BW_DH_OUR 5U /* DHour: INTEGER (0..31) */ -#define J2735_BW_DM_INUTE 6U /* DMinute: INTEGER (0..60) */ -#define J2735_BW_DM_ONTH 4U /* DMonth: INTEGER (0..12) */ -#define J2735_BW_DM_ONTH_DAY 9U /* DMonthDay: SEQUENCE (2 fields) */ -#define J2735_BW_DO_FFSET 11U /* DOffset: INTEGER (-840..840) */ +#define J2735_BW_D_DATE 21U /* DDate: SEQUENCE (3 fields) */ +#define J2735_BW_D_DAY 5U /* DDay: INTEGER (0..31) */ +#define J2735_BW_D_FULL_TIME 32U /* DFullTime: SEQUENCE (5 fields) */ +#define J2735_BW_D_HOUR 5U /* DHour: INTEGER (0..31) */ +#define J2735_BW_D_MINUTE 6U /* DMinute: INTEGER (0..60) */ +#define J2735_BW_D_MONTH 4U /* DMonth: INTEGER (0..12) */ +#define J2735_BW_D_MONTH_DAY 9U /* DMonthDay: SEQUENCE (2 fields) */ +#define J2735_BW_D_OFFSET 11U /* DOffset: INTEGER (-840..840) */ #define J2735_BW_DSRC_MSG_ID 15U /* DSRCmsgID: INTEGER (0..32767) */ -#define J2735_BW_DS_ECOND 16U /* DSecond: INTEGER (0..65535) */ -#define J2735_BW_DY_EAR 12U /* DYear: INTEGER (0..4095) */ -#define J2735_BW_DY_EAR_MONTH 16U /* DYearMonth: SEQUENCE (2 fields) */ +#define J2735_BW_D_SECOND 16U /* DSecond: INTEGER (0..65535) */ +#define J2735_BW_D_YEAR 12U /* DYear: INTEGER (0..4095) */ +#define J2735_BW_D_YEAR_MONTH 16U /* DYearMonth: SEQUENCE (2 fields) */ #define J2735_BW_DELTA_ANGLE 9U /* DeltaAngle: INTEGER (-150..150) */ #define J2735_BW_DELTA_TIME 8U /* DeltaTime: INTEGER (-122..121) */ #define J2735_BW_DIRECTION_OF_USE 2U /* DirectionOfUse: ENUMERATED (4 values) */ -#define J2735_BW_DISTANCE_UNITS 3U /* DistanceUnits: ENUMERATED (8 values) */ #define J2735_BW_DRIVE_AXLE_LIFT_AIR_PRESSURE \ 10U /* DriveAxleLiftAirPressure: INTEGER (0..1000) \ */ @@ -252,7 +251,6 @@ _Static_assert(J2735_INTERNAL_NSNNWN_SMALL_BITS == #define J2735_BW_ELEVATION 16U /* Elevation: INTEGER (-4096..61439) */ #define J2735_BW_ELEVATION_CONFIDENCE 3U /* ElevationConfidence: ENUMERATED (8 values) */ #define J2735_BW_EXTENT 4U /* Extent: ENUMERATED (16 values) */ -#define J2735_BW_EXTERIOR_LIGHTS 9U /* ExteriorLights: BIT STRING (SIZE(9)) */ #define J2735_BW_FUEL_TYPE 4U /* FuelType: INTEGER (0..15) */ #define J2735_BW_FURTHER_INFO_ID 16U /* FurtherInfoID: OCTET STRING (SIZE(2)) */ #define J2735_BW_GNSS_STATUS 8U /* GNSSstatus: BIT STRING (SIZE(8)) */ @@ -264,13 +262,10 @@ _Static_assert(J2735_INTERNAL_NSNNWN_SMALL_BITS == #define J2735_BW_GROSS_SPEED 5U /* GrossSpeed: INTEGER (0..31) */ #define J2735_BW_HEADING 15U /* Heading: INTEGER (0..28800) */ #define J2735_BW_HEADING_CONFIDENCE 3U /* HeadingConfidence: ENUMERATED (8 values) */ -#define J2735_BW_HEADING_SLICE 16U /* HeadingSlice: BIT STRING (SIZE(16)) */ #define J2735_BW_HUMAN_PROPELLED_TYPE 3U /* HumanPropelledType: ENUMERATED (6 values) */ #define J2735_BW_ICE 1U /* Ice: SEQUENCE (1 fields) */ #define J2735_BW_ICE_TYPE 1U /* IceType: ENUMERATED (1 values) */ #define J2735_BW_INTERSECTION_ID 16U /* IntersectionID: INTEGER (0..65535) */ -#define J2735_BW_INTERSECTION_STATUS_OBJECT \ - 16U /* IntersectionStatusObject: BIT STRING (SIZE(16)) */ #define J2735_BW_IS_DOLLY 1U /* IsDolly: BOOLEAN */ #define J2735_BW_ISO_3833_VEHICLE_TYPE 7U /* Iso3833VehicleType: INTEGER (0..100) */ #define J2735_BW_LANE_CONNECTION_ID 8U /* LaneConnectionID: INTEGER (0..255) */ @@ -284,7 +279,7 @@ _Static_assert(J2735_INTERNAL_NSNNWN_SMALL_BITS == #define J2735_BW_LAYER_TYPE 3U /* LayerType: ENUMERATED (7 values) */ #define J2735_BW_LIGHTBAR_IN_USE 3U /* LightbarInUse: ENUMERATED (8 values) */ #define J2735_BW_LONGITUDE 32U /* Longitude: INTEGER (-1799999999..1800000001) */ -#define J2735_BW_MUTCDC_ODE 3U /* MUTCDCode: ENUMERATED (7 values) */ +#define J2735_BW_MUTCD_CODE 3U /* MUTCDCode: ENUMERATED (7 values) */ #define J2735_BW_MEAN_VARIATION 15U /* MeanVariation: INTEGER (0..25000) */ #define J2735_BW_MERGE_DIVERGE_NODE_ANGLE 9U /* MergeDivergeNodeAngle: INTEGER (-180..180) */ #define J2735_BW_MINUTE_OF_THE_YEAR 20U /* MinuteOfTheYear: INTEGER (0..527040) */ @@ -294,6 +289,21 @@ _Static_assert(J2735_INTERNAL_NSNNWN_SMALL_BITS == #define J2735_BW_MSG_CRC 16U /* MsgCRC: OCTET STRING (SIZE(2)) */ #define J2735_BW_MSG_COUNT 7U /* MsgCount: INTEGER (0..127) */ #define J2735_BW_MULTI_VEHICLE_RESPONSE 2U /* MultiVehicleResponse: ENUMERATED (4 values) */ +#define J2735_BW_NMEA_MSG_TYPE 15U /* NMEA-MsgType: INTEGER (0..32767) */ +#define J2735_BW_NMEA_REVISION 3U /* NMEA-Revision: ENUMERATED (7 values) */ +#define J2735_BW_NODE_LL_24_B 24U /* Node-LL-24B: SEQUENCE (2 fields) */ +#define J2735_BW_NODE_LL_28_B 28U /* Node-LL-28B: SEQUENCE (2 fields) */ +#define J2735_BW_NODE_LL_32_B 32U /* Node-LL-32B: SEQUENCE (2 fields) */ +#define J2735_BW_NODE_LL_36_B 36U /* Node-LL-36B: SEQUENCE (2 fields) */ +#define J2735_BW_NODE_LL_44_B 44U /* Node-LL-44B: SEQUENCE (2 fields) */ +#define J2735_BW_NODE_LL_48_B 48U /* Node-LL-48B: SEQUENCE (2 fields) */ +#define J2735_BW_NODE_LL_M_D_64_B 63U /* Node-LLmD-64b: SEQUENCE (2 fields) */ +#define J2735_BW_NODE_XY_20_B 20U /* Node-XY-20b: SEQUENCE (2 fields) */ +#define J2735_BW_NODE_XY_22_B 22U /* Node-XY-22b: SEQUENCE (2 fields) */ +#define J2735_BW_NODE_XY_24_B 24U /* Node-XY-24b: SEQUENCE (2 fields) */ +#define J2735_BW_NODE_XY_26_B 26U /* Node-XY-26b: SEQUENCE (2 fields) */ +#define J2735_BW_NODE_XY_28_B 28U /* Node-XY-28b: SEQUENCE (2 fields) */ +#define J2735_BW_NODE_XY_32_B 32U /* Node-XY-32b: SEQUENCE (2 fields) */ #define J2735_BW_NODE_ATTRIBUTE_LL 1U /* NodeAttributeLL: ENUMERATED (2 values) */ #define J2735_BW_NODE_ATTRIBUTE_XY 1U /* NodeAttributeXY: ENUMERATED (2 values) */ #define J2735_BW_NODE_OFFSET_POINT_LL 4U /* NodeOffsetPointLL: CHOICE (14 alternatives) */ @@ -303,38 +313,45 @@ _Static_assert(J2735_INTERNAL_NSNNWN_SMALL_BITS == #define J2735_BW_OBJECT_COUNT 10U /* ObjectCount: INTEGER (0..1023) */ #define J2735_BW_OBSTACLE_DIRECTION 15U /* ObstacleDirection */ #define J2735_BW_OBSTACLE_DISTANCE 15U /* ObstacleDistance: INTEGER (0..32767) */ +#define J2735_BW_OFFSET_B_09 9U /* Offset-B09: INTEGER (-256..255) */ +#define J2735_BW_OFFSET_B_10 10U /* Offset-B10: INTEGER (-512..511) */ +#define J2735_BW_OFFSET_B_11 11U /* Offset-B11: INTEGER (-1024..1023) */ +#define J2735_BW_OFFSET_B_12 12U /* Offset-B12: INTEGER (-2048..2047) */ +#define J2735_BW_OFFSET_B_13 13U /* Offset-B13: INTEGER (-4096..4095) */ +#define J2735_BW_OFFSET_B_14 14U /* Offset-B14: INTEGER (-8192..8191) */ +#define J2735_BW_OFFSET_B_16 16U /* Offset-B16: INTEGER (-32768..32767) */ +#define J2735_BW_OFFSET_LL_B_12 12U /* OffsetLL-B12: INTEGER (-2048..2047) */ +#define J2735_BW_OFFSET_LL_B_14 14U /* OffsetLL-B14: INTEGER (-8192..8191) */ +#define J2735_BW_OFFSET_LL_B_16 16U /* OffsetLL-B16: INTEGER (-32768..32767) */ +#define J2735_BW_OFFSET_LL_B_18 18U /* OffsetLL-B18: INTEGER (-131072..131071) */ +#define J2735_BW_OFFSET_LL_B_22 22U /* OffsetLL-B22: INTEGER (-2097152..2097151) */ +#define J2735_BW_OFFSET_LL_B_24 24U /* OffsetLL-B24: INTEGER (-8388608..8388607) */ #define J2735_BW_PATH_PREDICTION 24U /* PathPrediction: SEQUENCE (2 fields) */ #define J2735_BW_PEDESTRIAN_BICYCLE_DETECT 1U /* PedestrianBicycleDetect: BOOLEAN */ #define J2735_BW_PEDESTRIAN_CALL 1U /* PedestrianCall: BOOLEAN */ #define J2735_BW_PERMISSIVE_NON_PROTECTED 1U /* PermissiveNonProtected: ENUMERATED (2 values) */ -#define J2735_BW_PERSONAL_ASSISTIVE 6U /* PersonalAssistive: BIT STRING (SIZE(6)) */ #define J2735_BW_PERSONAL_CLUSTER_RADIUS 7U /* PersonalClusterRadius: INTEGER (0..100) */ #define J2735_BW_PERSONAL_CROSSING_IN_PROGRESS 1U /* PersonalCrossingInProgress: BOOLEAN */ #define J2735_BW_PERSONAL_CROSSING_REQUEST 1U /* PersonalCrossingRequest: BOOLEAN */ -#define J2735_BW_PERSONAL_DEVICE_USAGE_STATE \ - 9U /* PersonalDeviceUsageState: BIT STRING (SIZE(9)) \ - */ -#define J2735_BW_PERSONAL_DEVICE_USER_TYPE 3U /* PersonalDeviceUserType: ENUMERATED (5 values) */ -#define J2735_BW_PIVOTING_ALLOWED 1U /* PivotingAllowed: BOOLEAN */ -#define J2735_BW_PORTLAND_CEMENT 2U /* PortlandCement: SEQUENCE (1 fields) */ -#define J2735_BW_PORTLAND_CEMENT_TYPE 2U /* PortlandCementType: ENUMERATED (3 values) */ -#define J2735_BW_POSITION_CONFIDENCE 4U /* PositionConfidence: ENUMERATED (16 values) */ -#define J2735_BW_POSITION_CONFIDENCE_SET 7U /* PositionConfidenceSet: SEQUENCE (2 fields) */ -#define J2735_BW_POSITIONAL_ACCURACY 32U /* PositionalAccuracy: SEQUENCE (3 fields) */ +#define J2735_BW_PERSONAL_DEVICE_USER_TYPE 3U /* PersonalDeviceUserType: ENUMERATED (5 values) */ +#define J2735_BW_PIVOT_POINT_DESCRIPTION 27U /* PivotPointDescription: SEQUENCE (3 fields) */ +#define J2735_BW_PIVOTING_ALLOWED 1U /* PivotingAllowed: BOOLEAN */ +#define J2735_BW_PORTLAND_CEMENT 2U /* PortlandCement: SEQUENCE (1 fields) */ +#define J2735_BW_PORTLAND_CEMENT_TYPE 2U /* PortlandCementType: ENUMERATED (3 values) */ +#define J2735_BW_POSITION_CONFIDENCE 4U /* PositionConfidence: ENUMERATED (16 values) */ +#define J2735_BW_POSITION_CONFIDENCE_SET 7U /* PositionConfidenceSet: SEQUENCE (2 fields) */ +#define J2735_BW_POSITIONAL_ACCURACY 32U /* PositionalAccuracy: SEQUENCE (3 fields) */ #define J2735_BW_PRIORITIZATION_RESPONSE_STATUS \ 3U /* PrioritizationResponseStatus: ENUMERATED (8 values) */ -#define J2735_BW_PRIORITY 8U /* Priority: OCTET STRING (SIZE(1)) */ -#define J2735_BW_PRIORITY_REQUEST_TYPE 2U /* PriorityRequestType: ENUMERATED (4 values) */ -#define J2735_BW_PRIVILEGED_EVENT_FLAGS 16U /* PrivilegedEventFlags: BIT STRING (SIZE(16)) */ -#define J2735_BW_PRIVILEGED_EVENTS 21U /* PrivilegedEvents: SEQUENCE (2 fields) */ -#define J2735_BW_PROBE_SEGMENT_NUMBER 15U /* ProbeSegmentNumber: INTEGER (0..32767) */ -#define J2735_BW_PROPELLED_INFORMATION 2U /* PropelledInformation: CHOICE (3 alternatives) */ -#define J2735_BW_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY \ - 6U /* PublicSafetyAndRoadWorkerActivity: BIT STRING (SIZE(6)) */ -#define J2735_BW_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE \ - 7U /* PublicSafetyDirectingTrafficSubType: BIT STRING (SIZE(7)) */ +#define J2735_BW_PRIORITY 8U /* Priority: OCTET STRING (SIZE(1)) */ +#define J2735_BW_PRIORITY_REQUEST_TYPE 2U /* PriorityRequestType: ENUMERATED (4 values) */ +#define J2735_BW_PROBE_SEGMENT_NUMBER 15U /* ProbeSegmentNumber: INTEGER (0..32767) */ +#define J2735_BW_PROPELLED_INFORMATION 2U /* PropelledInformation: CHOICE (3 alternatives) */ #define J2735_BW_PUBLIC_SAFETY_EVENT_RESPONDER_WORKER_TYPE \ 3U /* PublicSafetyEventResponderWorkerType: ENUMERATED (8 values) */ +#define J2735_BW_RTCM_REVISION 2U /* RTCM-Revision: ENUMERATED (4 values) */ +#define J2735_BW_RTCM_HEADER 39U /* RTCMheader: SEQUENCE (2 fields) */ +#define J2735_BW_RADIUS_B_12 12U /* Radius-B12: INTEGER (0..4095) */ #define J2735_BW_RADIUS_OF_CURVATURE 16U /* RadiusOfCurvature: INTEGER (-32767..32767) */ #define J2735_BW_RAIN_SENSOR 3U /* RainSensor: ENUMERATED (8 values) */ #define J2735_BW_REGION_ID 8U /* RegionId: INTEGER (0..255) */ @@ -355,6 +372,7 @@ _Static_assert(J2735_INTERNAL_NSNNWN_SMALL_BITS == #define J2735_BW_ROCK 1U /* Rock: SEQUENCE (1 fields) */ #define J2735_BW_ROCK_TYPE 1U /* RockType: ENUMERATED (1 values) */ #define J2735_BW_SSP_INDEX 5U /* SSPindex: INTEGER (0..31) */ +#define J2735_BW_SCALE_B_12 12U /* Scale-B12: INTEGER (-2048..2047) */ #define J2735_BW_SECOND_OF_TIME 6U /* SecondOfTime: INTEGER (0..61) */ #define J2735_BW_SEGMENT_ATTRIBUTE_LL 4U /* SegmentAttributeLL: ENUMERATED (10 values) */ #define J2735_BW_SEGMENT_ATTRIBUTE_XY 4U /* SegmentAttributeXY: ENUMERATED (10 values) */ @@ -394,6 +412,8 @@ _Static_assert(J2735_INTERNAL_NSNNWN_SMALL_BITS == #define J2735_BW_THROTTLE_CONFIDENCE 2U /* ThrottleConfidence: ENUMERATED (4 values) */ #define J2735_BW_THROTTLE_POSITION 8U /* ThrottlePosition: INTEGER (0..200) */ #define J2735_BW_TIME_CONFIDENCE 5U /* TimeConfidence: ENUMERATED (17 values) */ +#define J2735_BW_TIME_IN_SECOND_B_16 16U /* TimeInSecond-B16: INTEGER (0..65535) */ +#define J2735_BW_TIME_IN_SECOND_B_8 8U /* TimeInSecond-B8: INTEGER (0..255) */ #define J2735_BW_TIME_INTERVAL_CONFIDENCE 4U /* TimeIntervalConfidence: INTEGER (0..15) */ #define J2735_BW_TIME_MARK 16U /* TimeMark: INTEGER (0..36111) */ #define J2735_BW_TIME_OFFSET 16U /* TimeOffset: INTEGER (1..65535) */ @@ -402,28 +422,20 @@ _Static_assert(J2735_INTERNAL_NSNNWN_SMALL_BITS == #define J2735_BW_TIRE_PRESSURE 8U /* TirePressure: INTEGER (0..250) */ #define J2735_BW_TIRE_PRESSURE_THRESHOLD_DETECTION \ 3U /* TirePressureThresholdDetection: ENUMERATED (8 values) */ -#define J2735_BW_TIRE_TEMP 16U /* TireTemp: INTEGER (-8736..55519) */ -#define J2735_BW_TRACTION_CONTROL_STATUS 2U /* TractionControlStatus: ENUMERATED (4 values) */ -#define J2735_BW_TRAFFIC_LIGHT_CONTROLLER_STATUS \ - 8U /* TrafficLightControllerStatus: BIT STRING (SIZE(8)) */ -#define J2735_BW_TRAFFIC_LIGHT_DIRECTION_CODE 9U /* TrafficLightDirectionCode: INTEGER (0..359) */ -#define J2735_BW_TRAFFIC_LIGHT_ID 1U /* TrafficLightID: CHOICE (2 alternatives) */ +#define J2735_BW_TIRE_TEMP 16U /* TireTemp: INTEGER (-8736..55519) */ +#define J2735_BW_TRACTION_CONTROL_STATUS 2U /* TractionControlStatus: ENUMERATED (4 values) */ +#define J2735_BW_TRAFFIC_LIGHT_DIRECTION_CODE 9U /* TrafficLightDirectionCode: INTEGER (0..359) */ +#define J2735_BW_TRAFFIC_LIGHT_ID 1U /* TrafficLightID: CHOICE (2 alternatives) */ #define J2735_BW_TRAFFIC_LIGHT_INTERVAL_TYPE \ - 1U /* TrafficLightIntervalType: ENUMERATED (2 values) */ -#define J2735_BW_TRAFFIC_LIGHT_OPERATION_STATUS \ - 8U /* TrafficLightOperationStatus: BIT STRING (SIZE(8)) */ -#define J2735_BW_TRAFFIC_LIGHT_TYPE 3U /* TrafficLightType: ENUMERATED (6 values) */ -#define J2735_BW_TRAFFIC_LIGHTING_STATUS 2U /* TrafficLightingStatus: ENUMERATED (3 values) */ + 1U /* TrafficLightIntervalType: ENUMERATED (2 values) */ #define J2735_BW_TRAILER_MASS 8U /* TrailerMass: INTEGER (0..255) */ #define J2735_BW_TRAILER_WEIGHT 16U /* TrailerWeight: INTEGER (0..64255) */ #define J2735_BW_TRANSIT_STATUS 6U /* TransitStatus: BIT STRING (SIZE(6)) */ #define J2735_BW_TRANSIT_VEHICLE_OCCUPANCY 3U /* TransitVehicleOccupancy: ENUMERATED (8 values) */ -#define J2735_BW_TRANSIT_VEHICLE_STATUS 8U /* TransitVehicleStatus: BIT STRING (SIZE(8)) */ #define J2735_BW_TRANSMISSION_AND_SPEED 16U /* TransmissionAndSpeed: SEQUENCE (2 fields) */ #define J2735_BW_TRANSMISSION_STATE 3U /* TransmissionState: ENUMERATED (8 values) */ #define J2735_BW_TRAVELER_INFO_TYPE 2U /* TravelerInfoType: ENUMERATED (4 values) */ #define J2735_BW_UNIQUE_MSGID 72U /* UniqueMSGID: OCTET STRING (SIZE(9)) */ -#define J2735_BW_USER_SIZE_AND_BEHAVIOUR 5U /* UserSizeAndBehaviour: BIT STRING (SIZE(5)) */ #define J2735_BW_VARIATION_STD_DEV 12U /* VariationStdDev: INTEGER (0..2500) */ #define J2735_BW_VEHICLE_HEIGHT 7U /* VehicleHeight: INTEGER (0..127) */ #define J2735_BW_VEHICLE_ID 1U /* VehicleID: CHOICE (2 alternatives) */ @@ -435,6 +447,12 @@ _Static_assert(J2735_INTERNAL_NSNNWN_SMALL_BITS == #define J2735_BW_VEHICLE_TYPE 5U /* VehicleType: ENUMERATED (17 values) */ #define J2735_BW_VEHICLE_WIDTH 10U /* VehicleWidth: INTEGER (0..1023) */ #define J2735_BW_VELOCITY 13U /* Velocity: INTEGER (0..8191) */ +#define J2735_BW_VERT_OFFSET_B_07 7U /* VertOffset-B07: INTEGER (-64..63) */ +#define J2735_BW_VERT_OFFSET_B_08 8U /* VertOffset-B08: INTEGER (-128..127) */ +#define J2735_BW_VERT_OFFSET_B_09 9U /* VertOffset-B09: INTEGER (-256..255) */ +#define J2735_BW_VERT_OFFSET_B_10 10U /* VertOffset-B10: INTEGER (-512..511) */ +#define J2735_BW_VERT_OFFSET_B_11 11U /* VertOffset-B11: INTEGER (-1024..1023) */ +#define J2735_BW_VERT_OFFSET_B_12 12U /* VertOffset-B12: INTEGER (-2048..2047) */ #define J2735_BW_VERTICAL_ACCELERATION 8U /* VerticalAcceleration: INTEGER (-127..127) */ #define J2735_BW_VERTICAL_ACCELERATION_THRESHOLD \ 5U /* VerticalAccelerationThreshold: BIT STRING (SIZE(5)) */ diff --git a/tests/J2735_UPER_test.c b/tests/J2735_UPER_test.c index 509a5de..5ae2fae 100644 --- a/tests/J2735_UPER_test.c +++ b/tests/J2735_UPER_test.c @@ -440,7 +440,7 @@ void test_inline_read_length_determinant_nonzero_bit_offset(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_inline_read_length_determinant_misaligned_access(void) { static const uint8_t payload[] = { - 0xFF, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0x2A, /* 0_0101010: short form, length=42 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; @@ -1075,7 +1075,7 @@ void test_inline_read_nsnnwn_nonzero_bit_offset(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_inline_read_nsnnwn_misaligned_access(void) { static const uint8_t payload[] = { - 0xFF, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0x14, /* 0_001010_0: small form, value=10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; @@ -1656,7 +1656,7 @@ void test_inline_skip_extensions_misaligned_access(void) { * Bytes: 00000001 00000001 10101011 * 0x01 0x01 0xAB */ static const uint8_t payload[] = { - 0xFF, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0x01, /* nsnnwn=0 + bitmap=1 */ 0x01, /* length_det=00000001 (1 byte) */ 0xAB, /* extension content (8 bits) */ diff --git a/tests/J2735_internal_DE_AllowedManeuvers_test.c b/tests/J2735_internal_DE_AllowedManeuvers_test.c index e0891c6..a476e64 100644 --- a/tests/J2735_internal_DE_AllowedManeuvers_test.c +++ b/tests/J2735_internal_DE_AllowedManeuvers_test.c @@ -352,18 +352,19 @@ void test_allowed_maneuvers_size(void) { } /** - * @brief Test AllowedManeuvers IS_EXTENDED always returns false. + * @brief Test AllowedManeuvers HAS_EXTENSION always returns false. */ /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ -void test_allowed_maneuvers_is_extended(void) { +void test_allowed_maneuvers_has_extension(void) { static const uint8_t payload[] = { 0xFF, /* flags[0:7]=11111111 */ 0xF0, /* flags[8:11]=1111 + padding */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_ALLOWED_MANEUVERS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "IS_EXTENDED should always be false for non-extensible type"); + bool has_ext = J2735_ALLOWED_MANEUVERS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, + "HAS_EXTENSION should always be false for non-extensible type"); } /** @@ -386,7 +387,7 @@ void test_allowed_maneuvers_is_extended(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_allowed_maneuvers_misaligned_access(void) { static const uint8_t payload[] = { - 0x00, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0xFF, /* flags[0:7]=11111111 */ 0xF0, /* flags[8:11]=1111 + padding */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ @@ -416,6 +417,6 @@ void run_testsuite_allowed_maneuvers(void) { RUN_TEST(test_allowed_maneuvers_single_bit_straight_allowed); RUN_TEST(test_allowed_maneuvers_single_bit_reserved_1); RUN_TEST(test_allowed_maneuvers_size); - RUN_TEST(test_allowed_maneuvers_is_extended); + RUN_TEST(test_allowed_maneuvers_has_extension); RUN_TEST(test_allowed_maneuvers_misaligned_access); } diff --git a/tests/J2735_internal_DE_AllowedManeuvers_test.h b/tests/J2735_internal_DE_AllowedManeuvers_test.h index c965757..03db8de 100644 --- a/tests/J2735_internal_DE_AllowedManeuvers_test.h +++ b/tests/J2735_internal_DE_AllowedManeuvers_test.h @@ -38,7 +38,7 @@ void test_allowed_maneuvers_single_bit_reserved_1(void); /* Metadata tests */ void test_allowed_maneuvers_size(void); -void test_allowed_maneuvers_is_extended(void); +void test_allowed_maneuvers_has_extension(void); /* Misalignment test */ void test_allowed_maneuvers_misaligned_access(void); diff --git a/tests/J2735_internal_DE_BrakeAppliedStatus_test.c b/tests/J2735_internal_DE_BrakeAppliedStatus_test.c index 354f270..8133ae6 100644 --- a/tests/J2735_internal_DE_BrakeAppliedStatus_test.c +++ b/tests/J2735_internal_DE_BrakeAppliedStatus_test.c @@ -294,17 +294,18 @@ void test_brake_applied_status_size(void) { } /** - * @brief Test BrakeAppliedStatus IS_EXTENDED always returns false. + * @brief Test BrakeAppliedStatus HAS_EXTENSION always returns false. */ /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ -void test_brake_applied_status_is_extended(void) { +void test_brake_applied_status_has_extension(void) { static const uint8_t payload[] = { 0xF8, /* flags[0:4]=11111 + padding */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_BRAKE_APPLIED_STATUS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "IS_EXTENDED should always be false for non-extensible type"); + bool has_ext = J2735_BRAKE_APPLIED_STATUS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, + "HAS_EXTENSION should always be false for non-extensible type"); } /** @@ -326,7 +327,7 @@ void test_brake_applied_status_is_extended(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_brake_applied_status_misaligned_access(void) { static const uint8_t payload[] = { - 0xFF, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0xF8, /* flags[0:4]=11111 + padding */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; @@ -353,6 +354,6 @@ void run_testsuite_brake_applied_status(void) { RUN_TEST(test_brake_applied_status_single_bit_unavailable); RUN_TEST(test_brake_applied_status_single_bit_right_rear); RUN_TEST(test_brake_applied_status_size); - RUN_TEST(test_brake_applied_status_is_extended); + RUN_TEST(test_brake_applied_status_has_extension); RUN_TEST(test_brake_applied_status_misaligned_access); } diff --git a/tests/J2735_internal_DE_BrakeAppliedStatus_test.h b/tests/J2735_internal_DE_BrakeAppliedStatus_test.h index 6d470f7..bc4cd32 100644 --- a/tests/J2735_internal_DE_BrakeAppliedStatus_test.h +++ b/tests/J2735_internal_DE_BrakeAppliedStatus_test.h @@ -37,7 +37,7 @@ void test_brake_applied_status_single_bit_right_rear(void); /* Metadata tests */ void test_brake_applied_status_size(void); -void test_brake_applied_status_is_extended(void); +void test_brake_applied_status_has_extension(void); /* Misalignment test */ void test_brake_applied_status_misaligned_access(void); diff --git a/tests/J2735_internal_DE_ExteriorLights_test.c b/tests/J2735_internal_DE_ExteriorLights_test.c index e221dbe..20d3392 100644 --- a/tests/J2735_internal_DE_ExteriorLights_test.c +++ b/tests/J2735_internal_DE_ExteriorLights_test.c @@ -39,6 +39,10 @@ * @par Wire Format Summary: * - Non-extended form (10 bits): [ext=0][9 flag bits] * - Extended form (17 bits): [ext=1][nsnnwn=7 bits][9 flag bits] + * + * @par Bit Numbering Convention: + * - ASN.1 bit 0 = leftmost/MSB of BIT STRING content (lowBeamHeadlightsOn) + * - ASN.1 bit 8 = rightmost root bit (parkingLightsOn) */ #include @@ -77,8 +81,8 @@ void test_exterior_lights_non_extended(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_EXTERIOR_LIGHTS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Extension bit should be 0 for non-extended form"); + bool has_ext = J2735_EXTERIOR_LIGHTS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Extension bit should be 0 for non-extended form"); TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x0155U, J2735_EXTERIOR_LIGHTS_GET(payload), "Flags should be 0x0155 for non-extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(10U, J2735_EXTERIOR_LIGHTS_SIZE(payload), @@ -115,8 +119,8 @@ void test_exterior_lights_extended(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_EXTERIOR_LIGHTS_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Extension bit should be 1 for extended form"); + bool has_ext = J2735_EXTERIOR_LIGHTS_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Extension bit should be 1 for extended form"); TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x01FFU, J2735_EXTERIOR_LIGHTS_GET(payload), "Flags should be 0x01FF for extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(17U, J2735_EXTERIOR_LIGHTS_SIZE(payload), @@ -214,8 +218,8 @@ void test_exterior_lights_all_zeros_non_extended(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_EXTERIOR_LIGHTS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_EXTERIOR_LIGHTS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x0000U, J2735_EXTERIOR_LIGHTS_GET(payload), "All flags should be zero"); } @@ -235,8 +239,8 @@ void test_exterior_lights_non_extended_all_flags_on(void) { 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_EXTERIOR_LIGHTS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_EXTERIOR_LIGHTS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x01FFU, J2735_EXTERIOR_LIGHTS_GET(payload), "All 9 flags should be ON (0x01FF)"); } @@ -257,8 +261,8 @@ void test_exterior_lights_extended_all_zeros(void) { 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_EXTERIOR_LIGHTS_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Should be extended"); + bool has_ext = J2735_EXTERIOR_LIGHTS_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Should be extended"); TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x0000U, J2735_EXTERIOR_LIGHTS_GET(payload), "All flags should be zero in extended form"); } @@ -371,14 +375,14 @@ void test_exterior_lights_single_bit_8_parking_lights(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_exterior_lights_misaligned_access(void) { static const uint8_t payload[] = { - 0x00, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0x7F, 0xC0, /* ext(0)+all flags ON */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; const uint8_t *unaligned_ptr = &payload[1]; - bool is_ext = J2735_EXTERIOR_LIGHTS_IS_EXTENDED(unaligned_ptr); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Misaligned: should be non-extended"); + bool has_ext = J2735_EXTERIOR_LIGHTS_HAS_EXTENSION(unaligned_ptr); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Misaligned: should be non-extended"); TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x01FFU, J2735_EXTERIOR_LIGHTS_GET(unaligned_ptr), "Misaligned: all flags should be ON"); } diff --git a/tests/J2735_internal_DE_GNSSstatus_test.c b/tests/J2735_internal_DE_GNSSstatus_test.c index 3624cb6..abf0720 100644 --- a/tests/J2735_internal_DE_GNSSstatus_test.c +++ b/tests/J2735_internal_DE_GNSSstatus_test.c @@ -313,17 +313,18 @@ void test_gnss_status_size(void) { } /** - * @brief Test GNSSstatus IS_EXTENDED always returns false. + * @brief Test GNSSstatus HAS_EXTENSION always returns false. */ /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ -void test_gnss_status_is_extended(void) { +void test_gnss_status_has_extension(void) { static const uint8_t payload[] = { 0xFF, /* flags[0:7]=11111111 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_GNSS_STATUS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "IS_EXTENDED should always be false for non-extensible type"); + bool has_ext = J2735_GNSS_STATUS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, + "HAS_EXTENSION should always be false for non-extensible type"); } /** @@ -345,7 +346,7 @@ void test_gnss_status_is_extended(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_gnss_status_misaligned_access(void) { static const uint8_t payload[] = { - 0x00, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0xFF, /* flags[0:7]=11111111 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; @@ -374,6 +375,6 @@ void run_testsuite_gnss_status(void) { RUN_TEST(test_gnss_status_single_bit_unavailable); RUN_TEST(test_gnss_status_single_bit_network_corrections_present); RUN_TEST(test_gnss_status_size); - RUN_TEST(test_gnss_status_is_extended); + RUN_TEST(test_gnss_status_has_extension); RUN_TEST(test_gnss_status_misaligned_access); } diff --git a/tests/J2735_internal_DE_GNSSstatus_test.h b/tests/J2735_internal_DE_GNSSstatus_test.h index 23590a0..c582428 100644 --- a/tests/J2735_internal_DE_GNSSstatus_test.h +++ b/tests/J2735_internal_DE_GNSSstatus_test.h @@ -38,7 +38,7 @@ void test_gnss_status_single_bit_network_corrections_present(void); /* Metadata tests */ void test_gnss_status_size(void); -void test_gnss_status_is_extended(void); +void test_gnss_status_has_extension(void); /* Misalignment test */ void test_gnss_status_misaligned_access(void); diff --git a/tests/J2735_internal_DE_LaneDirection_test.c b/tests/J2735_internal_DE_LaneDirection_test.c index 792296f..59ec0b0 100644 --- a/tests/J2735_internal_DE_LaneDirection_test.c +++ b/tests/J2735_internal_DE_LaneDirection_test.c @@ -229,19 +229,20 @@ void test_lane_direction_size(void) { } /** - * @brief Test LaneDirection IS_EXTENDED always returns false. + * @brief Test LaneDirection HAS_EXTENSION always returns false. * - * LaneDirection is non-extensible, so IS_EXTENDED must always return 0. + * LaneDirection is non-extensible, so HAS_EXTENSION must always return 0. */ /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ -void test_lane_direction_is_extended(void) { +void test_lane_direction_has_extension(void) { static const uint8_t payload[] = { 0xC0, /* flags[0:1]=11 + padding */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_LANE_DIRECTION_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "IS_EXTENDED should always be false for non-extensible type"); + bool has_ext = J2735_LANE_DIRECTION_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, + "HAS_EXTENSION should always be false for non-extensible type"); } /** @@ -267,7 +268,7 @@ void test_lane_direction_is_extended(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_lane_direction_misaligned_access(void) { static const uint8_t payload[] = { - 0xFF, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0xC0, /* flags[0:1]=11 + padding */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; @@ -292,6 +293,6 @@ void run_testsuite_lane_direction(void) { RUN_TEST(test_lane_direction_single_bit_ingress_path); RUN_TEST(test_lane_direction_single_bit_egress_path); RUN_TEST(test_lane_direction_size); - RUN_TEST(test_lane_direction_is_extended); + RUN_TEST(test_lane_direction_has_extension); RUN_TEST(test_lane_direction_misaligned_access); } diff --git a/tests/J2735_internal_DE_LaneDirection_test.h b/tests/J2735_internal_DE_LaneDirection_test.h index 984ac77..cf4e7a1 100644 --- a/tests/J2735_internal_DE_LaneDirection_test.h +++ b/tests/J2735_internal_DE_LaneDirection_test.h @@ -35,7 +35,7 @@ void test_lane_direction_single_bit_egress_path(void); /* Metadata tests */ void test_lane_direction_size(void); -void test_lane_direction_is_extended(void); +void test_lane_direction_has_extension(void); /* Misalignment test */ void test_lane_direction_misaligned_access(void); diff --git a/tests/J2735_internal_DE_LaneSharing_test.c b/tests/J2735_internal_DE_LaneSharing_test.c index ac8e8a8..47fb384 100644 --- a/tests/J2735_internal_DE_LaneSharing_test.c +++ b/tests/J2735_internal_DE_LaneSharing_test.c @@ -342,18 +342,19 @@ void test_lane_sharing_size(void) { } /** - * @brief Test LaneSharing IS_EXTENDED always returns false. + * @brief Test LaneSharing HAS_EXTENSION always returns false. */ /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ -void test_lane_sharing_is_extended(void) { +void test_lane_sharing_has_extension(void) { static const uint8_t payload[] = { 0xFF, /* flags[0:7]=11111111 */ 0xC0, /* flags[8:9]=11 + padding */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_LANE_SHARING_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "IS_EXTENDED should always be false for non-extensible type"); + bool has_ext = J2735_LANE_SHARING_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, + "HAS_EXTENSION should always be false for non-extensible type"); } /** @@ -376,7 +377,7 @@ void test_lane_sharing_is_extended(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_lane_sharing_misaligned_access(void) { static const uint8_t payload[] = { - 0x00, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0xFF, /* flags[0:7]=11111111 */ 0xC0, /* flags[8:9]=11 + padding */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ @@ -406,6 +407,6 @@ void run_testsuite_lane_sharing(void) { RUN_TEST(test_lane_sharing_single_bit_overlapping); RUN_TEST(test_lane_sharing_single_bit_reserved); RUN_TEST(test_lane_sharing_size); - RUN_TEST(test_lane_sharing_is_extended); + RUN_TEST(test_lane_sharing_has_extension); RUN_TEST(test_lane_sharing_misaligned_access); } diff --git a/tests/J2735_internal_DE_LaneSharing_test.h b/tests/J2735_internal_DE_LaneSharing_test.h index 18d8cfc..c42e360 100644 --- a/tests/J2735_internal_DE_LaneSharing_test.h +++ b/tests/J2735_internal_DE_LaneSharing_test.h @@ -38,7 +38,7 @@ void test_lane_sharing_single_bit_reserved(void); /* Metadata tests */ void test_lane_sharing_size(void); -void test_lane_sharing_is_extended(void); +void test_lane_sharing_has_extension(void); /* Misalignment test */ void test_lane_sharing_misaligned_access(void); diff --git a/tests/J2735_internal_DE_PersonalAssistive_test.c b/tests/J2735_internal_DE_PersonalAssistive_test.c index ee53c3a..0abd03b 100644 --- a/tests/J2735_internal_DE_PersonalAssistive_test.c +++ b/tests/J2735_internal_DE_PersonalAssistive_test.c @@ -36,6 +36,10 @@ * @par Wire Format Summary: * - Non-extended form (7 bits): [ext=0][6 flag bits] * - Extended form (14 bits): [ext=1][nsnnwn=7 bits][6 flag bits] + * + * @par Bit Numbering Convention: + * - ASN.1 bit 0 = leftmost/MSB of BIT STRING content (unavailable) + * - ASN.1 bit 5 = rightmost root bit (cognition) */ #include @@ -73,8 +77,8 @@ void test_personal_assistive_non_extended(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PERSONAL_ASSISTIVE_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Extension bit should be 0 for non-extended form"); + bool has_ext = J2735_PERSONAL_ASSISTIVE_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Extension bit should be 0 for non-extended form"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x2AU, J2735_PERSONAL_ASSISTIVE_GET(payload), "Flags should be 0x2A for non-extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(7U, J2735_PERSONAL_ASSISTIVE_SIZE(payload), @@ -109,8 +113,8 @@ void test_personal_assistive_extended(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PERSONAL_ASSISTIVE_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Extension bit should be 1 for extended form"); + bool has_ext = J2735_PERSONAL_ASSISTIVE_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Extension bit should be 1 for extended form"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x3FU, J2735_PERSONAL_ASSISTIVE_GET(payload), "Flags should be 0x3F for extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(14U, J2735_PERSONAL_ASSISTIVE_SIZE(payload), @@ -201,8 +205,8 @@ void test_personal_assistive_all_zeros_non_extended(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PERSONAL_ASSISTIVE_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_PERSONAL_ASSISTIVE_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x00U, J2735_PERSONAL_ASSISTIVE_GET(payload), "All flags should be zero"); } @@ -221,8 +225,8 @@ void test_personal_assistive_non_extended_all_flags_on(void) { 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PERSONAL_ASSISTIVE_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_PERSONAL_ASSISTIVE_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x3FU, J2735_PERSONAL_ASSISTIVE_GET(payload), "All 6 flags should be ON (0x3F)"); } @@ -242,8 +246,8 @@ void test_personal_assistive_extended_all_zeros(void) { 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PERSONAL_ASSISTIVE_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Should be extended"); + bool has_ext = J2735_PERSONAL_ASSISTIVE_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Should be extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x00U, J2735_PERSONAL_ASSISTIVE_GET(payload), "All flags should be zero in extended form"); } @@ -353,14 +357,14 @@ void test_personal_assistive_single_bit_5_cognition(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_personal_assistive_misaligned_access(void) { static const uint8_t payload[] = { - 0x00, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0x7E, /* ext(0)+flags(111111)+pad(1) */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; const uint8_t *unaligned_ptr = &payload[1]; - bool is_ext = J2735_PERSONAL_ASSISTIVE_IS_EXTENDED(unaligned_ptr); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Misaligned: should be non-extended"); + bool has_ext = J2735_PERSONAL_ASSISTIVE_HAS_EXTENSION(unaligned_ptr); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Misaligned: should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x3FU, J2735_PERSONAL_ASSISTIVE_GET(unaligned_ptr), "Misaligned: all flags should be ON"); } diff --git a/tests/J2735_internal_DE_PersonalDeviceUsageState_test.c b/tests/J2735_internal_DE_PersonalDeviceUsageState_test.c index cee9023..0aa3fc3 100644 --- a/tests/J2735_internal_DE_PersonalDeviceUsageState_test.c +++ b/tests/J2735_internal_DE_PersonalDeviceUsageState_test.c @@ -39,6 +39,10 @@ * @par Wire Format Summary: * - Non-extended form (10 bits): [ext=0][9 flag bits] * - Extended form (17 bits): [ext=1][nsnnwn=7 bits][9 flag bits] + * + * @par Bit Numbering Convention: + * - ASN.1 bit 0 = leftmost/MSB of BIT STRING content (unavailable) + * - ASN.1 bit 8 = rightmost root bit (viewing) */ #include @@ -69,8 +73,8 @@ void test_personal_device_usage_state_non_extended(void) { 0x55, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PERSONAL_DEVICE_USAGE_STATE_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Extension bit should be 0 for non-extended form"); + bool has_ext = J2735_PERSONAL_DEVICE_USAGE_STATE_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Extension bit should be 0 for non-extended form"); TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x0155U, J2735_PERSONAL_DEVICE_USAGE_STATE_GET(payload), "Flags should be 0x0155 for non-extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(10U, J2735_PERSONAL_DEVICE_USAGE_STATE_SIZE(payload), @@ -97,8 +101,8 @@ void test_personal_device_usage_state_extended(void) { 0x89, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PERSONAL_DEVICE_USAGE_STATE_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Extension bit should be 1 for extended form"); + bool has_ext = J2735_PERSONAL_DEVICE_USAGE_STATE_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Extension bit should be 1 for extended form"); TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x01FFU, J2735_PERSONAL_DEVICE_USAGE_STATE_GET(payload), "Flags should be 0x01FF for extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(17U, J2735_PERSONAL_DEVICE_USAGE_STATE_SIZE(payload), @@ -176,8 +180,8 @@ void test_personal_device_usage_state_all_zeros_non_extended(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PERSONAL_DEVICE_USAGE_STATE_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_PERSONAL_DEVICE_USAGE_STATE_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x0000U, J2735_PERSONAL_DEVICE_USAGE_STATE_GET(payload), "All flags should be zero"); } @@ -197,8 +201,8 @@ void test_personal_device_usage_state_non_extended_all_flags_on(void) { 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PERSONAL_DEVICE_USAGE_STATE_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_PERSONAL_DEVICE_USAGE_STATE_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x01FFU, J2735_PERSONAL_DEVICE_USAGE_STATE_GET(payload), "All 9 flags should be ON (0x01FF)"); } @@ -212,8 +216,8 @@ void test_personal_device_usage_state_extended_all_zeros(void) { 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PERSONAL_DEVICE_USAGE_STATE_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Should be extended"); + bool has_ext = J2735_PERSONAL_DEVICE_USAGE_STATE_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Should be extended"); TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x0000U, J2735_PERSONAL_DEVICE_USAGE_STATE_GET(payload), "All flags should be zero in extended form"); } @@ -320,14 +324,14 @@ void test_personal_device_usage_state_single_bit_8_viewing(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_personal_device_usage_state_misaligned_access(void) { static const uint8_t payload[] = { - 0x00, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0x7F, 0xC0, /* ext(0)+all flags ON */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; const uint8_t *unaligned_ptr = &payload[1]; - bool is_ext = J2735_PERSONAL_DEVICE_USAGE_STATE_IS_EXTENDED(unaligned_ptr); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Misaligned: should be non-extended"); + bool has_ext = J2735_PERSONAL_DEVICE_USAGE_STATE_HAS_EXTENSION(unaligned_ptr); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Misaligned: should be non-extended"); TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x01FFU, J2735_PERSONAL_DEVICE_USAGE_STATE_GET(unaligned_ptr), "Misaligned: all flags should be ON"); } diff --git a/tests/J2735_internal_DE_PublicSafetyAndRoadWorkerActivity_test.c b/tests/J2735_internal_DE_PublicSafetyAndRoadWorkerActivity_test.c index 952c961..2dd921a 100644 --- a/tests/J2735_internal_DE_PublicSafetyAndRoadWorkerActivity_test.c +++ b/tests/J2735_internal_DE_PublicSafetyAndRoadWorkerActivity_test.c @@ -36,6 +36,10 @@ * @par Wire Format Summary: * - Non-extended form (7 bits): [ext=0][6 flag bits] * - Extended form (14 bits): [ext=1][nsnnwn=7 bits][6 flag bits] + * + * @par Bit Numbering Convention: + * - ASN.1 bit 0 = leftmost/MSB of BIT STRING content (unavailable) + * - ASN.1 bit 5 = rightmost root bit (otherActivities) */ #include @@ -66,8 +70,8 @@ void test_public_safety_and_road_worker_activity_non_extended(void) { 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Extension bit should be 0 for non-extended form"); + bool has_ext = J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Extension bit should be 0 for non-extended form"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x2AU, J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_GET(payload), "Flags should be 0x2A for non-extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(7U, J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_SIZE(payload), @@ -93,8 +97,8 @@ void test_public_safety_and_road_worker_activity_extended(void) { 0x86, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Extension bit should be 1 for extended form"); + bool has_ext = J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Extension bit should be 1 for extended form"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x3FU, J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_GET(payload), "Flags should be 0x3F for extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(14U, J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_SIZE(payload), @@ -170,8 +174,8 @@ void test_public_safety_and_road_worker_activity_all_zeros_non_extended(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x00U, J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_GET(payload), "All flags should be zero"); } @@ -190,8 +194,8 @@ void test_public_safety_and_road_worker_activity_non_extended_all_flags_on(void) 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x3FU, J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_GET(payload), "All 6 flags should be ON (0x3F)"); } @@ -205,8 +209,8 @@ void test_public_safety_and_road_worker_activity_extended_all_zeros(void) { 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Should be extended"); + bool has_ext = J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Should be extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x00U, J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_GET(payload), "All flags should be zero in extended form"); } @@ -319,14 +323,14 @@ void test_public_safety_and_road_worker_activity_single_bit_5_other_activities(v /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_public_safety_and_road_worker_activity_misaligned_access(void) { static const uint8_t payload[] = { - 0x00, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0x7E, /* ext(0)+flags(111111)+pad(1) */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; const uint8_t *unaligned_ptr = &payload[1]; - bool is_ext = J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_IS_EXTENDED(unaligned_ptr); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Misaligned: should be non-extended"); + bool has_ext = J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_HAS_EXTENSION(unaligned_ptr); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Misaligned: should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x3FU, J2735_PUBLIC_SAFETY_AND_ROAD_WORKER_ACTIVITY_GET(unaligned_ptr), "Misaligned: all flags should be ON"); diff --git a/tests/J2735_internal_DE_PublicSafetyDirectingTrafficSubType_test.c b/tests/J2735_internal_DE_PublicSafetyDirectingTrafficSubType_test.c index 1299ccd..f06d166 100644 --- a/tests/J2735_internal_DE_PublicSafetyDirectingTrafficSubType_test.c +++ b/tests/J2735_internal_DE_PublicSafetyDirectingTrafficSubType_test.c @@ -37,6 +37,10 @@ * @par Wire Format Summary: * - Non-extended form (8 bits): [ext=0][7 flag bits] — exact byte, no padding * - Extended form (15 bits): [ext=1][nsnnwn=7 bits][7 flag bits] + * + * @par Bit Numbering Convention: + * - ASN.1 bit 0 = leftmost/MSB of BIT STRING content (unavailable) + * - ASN.1 bit 6 = rightmost root bit (highwayServiceVehiclePersonnel) */ #include @@ -72,8 +76,8 @@ void test_public_safety_directing_traffic_sub_type_non_extended(void) { 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Extension bit should be 0 for non-extended form"); + bool has_ext = J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Extension bit should be 0 for non-extended form"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x55U, J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_GET(payload), "Flags should be 0x55 for non-extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(8U, J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_SIZE(payload), @@ -99,8 +103,8 @@ void test_public_safety_directing_traffic_sub_type_extended(void) { 0x87, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Extension bit should be 1 for extended form"); + bool has_ext = J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Extension bit should be 1 for extended form"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x7FU, J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_GET(payload), "Flags should be 0x7F for extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(15U, @@ -185,8 +189,8 @@ void test_public_safety_directing_traffic_sub_type_all_zeros_non_extended(void) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x00U, J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_GET(payload), "All flags should be zero"); } @@ -205,8 +209,8 @@ void test_public_safety_directing_traffic_sub_type_non_extended_all_flags_on(voi 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x7FU, J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_GET(payload), "All 7 flags should be ON (0x7F)"); } @@ -220,8 +224,8 @@ void test_public_safety_directing_traffic_sub_type_extended_all_zeros(void) { 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Should be extended"); + bool has_ext = J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Should be extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x00U, J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_GET(payload), "All flags should be zero in extended form"); } @@ -336,14 +340,14 @@ void test_public_safety_directing_traffic_sub_type_single_bit_6_highway_service( /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_public_safety_directing_traffic_sub_type_misaligned_access(void) { static const uint8_t payload[] = { - 0x00, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0x7F, /* ext(0)+flags(1111111) */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; const uint8_t *unaligned_ptr = &payload[1]; - bool is_ext = J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_IS_EXTENDED(unaligned_ptr); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Misaligned: should be non-extended"); + bool has_ext = J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_HAS_EXTENSION(unaligned_ptr); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Misaligned: should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x7FU, J2735_PUBLIC_SAFETY_DIRECTING_TRAFFIC_SUB_TYPE_GET(unaligned_ptr), "Misaligned: all flags should be ON"); diff --git a/tests/J2735_internal_DE_TrafficLightOperationStatus_test.c b/tests/J2735_internal_DE_TrafficLightOperationStatus_test.c index 1df07ce..9400d33 100644 --- a/tests/J2735_internal_DE_TrafficLightOperationStatus_test.c +++ b/tests/J2735_internal_DE_TrafficLightOperationStatus_test.c @@ -38,6 +38,10 @@ * @par Wire Format Summary: * - Non-extended form (9 bits): [ext=0][8 flag bits] * - Extended form (16 bits): [ext=1][nsnnwn=7 bits][8 flag bits] — exact 2 bytes + * + * @par Bit Numbering Convention: + * - ASN.1 bit 0 = leftmost/MSB of BIT STRING content (manual) + * - ASN.1 bit 7 = rightmost root bit (reserved) */ #include @@ -74,8 +78,8 @@ void test_traffic_light_operation_status_non_extended(void) { 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_TRAFFIC_LIGHT_OPERATION_STATUS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Extension bit should be 0 for non-extended form"); + bool has_ext = J2735_TRAFFIC_LIGHT_OPERATION_STATUS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Extension bit should be 0 for non-extended form"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0xAAU, J2735_TRAFFIC_LIGHT_OPERATION_STATUS_GET(payload), "Flags should be 0xAA for non-extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(9U, J2735_TRAFFIC_LIGHT_OPERATION_STATUS_SIZE(payload), @@ -101,8 +105,8 @@ void test_traffic_light_operation_status_extended(void) { 0x88, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_TRAFFIC_LIGHT_OPERATION_STATUS_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Extension bit should be 1 for extended form"); + bool has_ext = J2735_TRAFFIC_LIGHT_OPERATION_STATUS_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Extension bit should be 1 for extended form"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0xFFU, J2735_TRAFFIC_LIGHT_OPERATION_STATUS_GET(payload), "Flags should be 0xFF for extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(16U, J2735_TRAFFIC_LIGHT_OPERATION_STATUS_SIZE(payload), @@ -177,8 +181,8 @@ void test_traffic_light_operation_status_all_zeros_non_extended(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_TRAFFIC_LIGHT_OPERATION_STATUS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_TRAFFIC_LIGHT_OPERATION_STATUS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x00U, J2735_TRAFFIC_LIGHT_OPERATION_STATUS_GET(payload), "All flags should be zero"); } @@ -198,8 +202,8 @@ void test_traffic_light_operation_status_non_extended_all_flags_on(void) { 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_TRAFFIC_LIGHT_OPERATION_STATUS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_TRAFFIC_LIGHT_OPERATION_STATUS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0xFFU, J2735_TRAFFIC_LIGHT_OPERATION_STATUS_GET(payload), "All 8 flags should be ON (0xFF)"); } @@ -213,8 +217,8 @@ void test_traffic_light_operation_status_extended_all_zeros(void) { 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_TRAFFIC_LIGHT_OPERATION_STATUS_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Should be extended"); + bool has_ext = J2735_TRAFFIC_LIGHT_OPERATION_STATUS_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Should be extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x00U, J2735_TRAFFIC_LIGHT_OPERATION_STATUS_GET(payload), "All flags should be zero in extended form"); } @@ -321,14 +325,14 @@ void test_traffic_light_operation_status_single_bit_7_reserved(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_traffic_light_operation_status_misaligned_access(void) { static const uint8_t payload[] = { - 0x00, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0x7F, 0x80, /* ext(0)+all flags ON */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; const uint8_t *unaligned_ptr = &payload[1]; - bool is_ext = J2735_TRAFFIC_LIGHT_OPERATION_STATUS_IS_EXTENDED(unaligned_ptr); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Misaligned: should be non-extended"); + bool has_ext = J2735_TRAFFIC_LIGHT_OPERATION_STATUS_HAS_EXTENSION(unaligned_ptr); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Misaligned: should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0xFFU, J2735_TRAFFIC_LIGHT_OPERATION_STATUS_GET(unaligned_ptr), "Misaligned: all flags should be ON"); } diff --git a/tests/J2735_internal_DE_TransitStatus_test.c b/tests/J2735_internal_DE_TransitStatus_test.c index 05e66cf..2386201 100644 --- a/tests/J2735_internal_DE_TransitStatus_test.c +++ b/tests/J2735_internal_DE_TransitStatus_test.c @@ -296,17 +296,18 @@ void test_transit_status_size(void) { } /** - * @brief Test TransitStatus IS_EXTENDED always returns false. + * @brief Test TransitStatus HAS_EXTENSION always returns false. */ /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ -void test_transit_status_is_extended(void) { +void test_transit_status_has_extension(void) { static const uint8_t payload[] = { 0xFC, /* flags[0:5]=111111 + padding */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_TRANSIT_STATUS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "IS_EXTENDED should always be false for non-extensible type"); + bool has_ext = J2735_TRANSIT_STATUS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, + "HAS_EXTENSION should always be false for non-extensible type"); } /** @@ -328,7 +329,7 @@ void test_transit_status_is_extended(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_transit_status_misaligned_access(void) { static const uint8_t payload[] = { - 0xFF, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0xFC, /* flags[0:5]=111111 + padding */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; @@ -355,6 +356,6 @@ void run_testsuite_transit_status(void) { RUN_TEST(test_transit_status_single_bit_none); RUN_TEST(test_transit_status_single_bit_occ_l); RUN_TEST(test_transit_status_size); - RUN_TEST(test_transit_status_is_extended); + RUN_TEST(test_transit_status_has_extension); RUN_TEST(test_transit_status_misaligned_access); } diff --git a/tests/J2735_internal_DE_TransitStatus_test.h b/tests/J2735_internal_DE_TransitStatus_test.h index ae9b7d8..0afa19d 100644 --- a/tests/J2735_internal_DE_TransitStatus_test.h +++ b/tests/J2735_internal_DE_TransitStatus_test.h @@ -37,7 +37,7 @@ void test_transit_status_single_bit_occ_l(void); /* Metadata tests */ void test_transit_status_size(void); -void test_transit_status_is_extended(void); +void test_transit_status_has_extension(void); /* Misalignment test */ void test_transit_status_misaligned_access(void); diff --git a/tests/J2735_internal_DE_UserSizeAndBehaviour_test.c b/tests/J2735_internal_DE_UserSizeAndBehaviour_test.c index 079bdd9..3fefa44 100644 --- a/tests/J2735_internal_DE_UserSizeAndBehaviour_test.c +++ b/tests/J2735_internal_DE_UserSizeAndBehaviour_test.c @@ -77,8 +77,8 @@ void test_user_size_and_behaviour_non_extended(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_USER_SIZE_AND_BEHAVIOUR_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Extension bit should be 0 for non-extended form"); + bool has_ext = J2735_USER_SIZE_AND_BEHAVIOUR_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Extension bit should be 0 for non-extended form"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x15U, J2735_USER_SIZE_AND_BEHAVIOUR_GET(payload), "Flags should be 0x15 for non-extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(6U, J2735_USER_SIZE_AND_BEHAVIOUR_SIZE(payload), @@ -126,8 +126,8 @@ void test_user_size_and_behaviour_extended(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_USER_SIZE_AND_BEHAVIOUR_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Extension bit should be 1 for extended form"); + bool has_ext = J2735_USER_SIZE_AND_BEHAVIOUR_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Extension bit should be 1 for extended form"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x1FU, J2735_USER_SIZE_AND_BEHAVIOUR_GET(payload), "Flags should be 0x1F for extended form"); TEST_ASSERT_EQUAL_UINT32_MESSAGE(13U, J2735_USER_SIZE_AND_BEHAVIOUR_SIZE(payload), @@ -221,8 +221,8 @@ void test_user_size_and_behaviour_all_zeros_non_extended(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_USER_SIZE_AND_BEHAVIOUR_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_USER_SIZE_AND_BEHAVIOUR_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x00U, J2735_USER_SIZE_AND_BEHAVIOUR_GET(payload), "All flags should be zero"); } @@ -245,8 +245,8 @@ void test_user_size_and_behaviour_non_extended_all_flags_on(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_USER_SIZE_AND_BEHAVIOUR_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Should be non-extended"); + bool has_ext = J2735_USER_SIZE_AND_BEHAVIOUR_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x1FU, J2735_USER_SIZE_AND_BEHAVIOUR_GET(payload), "All 5 flags should be ON (0x1F)"); } @@ -268,8 +268,8 @@ void test_user_size_and_behaviour_extended_all_zeros(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_USER_SIZE_AND_BEHAVIOUR_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_ext, "Should be extended"); + bool has_ext = J2735_USER_SIZE_AND_BEHAVIOUR_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_ext, "Should be extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x00U, J2735_USER_SIZE_AND_BEHAVIOUR_GET(payload), "All flags should be zero in extended form"); } @@ -403,14 +403,14 @@ void test_user_size_and_behaviour_single_bit_4_slow_moving(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_user_size_and_behaviour_misaligned_access(void) { static const uint8_t payload[] = { - 0x00, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0x7C, /* ext(0)+flags(11111)+pad(2) */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; const uint8_t *unaligned_ptr = &payload[1]; - bool is_ext = J2735_USER_SIZE_AND_BEHAVIOUR_IS_EXTENDED(unaligned_ptr); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "Misaligned: should be non-extended"); + bool has_ext = J2735_USER_SIZE_AND_BEHAVIOUR_HAS_EXTENSION(unaligned_ptr); + TEST_ASSERT_FALSE_MESSAGE(has_ext, "Misaligned: should be non-extended"); TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x1FU, J2735_USER_SIZE_AND_BEHAVIOUR_GET(unaligned_ptr), "Misaligned: all flags should be ON"); } diff --git a/tests/J2735_internal_DE_VehicleEventFlags_test.c b/tests/J2735_internal_DE_VehicleEventFlags_test.c index 921dcbf..477b4b3 100644 --- a/tests/J2735_internal_DE_VehicleEventFlags_test.c +++ b/tests/J2735_internal_DE_VehicleEventFlags_test.c @@ -101,8 +101,8 @@ void test_vehicle_event_flags_non_extended(void) { }; /* Check extension bit */ - bool is_extended = J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_extended, "Extension bit should be 0 for non-extended form"); + bool has_extension = J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_extension, "Extension bit should be 0 for non-extended form"); /* Check flags value using unified getter */ uint16_t const flags = J2735_VEHICLE_EVENT_FLAGS_GET(payload); @@ -151,8 +151,8 @@ void test_vehicle_event_flags_extended(void) { }; /* Check extension bit */ - bool is_extended = J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_extended, "Extension bit should be 1 for extended form"); + bool has_extension = J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_extension, "Extension bit should be 1 for extended form"); /* Check flags value using unified getter */ uint16_t const flags = J2735_VEHICLE_EVENT_FLAGS_GET(payload); @@ -500,8 +500,8 @@ void test_vehicle_event_flags_all_zeros_non_extended(void) { }; /* Verify extension bit */ - bool is_extended = J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_extended, "Extension bit should be 0"); + bool has_extension = J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_extension, "Extension bit should be 0"); /* Verify flags value is zero */ TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x0000U, J2735_VEHICLE_EVENT_FLAGS_GET(payload), @@ -552,8 +552,8 @@ void test_vehicle_event_flags_extended_single_jackknife(void) { }; /* Verify extension bit */ - bool is_extended = J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_extended, "Extension bit should be 1"); + bool has_extension = J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_extension, "Extension bit should be 1"); /* Verify flags value */ TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x0001U, J2735_VEHICLE_EVENT_FLAGS_GET(payload), @@ -598,8 +598,8 @@ void test_vehicle_event_flags_non_extended_all_root_flags_on_metadata(void) { }; /* Verify non-extended */ - bool is_extended = J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_extended, "Extension bit should be 0"); + bool has_extension = J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_extension, "Extension bit should be 0"); /* Verify max 13-bit value */ TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x1FFFU, J2735_VEHICLE_EVENT_FLAGS_GET(payload), @@ -664,8 +664,8 @@ void test_vehicle_event_flags_extended_all_zeros(void) { }; /* Verify extended */ - bool is_extended = J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_extended, "Extension bit should be 1"); + bool has_extension = J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_extension, "Extension bit should be 1"); /* Verify zero flags */ TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x0000U, J2735_VEHICLE_EVENT_FLAGS_GET(payload), @@ -709,8 +709,8 @@ void test_vehicle_event_flags_non_extended_alternating_0x1555_metadata(void) { }; /* Verify non-extended */ - bool is_extended = J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_extended, "Extension bit should be 0"); + bool has_extension = J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_extension, "Extension bit should be 0"); /* Verify alternating pattern */ TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x1555U, J2735_VEHICLE_EVENT_FLAGS_GET(payload), @@ -869,8 +869,8 @@ void test_vehicle_event_flags_non_extended_alternating_0x0AAA_metadata(void) { }; /* Verify non-extended */ - bool is_extended = J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_extended, "Extension bit should be 0"); + bool has_extension = J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_extension, "Extension bit should be 0"); /* Verify alternating pattern */ TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x0AAAU, J2735_VEHICLE_EVENT_FLAGS_GET(payload), @@ -1152,8 +1152,8 @@ void test_vehicle_event_flags_extended_single_hazard_lights(void) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_extended = J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED(payload); - TEST_ASSERT_TRUE_MESSAGE(is_extended, "Extension bit should be 1"); + bool has_extension = J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION(payload); + TEST_ASSERT_TRUE_MESSAGE(has_extension, "Extension bit should be 1"); TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x2000U, J2735_VEHICLE_EVENT_FLAGS_GET(payload), "Only bit 0 should be set in 14-bit form (0x2000)"); @@ -1190,7 +1190,7 @@ void test_vehicle_event_flags_extended_single_hazard_lights(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_vehicle_event_flags_misaligned_access(void) { static const uint8_t payload[] = { - 0x00, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0x7F, /* ext(0) + flags[12:6] = 01111111 */ 0xFC, /* flags[5:0] + padding = 11111100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ @@ -1198,8 +1198,8 @@ void test_vehicle_event_flags_misaligned_access(void) { const uint8_t *unaligned_ptr = &payload[1]; /* Verify non-extended */ - bool is_extended = J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED(unaligned_ptr); - TEST_ASSERT_FALSE_MESSAGE(is_extended, "Misaligned: extension bit should be 0"); + bool has_extension = J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION(unaligned_ptr); + TEST_ASSERT_FALSE_MESSAGE(has_extension, "Misaligned: extension bit should be 0"); /* Verify all 13 root flags ON */ TEST_ASSERT_EQUAL_HEX16_MESSAGE(0x1FFFU, J2735_VEHICLE_EVENT_FLAGS_GET(unaligned_ptr), diff --git a/tests/J2735_internal_DE_VerticalAccelerationThreshold_test.c b/tests/J2735_internal_DE_VerticalAccelerationThreshold_test.c index 79cb53c..193f992 100644 --- a/tests/J2735_internal_DE_VerticalAccelerationThreshold_test.c +++ b/tests/J2735_internal_DE_VerticalAccelerationThreshold_test.c @@ -299,17 +299,18 @@ void test_vertical_acceleration_threshold_size(void) { } /** - * @brief Test VerticalAccelerationThreshold IS_EXTENDED always returns false. + * @brief Test VerticalAccelerationThreshold HAS_EXTENSION always returns false. */ /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ -void test_vertical_acceleration_threshold_is_extended(void) { +void test_vertical_acceleration_threshold_has_extension(void) { static const uint8_t payload[] = { 0xF8, /* flags[0:4]=11111 + padding */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; - bool is_ext = J2735_VERTICAL_ACCELERATION_THRESHOLD_IS_EXTENDED(payload); - TEST_ASSERT_FALSE_MESSAGE(is_ext, "IS_EXTENDED should always be false for non-extensible type"); + bool has_ext = J2735_VERTICAL_ACCELERATION_THRESHOLD_HAS_EXTENSION(payload); + TEST_ASSERT_FALSE_MESSAGE(has_ext, + "HAS_EXTENSION should always be false for non-extensible type"); } /** @@ -331,7 +332,7 @@ void test_vertical_acceleration_threshold_is_extended(void) { /* cppcheck-suppress misra-c2012-8.7 ; Unity RUN_TEST requires external linkage */ void test_vertical_acceleration_threshold_misaligned_access(void) { static const uint8_t payload[] = { - 0xFF, /* junk byte for misalignment */ + 0xFF, /* padding byte to force misalignment */ 0xF8, /* flags[0:4]=11111 + padding */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ }; @@ -360,6 +361,6 @@ void run_testsuite_vertical_acceleration_threshold(void) { RUN_TEST(test_vertical_acceleration_threshold_single_bit_not_equipped); RUN_TEST(test_vertical_acceleration_threshold_single_bit_right_rear); RUN_TEST(test_vertical_acceleration_threshold_size); - RUN_TEST(test_vertical_acceleration_threshold_is_extended); + RUN_TEST(test_vertical_acceleration_threshold_has_extension); RUN_TEST(test_vertical_acceleration_threshold_misaligned_access); } diff --git a/tests/J2735_internal_DE_VerticalAccelerationThreshold_test.h b/tests/J2735_internal_DE_VerticalAccelerationThreshold_test.h index 0f38e9f..b35478a 100644 --- a/tests/J2735_internal_DE_VerticalAccelerationThreshold_test.h +++ b/tests/J2735_internal_DE_VerticalAccelerationThreshold_test.h @@ -37,7 +37,7 @@ void test_vertical_acceleration_threshold_single_bit_right_rear(void); /* Metadata tests */ void test_vertical_acceleration_threshold_size(void); -void test_vertical_acceleration_threshold_is_extended(void); +void test_vertical_acceleration_threshold_has_extension(void); /* Misalignment test */ void test_vertical_acceleration_threshold_misaligned_access(void); diff --git a/tests/J2735_internal_DF_ApproachOrLane_test.c b/tests/J2735_internal_DF_ApproachOrLane_test.c index cfd5fd1..e565bfe 100644 --- a/tests/J2735_internal_DF_ApproachOrLane_test.c +++ b/tests/J2735_internal_DF_ApproachOrLane_test.c @@ -21,8 +21,18 @@ * @author Yogev Neumann * @brief Tests for ApproachOrLane CHOICE type. * - * ApproachOrLane is a non-extensible CHOICE with 2 alternatives. - * This validates CHOICE index reading and alternative value extraction. + * @par ASN.1 Type Under Test: + * @code + * ApproachOrLane ::= CHOICE { + * approach ApproachID, -- 4 bits + * lane LaneID -- 8 bits + * } + * @endcode + * + * @par Wire Format Summary: + * - Approach selected (5 bits): [Index=0][ApproachID(4)] + * - Lane selected (9 bits): [Index=1][LaneID(8)] + * - Non-extensible CHOICE, 1-bit index * * All tests use the efficient single-I/O pattern: * @code diff --git a/tests/J2735_internal_DF_BSMcoreData_test.c b/tests/J2735_internal_DF_BSMcoreData_test.c index 96e3968..7b0df5b 100644 --- a/tests/J2735_internal_DF_BSMcoreData_test.c +++ b/tests/J2735_internal_DF_BSMcoreData_test.c @@ -21,7 +21,30 @@ * @author Yogev Neumann * @brief Tests for BSMcoreData non-extensible SEQUENCE. * - * The data frame BSMcoreData is a simple case with no extensions or optional fields. + * @par ASN.1 Type Under Test: + * @code + * BSMcoreData ::= SEQUENCE { + * msgCnt MsgCount, -- 7 bits + * id TemporaryID, -- 32 bits + * secMark DSecond, -- 16 bits + * lat Latitude, -- 31 bits (signed) + * long Longitude, -- 32 bits (signed) + * elev Elevation, -- 16 bits (signed) + * accuracy PositionalAccuracy, -- 32 bits + * transmission TransmissionState, -- 3 bits + * speed Speed, -- 13 bits + * heading Heading, -- 15 bits + * angle SteeringWheelAngle, -- 8 bits (signed) + * accelSet AccelerationSet4Way, -- 48 bits + * brakes BrakeSystemStatus, -- 15 bits + * size VehicleSize -- 22 bits + * } + * @endcode + * + * @par Wire Format Summary: + * - Fixed form (290 bits): all required fields, no preamble + * - No extension marker (non-extensible type) + * - No optional fields */ #include @@ -349,10 +372,12 @@ void test_bsm_core_data_misaligned_access(void) { 0xC7, /* lat[21:14] */ 0xF2, /* lat[13:6] */ 0xE8, /* lat[5:0] + padding */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* safety padding */ - }; + /* 32 bytes safety padding: BSM is 290 bits (~37 bytes). J2735_READ_BITS + loads 8 bytes at a time, so the buffer must extend beyond the last + field under test to avoid out-of-bounds reads. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00}; /* Offset pointer by 1 byte to force misalignment */ const uint8_t *unaligned_ptr = &payload[1]; diff --git a/tests/J2735_internal_DF_IntersectionReferenceID_test.c b/tests/J2735_internal_DF_IntersectionReferenceID_test.c index 6a0ba07..bfb4648 100644 --- a/tests/J2735_internal_DF_IntersectionReferenceID_test.c +++ b/tests/J2735_internal_DF_IntersectionReferenceID_test.c @@ -21,7 +21,18 @@ * @author Yogev Neumann * @brief Tests for IntersectionReferenceID non-extensible SEQUENCE. * - * The data frame IntersectionReferenceID is a simple case with an optional field. + * @par ASN.1 Type Under Test: + * @code + * IntersectionReferenceID ::= SEQUENCE { + * region RoadRegulatorID OPTIONAL, -- 16 bits + * id IntersectionID -- 16 bits + * } + * @endcode + * + * @par Wire Format Summary: + * - Region absent (17 bits): [Opt=0][id(16)] + * - Region present (33 bits): [Opt=1][region(16)][id(16)] + * - 1-bit optional preamble, no extension marker */ #include diff --git a/tests/J2735_internal_DF_PathPrediction_test.c b/tests/J2735_internal_DF_PathPrediction_test.c index 2a5b884..1b6feb4 100644 --- a/tests/J2735_internal_DF_PathPrediction_test.c +++ b/tests/J2735_internal_DF_PathPrediction_test.c @@ -21,7 +21,19 @@ * @author Yogev Neumann * @brief Tests for PathPrediction extensible SEQUENCE. * - * The data frame PathPrediction is a simple case with an extension field. + * @par ASN.1 Type Under Test: + * @code + * PathPrediction ::= SEQUENCE { + * radiusOfCurve RadiusOfCurvature, -- 16 bits (signed) + * confidence Confidence, -- 8 bits + * ... + * } + * @endcode + * + * @par Wire Format Summary: + * - Non-extended (25 bits): [Ext=0][radiusOfCurve(16)][confidence(8)] + * - Extended (25+ bits): [Ext=1][radiusOfCurve(16)][confidence(8)][ext data] + * - Extension marker at bit 0 */ #include diff --git a/tools/j2735_c_generator_data_frame.py b/tools/j2735_c_generator_data_frame.py index fa1fd2e..cb635c6 100644 --- a/tools/j2735_c_generator_data_frame.py +++ b/tools/j2735_c_generator_data_frame.py @@ -62,7 +62,7 @@ def generate_data_frame(type_name: str, spec: J2735Specification) -> str: """Generate complete C header file for a Data Frame. - This is the main entry point for Data Element code generation. Dispatches + This is the main entry point for Data Frame code generation. Dispatches to the appropriate internal generator based on the ASN.1 type class. Supported types: diff --git a/tools/j2735_c_generator_jinja.py b/tools/j2735_c_generator_jinja.py index 7aa8fd3..ae176c7 100644 --- a/tools/j2735_c_generator_jinja.py +++ b/tools/j2735_c_generator_jinja.py @@ -169,8 +169,19 @@ def filter_is_signed(field: SequenceField) -> bool: def filter_screaming_snake(name: str) -> str: """Convert CamelCase or mixedCase name to SCREAMING_SNAKE_CASE. - Handles abbreviations correctly: when 2+ uppercase letters are followed - by a lowercase letter, the abbreviation stays together. + Handles abbreviations correctly using a multi-phase uppercase split: + + 1. Single uppercase letter before CamelCase word (``DDate`` → ``D_DATE``). + A start-of-string anchor ``^`` limits this to names that begin + with a single-letter prefix, so mid-name abbreviations like + ``LL`` in ``Node-LLmD-64b`` stay intact. + 2. Long abbreviation (4+ letters) before CamelCase word + (``MUTCDCode`` → ``MUTCD_CODE``). The min-4 threshold protects + short abbreviations like BSM (3) unconditionally. GNSS (4) and + DSRC (4) would match but are safe because no spec name pairs them + with a CamelCase suffix (they use lowercase: GNSSstatus, DSRCmsgID). + 3. Remaining abbreviation run (2+ uppercase) before lowercase + (``GNSSstatus`` → ``GNSS_STATUS``). This is registered as a Jinja filter for use in templates. @@ -181,30 +192,80 @@ def filter_screaming_snake(name: str) -> str: SCREAMING_SNAKE_CASE version of the name. Examples: + Standard CamelCase: + >>> filter_screaming_snake("msgCnt") 'MSG_CNT' >>> filter_screaming_snake("MsgCount") 'MSG_COUNT' - >>> filter_screaming_snake("BSMcoreData") - 'BSM_CORE_DATA' >>> filter_screaming_snake("AccelerationSet4Way") 'ACCELERATION_SET_4_WAY' + >>> filter_screaming_snake("LATITUDE") + 'LATITUDE' + + ASN.1 hyphenated names: + >>> filter_screaming_snake("Offset-B10") 'OFFSET_B_10' >>> filter_screaming_snake("Node-LL-24B") 'NODE_LL_24_B' >>> filter_screaming_snake("NMEA-MsgType") 'NMEA_MSG_TYPE' + + Short abbreviation + lowercase continuation (must stay together): + + >>> filter_screaming_snake("BSMcoreData") + 'BSM_CORE_DATA' + >>> filter_screaming_snake("GNSSstatus") + 'GNSS_STATUS' + >>> filter_screaming_snake("DSRCmsgID") + 'DSRC_MSG_ID' + + Single uppercase prefix + CamelCase (D-prefix date/time types): + + >>> filter_screaming_snake("DDate") + 'D_DATE' + >>> filter_screaming_snake("DMonthDay") + 'D_MONTH_DAY' + >>> filter_screaming_snake("DFullTime") + 'D_FULL_TIME' + + Long abbreviation (4+) before CamelCase word: + + >>> filter_screaming_snake("MUTCDCode") + 'MUTCD_CODE' + >>> filter_screaming_snake("RTCMPackage") + 'RTCM_PACKAGE' + + Doubled letter after hyphen (LL = Lat/Lon abbreviation stays together): + + >>> filter_screaming_snake("Node-LLmD-64b") + 'NODE_LL_M_D_64_B' + >>> filter_screaming_snake("Node-LLdms-48b") + 'NODE_LL_DMS_48_B' """ # Step 1: Replace hyphens with underscores (ASN.1 names like Offset-B10, Node-LL-24B) name = name.replace("-", "_") - # Step 2: Insert underscore after abbreviation (2+ uppercase) before lowercase - result = sub(r"([A-Z]{2,})([a-z])", r"\1_\2", name) - # Step 3: Insert underscore between lowercase and uppercase + # Step 2: Split single uppercase prefix before CamelCase word + # DDate -> D_Date, DHour -> D_Hour + # Anchored to ^ so it only fires at the very start of the name. + # This keeps mid-name abbreviations like LL in Node_LLmD intact, + # while still splitting D-prefix types (DDate, DHour, etc.). + result = sub(r"^([A-Z])([A-Z][a-z])", r"\1_\2", name) + # Step 3: Split long abbreviation (4+ uppercase) before CamelCase word + # MUTCDCode -> MUTCD_Code, RTCMPackage -> RTCM_Package + # Min-4 threshold protects BSM (3) unconditionally. GNSS (4) and DSRC (4) + # would match the {4,} pattern, but are safe because no spec name pairs + # them with a CamelCase suffix (they use lowercase: GNSSstatus, DSRCmsgID). + result = sub(r"([A-Z]{4,})([A-Z][a-z])", r"\1_\2", result) + # Step 4: Split remaining abbreviation run (2+ uppercase) before lowercase + # GNSSstatus -> GNSS_status, BSMcoreData -> BSM_coreData + result = sub(r"([A-Z]{2,})([a-z])", r"\1_\2", result) + # Step 5: Insert underscore between lowercase and uppercase result = sub(r"([a-z])([A-Z])", r"\1_\2", result) - # Step 4: Insert underscore between letter and digit + # Step 6: Insert underscore between letter and digit result = sub(r"([a-zA-Z])([0-9])", r"\1_\2", result) - # Step 5: Insert underscore between digit and letter + # Step 7: Insert underscore between digit and letter result = sub(r"([0-9])([a-zA-Z])", r"\1_\2", result) return result.upper() diff --git a/tools/j2735_c_generator_wire_format.py b/tools/j2735_c_generator_wire_format.py index 99085f6..2b05c44 100644 --- a/tools/j2735_c_generator_wire_format.py +++ b/tools/j2735_c_generator_wire_format.py @@ -40,7 +40,7 @@ ) -@dataclass(frozen=True, slots=True) +@dataclass(frozen=True, kw_only=True, slots=True) class SequenceWireVariant: """A wire format variant for a SEQUENCE type. @@ -328,7 +328,7 @@ class ChoiceAlternativeDict(TypedDict): needs_shift: bool -@dataclass(frozen=True, slots=True) +@dataclass(frozen=True, kw_only=True, slots=True) class ChoiceWireVariant: """A wire format variant for a CHOICE alternative. diff --git a/tools/j2735_spec_constraints.py b/tools/j2735_spec_constraints.py index ab5500f..025c27f 100644 --- a/tools/j2735_spec_constraints.py +++ b/tools/j2735_spec_constraints.py @@ -1474,8 +1474,15 @@ def uper_bit_width(self) -> int | None: """Calculate total UPER bit-width for all fields. Returns: - Sum of all field bit-widths if all are fixed, non-optional, - and the sequence is non-extensible. None otherwise. + Sum of all root field bit-widths if all are fixed and + non-optional. None otherwise (e.g., OPTIONAL fields or + variable-width children). + + Note: + This does NOT include preamble bits (extension marker, + optional bitmap). Those are infrastructure, not fields. + Extensible SEQUENCEs return the root field sum, which is + used for J2735_BW_* constants and cross-check assertions. Examples: >>> SequenceType(fields=( @@ -1509,11 +1516,9 @@ def uper_bit_width(self) -> int | None: ... section_comment="", ... inline_comment="", ... ), - ... ), is_extensible=True).uper_bit_width is None - True + ... ), is_extensible=True).uper_bit_width + 3 """ - if self.is_extensible: - return None if any(f.is_optional for f in self.fields): return None total = 0 diff --git a/tools/templates/assemble_de_bitstring.j2 b/tools/templates/assemble_de_bitstring.j2 index 193cdec..c40252f 100644 --- a/tools/templates/assemble_de_bitstring.j2 +++ b/tools/templates/assemble_de_bitstring.j2 @@ -24,7 +24,6 @@ Context variables: - typedef: The full typedef object containing the metadata -#} -{%- set data_type = typedef.type_class.name | lower -%} {%- set is_extensible = typedef.constraint.is_extensible -%} {%- set named_bits = typedef.constraint.named_bits -%} {%- set typedef_name = typedef.name -%} @@ -131,6 +130,13 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_{{ typedef_name_upper }} == (J2735_INTERNAL_EXTENSION_MARKER_BITS + J2735_INTERNAL_NSNNWN_SMALL_BITS + J2735_INTERNAL_EXT_SIZE_{{ typedef_name_upper }}), "MAX_WIRE_BITS must equal ext_marker + nsnnwn + ext_size"); + +_Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_{{ typedef_name_upper }} <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); +{% else %} + +_Static_assert(J2735_BW_{{ typedef_name_upper }} <= 56U, + "BIT STRING must fit in a single 56-bit J2735_READ_BITS call"); {% endif %} {% if named_bits %} @@ -156,26 +162,24 @@ _Static_assert(J2735_INTERNAL_MAX_WIRE_BITS_{{ typedef_name_upper }} == /* INTERNAL: Extension Bit Check */ /* ============================================================================================== */ {% include 'bitstring/bitstring_internal_is_extension.j2' %} -{% if data_type == "bit_string" %} /* ============================================================================================== */ /* INTERNAL: Extract Flags */ /* ============================================================================================== */ -{% include 'bitstring/bitstring_internal_get_all.j2' %} +{% include 'bitstring/bitstring_internal_get_all.j2' %} -{% include 'bitstring/bitstring_internal_get_one.j2' %} -{% endif %} +{% include 'bitstring/bitstring_internal_get_one.j2' %} {% set public_api_line = "PUBLIC API: " ~ typedef_name ~ " Accessors" %} /* ============================================================================================== */ /* {{ "%-*s"|format(W, public_api_line) }} */ /* ============================================================================================== */ -{% include 'bitstring/bitstring_is_extended.j2' %} +{% include 'bitstring/bitstring_has_extension.j2' %} {% include 'bitstring/bitstring_size.j2' %} {% include 'bitstring/bitstring_get.j2' %} -{% if data_type == "bit_string" and named_bits %} +{% if named_bits %} {% include 'bitstring/bitstring_get_one.j2' %} {% endif %} diff --git a/tools/templates/bitstring/bitstring_get.j2 b/tools/templates/bitstring/bitstring_get.j2 index b0c6216..f7da27d 100644 --- a/tools/templates/bitstring/bitstring_get.j2 +++ b/tools/templates/bitstring/bitstring_get.j2 @@ -50,7 +50,7 @@ * @param[in] buf Pointer to the start of the {{ typedef_name }} UPER encoding (const uint8_t*). * @pre @p buf must point to valid {{ typedef_name }} encoding with +7 byte padding. * @return Right-aligned flag value ({{ return_type }}). Bit 0 of result = first named bit. - * @note Use J2735_{{ typedef_name_upper }}_IS_EXTENDED() to determine if bit {{ root_size }} is meaningful. + * @note Use J2735_{{ typedef_name_upper }}_HAS_EXTENSION() to determine if bit {{ root_size }} is meaningful. */ {% else %} /** diff --git a/tools/templates/bitstring/bitstring_get_one.j2 b/tools/templates/bitstring/bitstring_get_one.j2 index fb4ed0a..6d2a27d 100644 --- a/tools/templates/bitstring/bitstring_get_one.j2 +++ b/tools/templates/bitstring/bitstring_get_one.j2 @@ -49,9 +49,9 @@ * * @param[in] buf Pointer to {{ typedef_name }} UPER encoding (const uint8_t*). * @pre @p buf must point to valid encoding with +7 byte padding. - * @pre Caller should verify J2735_{{ typedef_name_upper }}_IS_EXTENDED(buf) returns true. + * @pre Caller should verify J2735_{{ typedef_name_upper }}_HAS_EXTENSION(buf) returns true. * @return 0 or 1. - * @warning Returns garbage (0 or 1) for non-extended messages. Always check IS_EXTENDED first. + * @warning Returns garbage (0 or 1) for non-extended messages. Always check HAS_EXTENSION first. */ {% else %} /** diff --git a/tools/templates/bitstring/bitstring_is_extended.j2 b/tools/templates/bitstring/bitstring_has_extension.j2 similarity index 80% rename from tools/templates/bitstring/bitstring_is_extended.j2 rename to tools/templates/bitstring/bitstring_has_extension.j2 index 92b3874..95b4a78 100644 --- a/tools/templates/bitstring/bitstring_is_extended.j2 +++ b/tools/templates/bitstring/bitstring_has_extension.j2 @@ -17,19 +17,19 @@ SPDX-FileCopyrightText: 2026 Yogev Neumann -#} {#- - BIT STRING Public Is-Extended Macro Template + BIT STRING Public Has-Extension Macro Template - Generates public C macro for checking if a BIT STRING is in extended form. + Generates public C macro for checking if a BIT STRING has an extension. Context variables: - typedef: The full typedef object containing the metadata Output format: /** - * @brief Check if VehicleEventFlags is in extended form. + * @brief Check if VehicleEventFlags has an extension. * ... */ - #define J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED(buf) \ + #define J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION(buf) \ J2735_INTERNAL_IS_EXTENSION_VEHICLE_EVENT_FLAGS(J2735_INTERNAL_RAW_READ_VEHICLE_EVENT_FLAGS(buf)) -#} {%- set ext_bits = typedef.constraint.ext_bits -%} @@ -38,7 +38,7 @@ {%- set typedef_name_upper = typedef_name | screaming_snake -%} {% if typedef.constraint.is_extensible %} /** - * @brief Check if {{ typedef_name }} is in extended form. + * @brief Check if {{ typedef_name }} has an extension. * * Extended form includes {{ ext_bits }} flags (bits 0-{{ ext_bits - 1 }}). * Root form has only {{ root_size }} flags (bits 0-{{ root_size - 1 }}). @@ -47,11 +47,11 @@ * @pre @p buf must point to valid {{ typedef_name }} encoding with +7 byte padding. * @return Non-zero (true) if extended ({{ ext_bits }} flags), zero (false) if root ({{ root_size }} flags). */ -#define J2735_{{ typedef_name_upper }}_IS_EXTENDED(buf) \ +#define J2735_{{ typedef_name_upper }}_HAS_EXTENSION(buf) \ J2735_INTERNAL_IS_EXTENSION_{{ typedef_name_upper }}(J2735_INTERNAL_RAW_READ_{{ typedef_name_upper }}(buf)) {% else %} /** - * @brief Check if {{ typedef_name }} is in extended form. + * @brief Check if {{ typedef_name }} has an extension. * * {{ typedef_name }} is a fixed-size BIT STRING with {{ root_size }} bits. * It does not have an extension marker, so this always returns 0 (false). @@ -59,5 +59,5 @@ * @param[in] buf Pointer to the start of the {{ typedef_name }} UPER encoding (const uint8_t*). * @return Always 0 (false) - this type is not extensible. */ -#define J2735_{{ typedef_name_upper }}_IS_EXTENDED(buf) ((void)(buf), 0) +#define J2735_{{ typedef_name_upper }}_HAS_EXTENSION(buf) ((void)(buf), 0) {% endif %} diff --git a/tools/templates/bitstring/bitstring_internal_get_all.j2 b/tools/templates/bitstring/bitstring_internal_get_all.j2 index 91da709..879342b 100644 --- a/tools/templates/bitstring/bitstring_internal_get_all.j2 +++ b/tools/templates/bitstring/bitstring_internal_get_all.j2 @@ -77,8 +77,8 @@ ? /* Extended: low {{ ext_bits }} bits */ \ (({{ return_type }})((raw{{ read_bits }}) & ((1ULL << J2735_INTERNAL_EXT_SIZE_{{ typedef_name_upper }}) - 1ULL))) \ : /* Non-ext: bits {{ read_bits - 2 }}..{{ root_shift }} = {{ root_size }} bits */ \ - (({{ return_type }})(((raw{{ read_bits }}) >> (J2735_INTERNAL_MAX_WIRE_BITS_{{ typedef_name_upper }} - 1U - J2735_INTERNAL_ROOT_SIZE_{{ typedef_name_upper }})) \ - & ((1ULL << J2735_INTERNAL_ROOT_SIZE_{{ typedef_name_upper }}) - 1ULL)))) + (({{ return_type }})(((raw{{ read_bits }}) >> (J2735_INTERNAL_MAX_WIRE_BITS_{{ typedef_name_upper }} - 1U - J2735_INTERNAL_ROOT_SIZE_BITS_{{ typedef_name_upper }})) \ + & ((1ULL << J2735_INTERNAL_ROOT_SIZE_BITS_{{ typedef_name_upper }}) - 1ULL)))) {% else %} /** * @internal diff --git a/tools/templates/bitstring/bitstring_internal_get_one.j2 b/tools/templates/bitstring/bitstring_internal_get_one.j2 index 92d1a58..35c7298 100644 --- a/tools/templates/bitstring/bitstring_internal_get_one.j2 +++ b/tools/templates/bitstring/bitstring_internal_get_one.j2 @@ -63,7 +63,7 @@ * constants. * @return 0 or 1 as uint8_t. * @warning For non-extended messages, bit_pos >= {{ root_size }} reads undefined garbage bits. - * Caller should verify IS_EXTENDED before accessing extension-only flags. + * Caller should verify HAS_EXTENSION before accessing extension-only flags. * @note Internal use only. Use J2735_{{ typedef_name_upper }}_GET_*() accessors for public API. */ #define J2735_INTERNAL_GET_ONE_{{ typedef_name_upper }}(raw{{ read_bits }}, bit_pos) \ diff --git a/tools/templates/bitstring/bitstring_internal_is_extension.j2 b/tools/templates/bitstring/bitstring_internal_is_extension.j2 index de78447..61577cc 100644 --- a/tools/templates/bitstring/bitstring_internal_is_extension.j2 +++ b/tools/templates/bitstring/bitstring_internal_is_extension.j2 @@ -48,7 +48,7 @@ * * @param[in] raw{{ read_bits }} Value previously returned by J2735_INTERNAL_RAW_READ_{{ typedef_name_upper }}(). * @return Non-zero (true) if extended form, zero (false) if root form. - * @note Internal use only. Use J2735_{{ typedef_name_upper }}_IS_EXTENDED() for public API. + * @note Internal use only. Use J2735_{{ typedef_name_upper }}_HAS_EXTENSION() for public API. */ #define J2735_INTERNAL_IS_EXTENSION_{{ typedef_name_upper }}(raw{{ read_bits }}) \ (((raw{{ read_bits }}) >> (J2735_INTERNAL_MAX_WIRE_BITS_{{ typedef_name_upper }} - 1U)) != 0U) diff --git a/tools/templates/bitstring/bitstring_internal_root_size.j2 b/tools/templates/bitstring/bitstring_internal_root_size.j2 index 7154c1f..3a0ecc6 100644 --- a/tools/templates/bitstring/bitstring_internal_root_size.j2 +++ b/tools/templates/bitstring/bitstring_internal_root_size.j2 @@ -20,7 +20,7 @@ BIT STRING Internal Root Size Constants Template Generates C #define constants for ASN.1 BIT STRING root size. - Pattern: J2735_INTERNAL_ROOT_SIZE_{TYPE} {ROOT_SIZE}U + Pattern: J2735_INTERNAL_ROOT_SIZE_BITS_{TYPE} {ROOT_SIZE}U Context variables: - typedef: The full typedef object containing the metadata @@ -30,7 +30,7 @@ Output format: /** @internal @brief Root size of... */ - #define J2735_INTERNAL_ROOT_SIZE_VEHICLE_EVENT_FLAGS 13U + #define J2735_INTERNAL_ROOT_SIZE_BITS_VEHICLE_EVENT_FLAGS 13U -#} {%- set root_size = typedef.constraint.root_size -%} {%- set typedef_name = typedef.name -%} @@ -39,4 +39,4 @@ * @internal * @brief Root size of {{ typedef_name }} in bits. */ -#define J2735_INTERNAL_ROOT_SIZE_{{ typedef_name_upper }} {{ root_size }}U +#define J2735_INTERNAL_ROOT_SIZE_BITS_{{ typedef_name_upper }} {{ root_size }}U diff --git a/tools/templates/bitstring/bitstring_size.j2 b/tools/templates/bitstring/bitstring_size.j2 index 6696a02..f06819f 100644 --- a/tools/templates/bitstring/bitstring_size.j2 +++ b/tools/templates/bitstring/bitstring_size.j2 @@ -53,7 +53,7 @@ (J2735_INTERNAL_IS_EXTENSION_{{ typedef_name_upper }}( \ J2735_INTERNAL_RAW_READ_{{ typedef_name_upper }}(buf)) \ ? J2735_INTERNAL_MAX_WIRE_BITS_{{ typedef_name_upper }} \ - : (J2735_INTERNAL_EXTENSION_MARKER_BITS + J2735_INTERNAL_ROOT_SIZE_{{ typedef_name_upper }})) + : (J2735_INTERNAL_EXTENSION_MARKER_BITS + J2735_INTERNAL_ROOT_SIZE_BITS_{{ typedef_name_upper }})) {% else %} /** * @brief Get wire size of {{ typedef_name }} in bits. diff --git a/tools/templates/wire_format_choice_section.j2 b/tools/templates/wire_format_choice_section.j2 index ec00d7a..7360389 100644 --- a/tools/templates/wire_format_choice_section.j2 +++ b/tools/templates/wire_format_choice_section.j2 @@ -20,8 +20,8 @@ J2735 CHOICE Wire Format Documentation Section (Partial Template) Renders wire format tables for all CHOICE alternatives. - Builds segments from domain data in ChoiceWireVariant, mirroring - how wire_format_table.j2 builds segments from SequenceWireVariant.fields. + Builds segments from domain data in ChoiceWireVariant, then + delegates box-drawing rendering to wire_format_draw_box.j2. Context variables: - choice_variants: list[ChoiceWireVariant] from get_choice_variants() @@ -66,18 +66,6 @@ {%- endif -%} {%- set val_content = variant.type_ref ~ " value (" ~ variant.value_bits ~ " bits)" -%} {%- set _ = segments.append((val_header, val_content, [val_header | length, val_content | length, 12] | max)) -%} -{#- Calculate column widths -#} -{%- set widths = [] -%} -{%- for seg in segments -%} -{%- set w = [seg[0] | length, seg[1] | length, seg[2]] | max -%} -{%- set _ = widths.append(w) -%} -{%- endfor %} - * ┌{% for w in widths %}{{ "─" * (w + 2) }}{% if not loop.last %}┬{% endif %}{% endfor %}┐ - * │{% for i in range(segments | length) %} {{ "%-*s" | format(widths[i], segments[i][0]) }} │{% endfor %} - - * ├{% for w in widths %}{{ "─" * (w + 2) }}{% if not loop.last %}┼{% endif %}{% endfor %}┤ - * │{% for i in range(segments | length) %} {{ "%-*s" | format(widths[i], segments[i][1]) }} │{% endfor %} - - * └{% for w in widths %}{{ "─" * (w + 2) }}{% if not loop.last %}┴{% endif %}{% endfor %}┘ +{% include 'wire_format_draw_box.j2' %} * @endverbatim {% endfor %} diff --git a/tools/templates/wire_format_draw_box.j2 b/tools/templates/wire_format_draw_box.j2 new file mode 100644 index 0000000..ae2ef47 --- /dev/null +++ b/tools/templates/wire_format_draw_box.j2 @@ -0,0 +1,46 @@ +{#- + Copyright 2026 Yogev Neumann + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 + SPDX-FileCopyrightText: 2026 Yogev Neumann +-#} +{#- + J2735 Wire Format Box-Drawing Sub-Template + + Renders a two-row Unicode box-drawing table from a pre-built segments list. + + Context variables: + - segments: list of (header, content, min_width) tuples + + Output format: + * ┌─────────┬───────────────────────────────┐ + * │ Header │ Header │ + * ├─────────┼───────────────────────────────┤ + * │ Content │ Content │ + * └─────────┴───────────────────────────────┘ +-#} +{#- Calculate column widths -#} +{%- set widths = [] -%} +{%- for seg in segments -%} +{%- set w = [seg[0] | length, seg[1] | length, seg[2]] | max -%} +{%- set _ = widths.append(w) -%} +{%- endfor %} + * ┌{% for w in widths %}{{ "─" * (w + 2) }}{% if not loop.last %}┬{% endif %}{% endfor %}┐ + * │{% for i in range(segments | length) %} {{ "%-*s" | format(widths[i], segments[i][0]) }} │{% endfor %} + + * ├{% for w in widths %}{{ "─" * (w + 2) }}{% if not loop.last %}┼{% endif %}{% endfor %}┤ + * │{% for i in range(segments | length) %} {{ "%-*s" | format(widths[i], segments[i][1]) }} │{% endfor %} + + * └{% for w in widths %}{{ "─" * (w + 2) }}{% if not loop.last %}┴{% endif %}{% endfor %}┘ diff --git a/tools/templates/wire_format_table.j2 b/tools/templates/wire_format_table.j2 index 0728fcf..1b78f8a 100644 --- a/tools/templates/wire_format_table.j2 +++ b/tools/templates/wire_format_table.j2 @@ -21,6 +21,7 @@ Renders a single wire format variant as a Unicode box-drawing table. Works directly with SequenceWireVariant containing SequenceField objects. + Delegates box-drawing rendering to wire_format_draw_box.j2. Context variables: - variant: SequenceWireVariant object (from j2735_c_generator_wire_format) @@ -75,16 +76,4 @@ {%- set _ = segments.append(("Bits " ~ bit_pos.val ~ "+", "(extension data)", 16)) -%} {%- endif -%} -{#- Calculate column widths -#} -{%- set widths = [] -%} -{%- for seg in segments -%} -{%- set w = [seg[0] | length, seg[1] | length, seg[2]] | max -%} -{%- set _ = widths.append(w) -%} -{%- endfor %} - * ┌{% for w in widths %}{{ "─" * (w + 2) }}{% if not loop.last %}┬{% endif %}{% endfor %}┐ - * │{% for i in range(segments | length) %} {{ "%-*s" | format(widths[i], segments[i][0]) }} │{% endfor %} - - * ├{% for w in widths %}{{ "─" * (w + 2) }}{% if not loop.last %}┼{% endif %}{% endfor %}┤ - * │{% for i in range(segments | length) %} {{ "%-*s" | format(widths[i], segments[i][1]) }} │{% endfor %} - - * └{% for w in widths %}{{ "─" * (w + 2) }}{% if not loop.last %}┴{% endif %}{% endfor %}┘ +{% include 'wire_format_draw_box.j2' %} diff --git a/tools/tests/c_generator/test_assemble_de_bitstring.py b/tools/tests/c_generator/test_assemble_de_bitstring.py index ba6f2b4..781e0cf 100644 --- a/tools/tests/c_generator/test_assemble_de_bitstring.py +++ b/tools/tests/c_generator/test_assemble_de_bitstring.py @@ -66,14 +66,14 @@ def test_extensible_has_constants_banner(self) -> None: self.assertIn("/* Constants", code) def test_non_extensible_assembled_uses_bw_not_root_size(self) -> None: - """Non-extensible assembled output must use J2735_BW_*, not ROOT_SIZE.""" + """Non-extensible assembled output must use J2735_BW_*, not ROOT_SIZE_BITS.""" for type_name, prefix in NON_EXTENSIBLE_BITSTRING_TYPES: with self.subTest(type_name=type_name): code = generate_data_element(type_name, self.spec) self.assertNotIn( - f"J2735_INTERNAL_ROOT_SIZE_{prefix}", + f"J2735_INTERNAL_ROOT_SIZE_BITS_{prefix}", code, - f"{type_name} assembled output should not contain ROOT_SIZE", + f"{type_name} assembled output should not contain ROOT_SIZE_BITS", ) self.assertIn( f"J2735_BW_{prefix}", @@ -82,9 +82,9 @@ def test_non_extensible_assembled_uses_bw_not_root_size(self) -> None: ) def test_extensible_assembled_uses_root_size(self) -> None: - """Extensible assembled output must define ROOT_SIZE.""" + """Extensible assembled output must define ROOT_SIZE_BITS.""" code = generate_data_element("VehicleEventFlags", self.spec) - self.assertIn("J2735_INTERNAL_ROOT_SIZE_VEHICLE_EVENT_FLAGS", code) + self.assertIn("J2735_INTERNAL_ROOT_SIZE_BITS_VEHICLE_EVENT_FLAGS", code) def test_wire_format_uses_doxygen_verbatim_blocks(self) -> None: """Wire format diagrams must be wrapped in @par + @verbatim/@endverbatim.""" diff --git a/tools/tests/c_generator/test_assemble_df_sequence.py b/tools/tests/c_generator/test_assemble_df_sequence.py index e9f0f29..54157a8 100644 --- a/tools/tests/c_generator/test_assemble_df_sequence.py +++ b/tools/tests/c_generator/test_assemble_df_sequence.py @@ -16,25 +16,14 @@ # SPDX-FileCopyrightText: 2026 Yogev Neumann """Tests for SEQUENCE type assembly via generate_data_frame().""" -from typing import ClassVar -from unittest import TestCase - from tools.j2735_c_generator_data_frame import generate_data_frame from tools.j2735_spec_constraints import SequenceType -from tools.j2735_spec_parser import J2735Specification, parse_spec_file -from tools.tests.conftest import SPEC_FILE_PATH +from tools.tests.conftest import SpecLoadingTestBase -class TestAssembleDfSequenceStaticAsserts(TestCase): +class TestAssembleDfSequenceStaticAsserts(SpecLoadingTestBase): """Tests for _Static_assert generation in assembled SEQUENCE headers.""" - spec: ClassVar[J2735Specification] - - @classmethod - def setUpClass(cls) -> None: - """Load spec once for all tests.""" - cls.spec = parse_spec_file(SPEC_FILE_PATH) - def test_extensible_sequence_has_root_size_assert(self) -> None: """Extensible SEQUENCE validates ROOT_SIZE_BITS == PREFIX + BW_*.""" code = generate_data_frame("PathPrediction", self.spec) diff --git a/tools/tests/c_generator/test_bitstring_common.py b/tools/tests/c_generator/test_bitstring_common.py index a069a12..21e505a 100644 --- a/tools/tests/c_generator/test_bitstring_common.py +++ b/tools/tests/c_generator/test_bitstring_common.py @@ -47,8 +47,8 @@ def test_naming_consistency_extensible(self) -> None: get_one_int = generate_bitstring_code( "bitstring/bitstring_internal_get_one.j2", self.spec, type_name ) - is_extended = generate_bitstring_code( - "bitstring/bitstring_is_extended.j2", self.spec, type_name + has_extension = generate_bitstring_code( + "bitstring/bitstring_has_extension.j2", self.spec, type_name ) size = generate_bitstring_code("bitstring/bitstring_size.j2", self.spec, type_name) get_pub = generate_bitstring_code("bitstring/bitstring_get.j2", self.spec, type_name) @@ -62,7 +62,7 @@ def test_naming_consistency_extensible(self) -> None: self.assertIn(f"J2735_INTERNAL_IS_EXTENSION_{prefix}", is_ext) self.assertIn(f"J2735_INTERNAL_GET_ALL_{prefix}", get_all) self.assertIn(f"J2735_INTERNAL_GET_ONE_{prefix}", get_one_int) - self.assertIn(f"J2735_{prefix}_IS_EXTENDED", is_extended) + self.assertIn(f"J2735_{prefix}_HAS_EXTENSION", has_extension) self.assertIn(f"J2735_{prefix}_SIZE", size) self.assertIn(f"J2735_{prefix}_GET", get_pub) self.assertIn(f"J2735_{prefix}_GET_", get_one_pub) diff --git a/tools/tests/c_generator/test_bitstring_is_extended.py b/tools/tests/c_generator/test_bitstring_has_extension.py similarity index 69% rename from tools/tests/c_generator/test_bitstring_is_extended.py rename to tools/tests/c_generator/test_bitstring_has_extension.py index fe61c22..62b0549 100644 --- a/tools/tests/c_generator/test_bitstring_is_extended.py +++ b/tools/tests/c_generator/test_bitstring_has_extension.py @@ -14,28 +14,28 @@ # # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: 2026 Yogev Neumann -"""Tests for BIT STRING public is-extended macro generator. +"""Tests for BIT STRING public has-extension macro generator. -Tests cover generate_bitstring_is_extended which generates -J2735__IS_EXTENDED public API macros. +Tests cover generate_bitstring_has_extension which generates +J2735__HAS_EXTENSION public API macros. """ from tools.tests.conftest import SpecLoadingTestBase, generate_bitstring_code -_TEMPLATE_NAME = "bitstring/bitstring_is_extended.j2" +_TEMPLATE_NAME = "bitstring/bitstring_has_extension.j2" -class TestIsExtendedGenerator(SpecLoadingTestBase): - """Tests for generate_bitstring_is_extended.""" +class TestHasExtensionGenerator(SpecLoadingTestBase): + """Tests for generate_bitstring_has_extension.""" def test_extensible_type_has_public_api(self) -> None: - """VehicleEventFlags should have IS_EXTENDED macro.""" + """VehicleEventFlags should have HAS_EXTENSION macro.""" code = generate_bitstring_code(_TEMPLATE_NAME, self.spec, "VehicleEventFlags") - self.assertIn("J2735_VEHICLE_EVENT_FLAGS_IS_EXTENDED", code) + self.assertIn("J2735_VEHICLE_EVENT_FLAGS_HAS_EXTENSION", code) # Should call internal macro self.assertIn("J2735_INTERNAL_IS_EXTENSION_VEHICLE_EVENT_FLAGS", code) def test_non_extensible_type_always_false(self) -> None: """GNSSstatus should always return 0 (never extended).""" code = generate_bitstring_code(_TEMPLATE_NAME, self.spec, "GNSSstatus") - self.assertIn("J2735_GNSS_STATUS_IS_EXTENDED", code) + self.assertIn("J2735_GNSS_STATUS_HAS_EXTENSION", code) diff --git a/tools/tests/c_generator/test_bitstring_internal_raw_read.py b/tools/tests/c_generator/test_bitstring_internal_raw_read.py index 7cb7a53..3917245 100644 --- a/tools/tests/c_generator/test_bitstring_internal_raw_read.py +++ b/tools/tests/c_generator/test_bitstring_internal_raw_read.py @@ -68,7 +68,7 @@ def test_non_extensible_must_not_reference_max_wire_bits(self) -> None: ) def test_non_extensible_raw_read_uses_bw_constant(self) -> None: - """Non-extensible RAW_READ should read J2735_BW_* bits, not ROOT_SIZE.""" + """Non-extensible RAW_READ should read J2735_BW_* bits, not ROOT_SIZE_BITS.""" for type_name, prefix in NON_EXTENSIBLE_BITSTRING_TYPES: with self.subTest(type_name=type_name): code = generate_bitstring_code(_TEMPLATE_NAME, self.spec, type_name) @@ -78,9 +78,9 @@ def test_non_extensible_raw_read_uses_bw_constant(self) -> None: f"{type_name} RAW_READ should use J2735_BW_* as bit count", ) self.assertNotIn( - f"J2735_INTERNAL_ROOT_SIZE_{prefix}", + f"J2735_INTERNAL_ROOT_SIZE_BITS_{prefix}", code, - f"{type_name} RAW_READ should not reference ROOT_SIZE", + f"{type_name} RAW_READ should not reference ROOT_SIZE_BITS", ) def test_extensible_raw_read_uses_max_wire_bits(self) -> None: diff --git a/tools/tests/c_generator/test_bitstring_internal_root_size.py b/tools/tests/c_generator/test_bitstring_internal_root_size.py index 0bb2de6..b9bfab9 100644 --- a/tools/tests/c_generator/test_bitstring_internal_root_size.py +++ b/tools/tests/c_generator/test_bitstring_internal_root_size.py @@ -17,7 +17,7 @@ """Tests for BIT STRING internal root size constants generator. Tests cover bitstring_internal_root_size.j2 which generates -J2735_INTERNAL_ROOT_SIZE_{TYPE} constants for root bit count. +J2735_INTERNAL_ROOT_SIZE_BITS_{TYPE} constants for root bit count. """ from tools.tests.conftest import SpecLoadingTestBase, generate_bitstring_code @@ -31,23 +31,23 @@ class TestRootSizeGenerator(SpecLoadingTestBase): def test_extensible_type_has_root_size_13(self) -> None: """VehicleEventFlags should have root_size=13.""" code = generate_bitstring_code(_TEMPLATE_NAME, self.spec, "VehicleEventFlags") - self.assertIn("J2735_INTERNAL_ROOT_SIZE_VEHICLE_EVENT_FLAGS", code) + self.assertIn("J2735_INTERNAL_ROOT_SIZE_BITS_VEHICLE_EVENT_FLAGS", code) self.assertIn("13U", code) def test_non_extensible_8bit_type(self) -> None: """GNSSstatus (8-bit) should have root_size=8.""" code = generate_bitstring_code(_TEMPLATE_NAME, self.spec, "GNSSstatus") - self.assertIn("J2735_INTERNAL_ROOT_SIZE_GNSS_STATUS", code) + self.assertIn("J2735_INTERNAL_ROOT_SIZE_BITS_GNSS_STATUS", code) self.assertIn("8U", code) def test_non_extensible_12bit_type(self) -> None: """AllowedManeuvers (12-bit) should have root_size=12.""" code = generate_bitstring_code(_TEMPLATE_NAME, self.spec, "AllowedManeuvers") - self.assertIn("J2735_INTERNAL_ROOT_SIZE_ALLOWED_MANEUVERS", code) + self.assertIn("J2735_INTERNAL_ROOT_SIZE_BITS_ALLOWED_MANEUVERS", code) self.assertIn("12U", code) def test_small_2bit_type(self) -> None: """LaneDirection (2-bit) should have root_size=2.""" code = generate_bitstring_code(_TEMPLATE_NAME, self.spec, "LaneDirection") - self.assertIn("J2735_INTERNAL_ROOT_SIZE_LANE_DIRECTION", code) + self.assertIn("J2735_INTERNAL_ROOT_SIZE_BITS_LANE_DIRECTION", code) self.assertIn("2U", code) diff --git a/tools/tests/c_generator/test_bitstring_size.py b/tools/tests/c_generator/test_bitstring_size.py index 37f7fb7..266507b 100644 --- a/tools/tests/c_generator/test_bitstring_size.py +++ b/tools/tests/c_generator/test_bitstring_size.py @@ -63,7 +63,7 @@ def test_non_extensible_size_must_not_include_extension_marker_bits(self) -> Non """Non-extensible SIZE must not add J2735_INTERNAL_EXTENSION_MARKER_BITS. Non-extensible BIT STRING has no extension marker on the wire. - SIZE should be exactly ROOT_SIZE, not EXTENSION_MARKER_BITS + ROOT_SIZE. + SIZE should be exactly ROOT_SIZE_BITS, not EXTENSION_MARKER_BITS + ROOT_SIZE_BITS. Example: LaneDirection SIZE should be 2, not 1+2=3. """ for type_name, prefix in NON_EXTENSIBLE_BITSTRING_TYPES: diff --git a/tools/tests/c_generator/test_choice_type.py b/tools/tests/c_generator/test_choice_type.py index f3c8ad0..39d5181 100644 --- a/tools/tests/c_generator/test_choice_type.py +++ b/tools/tests/c_generator/test_choice_type.py @@ -16,24 +16,13 @@ # SPDX-FileCopyrightText: 2026 Yogev Neumann """Tests for CHOICE type code generation via generate_data_frame().""" -from typing import ClassVar -from unittest import TestCase - from tools.j2735_c_generator_data_frame import generate_data_frame -from tools.j2735_spec_parser import J2735Specification, parse_spec_file -from tools.tests.conftest import SPEC_FILE_PATH +from tools.tests.conftest import SpecLoadingTestBase -class TestGenerateDataframeChoice(TestCase): +class TestGenerateDataframeChoice(SpecLoadingTestBase): """Tests for generate_data_frame() with CHOICE types.""" - spec: ClassVar[J2735Specification] - - @classmethod - def setUpClass(cls) -> None: - """Load spec once for all tests.""" - cls.spec = parse_spec_file(SPEC_FILE_PATH) - def test_generates_header_guard(self) -> None: """Generated code includes proper header guard.""" code = generate_data_frame("ApproachOrLane", self.spec) diff --git a/tools/tests/c_generator/test_jinja_filters.py b/tools/tests/c_generator/test_jinja_filters.py index edbd955..d010718 100644 --- a/tools/tests/c_generator/test_jinja_filters.py +++ b/tools/tests/c_generator/test_jinja_filters.py @@ -56,7 +56,7 @@ def test_lowercase_input(self) -> None: def test_mixed_case_abbreviation(self) -> None: """Handle mixed case with abbreviations.""" self.assertEqual(filter_screaming_snake("BSMcoreData"), "BSM_CORE_DATA") - self.assertEqual(filter_screaming_snake("HTTPSconnection"), "HTTPS_CONNECTION") + self.assertEqual(filter_screaming_snake("MUTCDCode"), "MUTCD_CODE") def test_digits_in_name(self) -> None: """Handle digits - split before and after.""" @@ -73,6 +73,11 @@ def test_hyphenated_asn1_names(self) -> None: self.assertEqual(filter_screaming_snake("VertOffset-B07"), "VERT_OFFSET_B_07") self.assertEqual(filter_screaming_snake("TimeInSecond-B16"), "TIME_IN_SECOND_B_16") + def test_doubled_letter_after_hyphen(self) -> None: + """LL abbreviation after hyphen stays together (Node-LLmD, Node-LLdms).""" + self.assertEqual(filter_screaming_snake("Node-LLmD-64b"), "NODE_LL_M_D_64_B") + self.assertEqual(filter_screaming_snake("Node-LLdms-48b"), "NODE_LL_DMS_48_B") + def test_already_screaming(self) -> None: """Already SCREAMING_SNAKE stays the same.""" self.assertEqual(filter_screaming_snake("MSG_COUNT"), "MSG_COUNT") @@ -110,6 +115,11 @@ def test_hyphenated_asn1_names(self) -> None: self.assertEqual(filter_snake_case("OffsetLL-B12"), "offset_ll_b_12") self.assertEqual(filter_snake_case("NMEA-MsgType"), "nmea_msg_type") + def test_doubled_letter_after_hyphen(self) -> None: + """LL abbreviation after hyphen stays together (Node-LLmD, Node-LLdms).""" + self.assertEqual(filter_snake_case("Node-LLmD-64b"), "node_ll_m_d_64_b") + self.assertEqual(filter_snake_case("Node-LLdms-80b"), "node_ll_dms_80_b") + def test_already_snake(self) -> None: """Already snake_case stays the same.""" self.assertEqual(filter_snake_case("msg_count"), "msg_count") diff --git a/tools/tests/c_generator/test_sequence_get.py b/tools/tests/c_generator/test_sequence_get.py index 046236c..27527e8 100644 --- a/tools/tests/c_generator/test_sequence_get.py +++ b/tools/tests/c_generator/test_sequence_get.py @@ -22,48 +22,24 @@ from unittest import TestCase -from tools.j2735_c_generator_jinja import ( - create_jinja_env, - get_template, -) -from tools.j2735_spec_constraints import SequenceType -from tools.j2735_spec_parser import J2735Specification from tools.tests.conftest import ( SpecLoadingTestBase, - get_sequence_typedef, + generate_sequence_code, make_extensible_mock_spec, make_nested_mock_spec, make_optional_mock_spec, ) -_TEMPLATE_NAME = "sequence/sequence_get.j2" - - -def generate_sequence_get(type_name: str, spec: J2735Specification) -> str: - """Generate C #define macros for field getters of a SEQUENCE. - - Args: - type_name: Name of the SEQUENCE type. - spec: The parsed J2735 specification. - - Returns: - C code with #define macros for each field. - - Raises: - ValueError: If type_name is not found or not a SEQUENCE. - """ - typedef = get_sequence_typedef(type_name, spec) - assert isinstance(typedef.constraint, SequenceType) - return get_template(create_jinja_env(), _TEMPLATE_NAME).render(typedef=typedef) +_SEQUENCE_GET_TEMPLATE_NAME = "sequence/sequence_get.j2" class TestGetGeneration(TestCase): - """Tests for generate_sequence_get function.""" + """Tests for sequence_get.j2 template with mock specs.""" def test_unsigned_field(self) -> None: """Unsigned field uses cast to uint type.""" spec = make_nested_mock_spec() - code = generate_sequence_get("PositionalAccuracy", spec) + code = generate_sequence_code(_SEQUENCE_GET_TEMPLATE_NAME, spec, "PositionalAccuracy") self.assertIn("J2735_POSITIONAL_ACCURACY_GET_SEMI_MAJOR(buf)", code) self.assertIn("(uint8_t)", code) @@ -72,7 +48,7 @@ def test_unsigned_field(self) -> None: def test_signed_field(self) -> None: """Signed field uses SIGN_EXTEND macro.""" spec = make_extensible_mock_spec() - code = generate_sequence_get("PathPrediction", spec) + code = generate_sequence_code(_SEQUENCE_GET_TEMPLATE_NAME, spec, "PathPrediction") self.assertIn("J2735_PATH_PREDICTION_GET_RADIUS_OF_CURVE(buf)", code) self.assertIn("J2735_INTERNAL_SIGN_EXTEND", code) @@ -81,26 +57,26 @@ def test_signed_field(self) -> None: def test_optional_field_has_precondition(self) -> None: """Optional field has @pre comment for HAS macro.""" spec = make_optional_mock_spec() - code = generate_sequence_get("IntersectionReferenceID", spec) + code = generate_sequence_code(_SEQUENCE_GET_TEMPLATE_NAME, spec, "IntersectionReferenceID") self.assertIn("J2735_INTERSECTION_REFERENCE_ID_GET_REGION(buf)", code) self.assertIn("@pre J2735_INTERSECTION_REFERENCE_ID_HAS_REGION(buf)", code) def test_not_found_raises(self) -> None: """Unknown type raises ValueError.""" - spec = make_nested_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_get("UnknownType", spec) + generate_sequence_code( + _SEQUENCE_GET_TEMPLATE_NAME, make_nested_mock_spec(), "UnknownType" + ) self.assertIn("not found", str(ctx.exception)) def test_non_sequence_raises(self) -> None: """Non-SEQUENCE type raises ValueError.""" - spec = make_extensible_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_get("RadiusOfCurvature", spec) + generate_sequence_code( + _SEQUENCE_GET_TEMPLATE_NAME, make_nested_mock_spec(), "SemiMajorAxisAccuracy" + ) self.assertIn("not a SEQUENCE", str(ctx.exception)) @@ -110,28 +86,30 @@ class TestGetWithRealSpec(SpecLoadingTestBase): def test_real_bsm_core_data_unsigned(self) -> None: """Real BSMcoreData msgCnt is unsigned.""" - code = generate_sequence_get("BSMcoreData", self.spec) + code = generate_sequence_code(_SEQUENCE_GET_TEMPLATE_NAME, self.spec, "BSMcoreData") self.assertIn("J2735_BSM_CORE_DATA_GET_MSG_CNT(buf)", code) self.assertIn("(uint8_t)", code) def test_real_bsm_core_data_signed(self) -> None: """Real BSMcoreData lat is signed (uses SIGN_EXTEND).""" - code = generate_sequence_get("BSMcoreData", self.spec) + code = generate_sequence_code(_SEQUENCE_GET_TEMPLATE_NAME, self.spec, "BSMcoreData") self.assertIn("J2735_BSM_CORE_DATA_GET_LAT(buf)", code) self.assertIn("J2735_INTERNAL_SIGN_EXTEND", code) def test_real_intersection_reference_id_optional(self) -> None: """Real IntersectionReferenceID region has @pre comment.""" - code = generate_sequence_get("IntersectionReferenceID", self.spec) + code = generate_sequence_code( + _SEQUENCE_GET_TEMPLATE_NAME, self.spec, "IntersectionReferenceID" + ) self.assertIn("J2735_INTERSECTION_REFERENCE_ID_GET_REGION(buf)", code) self.assertIn("@pre J2735_INTERSECTION_REFERENCE_ID_HAS_REGION(buf)", code) def test_real_path_prediction_signed(self) -> None: """Real PathPrediction radiusOfCurve is signed.""" - code = generate_sequence_get("PathPrediction", self.spec) + code = generate_sequence_code(_SEQUENCE_GET_TEMPLATE_NAME, self.spec, "PathPrediction") self.assertIn("J2735_PATH_PREDICTION_GET_RADIUS_OF_CURVE(buf)", code) self.assertIn("J2735_INTERNAL_SIGN_EXTEND", code) diff --git a/tools/tests/c_generator/test_sequence_has_extension.py b/tools/tests/c_generator/test_sequence_has_extension.py index 086a2cd..9a22cf4 100644 --- a/tools/tests/c_generator/test_sequence_has_extension.py +++ b/tools/tests/c_generator/test_sequence_has_extension.py @@ -16,56 +16,30 @@ # SPDX-FileCopyrightText: 2026 Yogev Neumann """Tests for has-extension macro generation. -Tests cover generate_sequence_has_extension function for extensible SEQUENCE types. +Tests cover sequence_has_extension.j2 template for extensible SEQUENCE types. """ from unittest import TestCase -from tools.j2735_c_generator_jinja import ( - create_jinja_env, - get_template, -) -from tools.j2735_spec_constraints import SequenceType -from tools.j2735_spec_parser import J2735Specification from tools.tests.conftest import ( SpecLoadingTestBase, - get_sequence_typedef, + generate_sequence_code, make_extensible_mock_spec, make_nested_mock_spec, ) -_TEMPLATE_NAME = "sequence/sequence_has_extension.j2" - - -def generate_sequence_has_extension(type_name: str, spec: J2735Specification) -> str: - """Generate C #define macro for checking extension bit in a SEQUENCE. - - Only generates output for extensible SEQUENCE types. - - Args: - type_name: Name of the SEQUENCE type (e.g., "PathPrediction"). - spec: The parsed J2735 specification. - - Returns: - C code with #define macro, or empty string if not extensible. - - Raises: - ValueError: If type_name is not found or not a SEQUENCE. - """ - typedef = get_sequence_typedef(type_name, spec) - assert isinstance(typedef.constraint, SequenceType) # Guaranteed by getter, required by Mypy - if not typedef.constraint.is_extensible: - return "" - return get_template(create_jinja_env(), _TEMPLATE_NAME).render(typedef=typedef) +_SEQUENCE_HAS_EXTENSION_TEMPLATE_NAME = "sequence/sequence_has_extension.j2" class TestHasExtensionGeneration(TestCase): - """Tests for generate_sequence_has_extension function.""" + """Tests for sequence_has_extension.j2 template with mock specs.""" def test_extensible_sequence_exact_output(self) -> None: """Extensible SEQUENCE generates exact expected output.""" spec = make_extensible_mock_spec() - code = generate_sequence_has_extension("PathPrediction", spec) + code = generate_sequence_code( + _SEQUENCE_HAS_EXTENSION_TEMPLATE_NAME, spec, "PathPrediction", require_extensible=True + ) expected = ( "/**\n" @@ -80,25 +54,30 @@ def test_extensible_sequence_exact_output(self) -> None: def test_non_extensible_returns_empty(self) -> None: """Non-extensible SEQUENCE returns empty string.""" spec = make_nested_mock_spec() - code = generate_sequence_has_extension("PositionalAccuracy", spec) + code = generate_sequence_code( + _SEQUENCE_HAS_EXTENSION_TEMPLATE_NAME, + spec, + "PositionalAccuracy", + require_extensible=True, + ) self.assertEqual(code, "") def test_not_found_raises(self) -> None: """Unknown type raises ValueError.""" - spec = make_extensible_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_has_extension("UnknownType", spec) + generate_sequence_code( + _SEQUENCE_HAS_EXTENSION_TEMPLATE_NAME, make_extensible_mock_spec(), "UnknownType" + ) self.assertIn("not found", str(ctx.exception)) def test_non_sequence_raises(self) -> None: """Non-SEQUENCE type raises ValueError.""" - spec = make_extensible_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_has_extension("RadiusOfCurvature", spec) + generate_sequence_code( + _SEQUENCE_HAS_EXTENSION_TEMPLATE_NAME, make_extensible_mock_spec(), "Confidence" + ) self.assertIn("not a SEQUENCE", str(ctx.exception)) @@ -108,7 +87,12 @@ class TestHasExtensionWithRealSpec(SpecLoadingTestBase): def test_real_path_prediction(self) -> None: """Real PathPrediction from spec.""" - code = generate_sequence_has_extension("PathPrediction", self.spec) + code = generate_sequence_code( + _SEQUENCE_HAS_EXTENSION_TEMPLATE_NAME, + self.spec, + "PathPrediction", + require_extensible=True, + ) expected = ( "/**\n" @@ -122,6 +106,8 @@ def test_real_path_prediction(self) -> None: def test_real_bsm_core_data_returns_empty(self) -> None: """Real BSMcoreData (non-extensible) returns empty string.""" - code = generate_sequence_has_extension("BSMcoreData", self.spec) + code = generate_sequence_code( + _SEQUENCE_HAS_EXTENSION_TEMPLATE_NAME, self.spec, "BSMcoreData", require_extensible=True + ) self.assertEqual(code, "") diff --git a/tools/tests/c_generator/test_sequence_has_field.py b/tools/tests/c_generator/test_sequence_has_field.py index 95e82b5..eed3d1b 100644 --- a/tools/tests/c_generator/test_sequence_has_field.py +++ b/tools/tests/c_generator/test_sequence_has_field.py @@ -22,48 +22,26 @@ from unittest import TestCase -from tools.j2735_c_generator_jinja import ( - create_jinja_env, - get_template, -) -from tools.j2735_spec_constraints import SequenceType -from tools.j2735_spec_parser import J2735Specification from tools.tests.conftest import ( SpecLoadingTestBase, - get_sequence_typedef, + generate_sequence_code, make_extensible_mock_spec, make_nested_mock_spec, make_optional_mock_spec, ) -_TEMPLATE_NAME = "sequence/sequence_has_field.j2" - - -def generate_sequence_has_field(type_name: str, spec: J2735Specification) -> str: - """Generate C #define macros for checking optional field presence. - - Args: - type_name: Name of the SEQUENCE type. - spec: The parsed J2735 specification. - - Returns: - C code with #define macros, or empty string if no optionals. - - Raises: - ValueError: If type_name is not found or not a SEQUENCE. - """ - typedef = get_sequence_typedef(type_name, spec) - assert isinstance(typedef.constraint, SequenceType) - return get_template(create_jinja_env(), _TEMPLATE_NAME).render(typedef=typedef) +_SEQUENCE_HAS_FIELD_TEMPLATE_NAME = "sequence/sequence_has_field.j2" class TestHasFieldGeneration(TestCase): - """Tests for generate_sequence_has_field function.""" + """Tests for sequence_has_field.j2 template with mock specs.""" def test_sequence_with_optional_field(self) -> None: """SEQUENCE with 1 optional field generates HAS macro.""" spec = make_optional_mock_spec() - code = generate_sequence_has_field("IntersectionReferenceID", spec) + code = generate_sequence_code( + _SEQUENCE_HAS_FIELD_TEMPLATE_NAME, spec, "IntersectionReferenceID" + ) self.assertIn("J2735_INTERSECTION_REFERENCE_ID_HAS_REGION(buf)", code) self.assertIn("J2735_INTERNAL_HAS_FIELD", code) @@ -72,32 +50,32 @@ def test_sequence_with_optional_field(self) -> None: def test_sequence_without_optional_returns_empty(self) -> None: """SEQUENCE with no optional fields returns empty string.""" spec = make_nested_mock_spec() - code = generate_sequence_has_field("PositionalAccuracy", spec) + code = generate_sequence_code(_SEQUENCE_HAS_FIELD_TEMPLATE_NAME, spec, "PositionalAccuracy") self.assertEqual(code, "") def test_extensible_without_optional_returns_empty(self) -> None: """Extensible SEQUENCE with no optional fields returns empty string.""" spec = make_extensible_mock_spec() - code = generate_sequence_has_field("PathPrediction", spec) + code = generate_sequence_code(_SEQUENCE_HAS_FIELD_TEMPLATE_NAME, spec, "PathPrediction") self.assertEqual(code, "") def test_not_found_raises(self) -> None: """Unknown type raises ValueError.""" - spec = make_optional_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_has_field("UnknownType", spec) + generate_sequence_code( + _SEQUENCE_HAS_FIELD_TEMPLATE_NAME, make_optional_mock_spec(), "UnknownType" + ) self.assertIn("not found", str(ctx.exception)) def test_non_sequence_raises(self) -> None: """Non-SEQUENCE type raises ValueError.""" - spec = make_optional_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_has_field("RoadRegulatorID", spec) + generate_sequence_code( + _SEQUENCE_HAS_FIELD_TEMPLATE_NAME, make_optional_mock_spec(), "IntersectionID" + ) self.assertIn("not a SEQUENCE", str(ctx.exception)) @@ -107,19 +85,23 @@ class TestHasFieldWithRealSpec(SpecLoadingTestBase): def test_real_intersection_reference_id(self) -> None: """Real IntersectionReferenceID has HAS_REGION macro.""" - code = generate_sequence_has_field("IntersectionReferenceID", self.spec) + code = generate_sequence_code( + _SEQUENCE_HAS_FIELD_TEMPLATE_NAME, self.spec, "IntersectionReferenceID" + ) self.assertIn("J2735_INTERSECTION_REFERENCE_ID_HAS_REGION(buf)", code) self.assertIn("J2735_INTERNAL_HAS_FIELD", code) def test_real_bsm_core_data_returns_empty(self) -> None: """Real BSMcoreData (no optionals) returns empty string.""" - code = generate_sequence_has_field("BSMcoreData", self.spec) + code = generate_sequence_code(_SEQUENCE_HAS_FIELD_TEMPLATE_NAME, self.spec, "BSMcoreData") self.assertEqual(code, "") def test_real_path_prediction_returns_empty(self) -> None: """Real PathPrediction (no optionals) returns empty string.""" - code = generate_sequence_has_field("PathPrediction", self.spec) + code = generate_sequence_code( + _SEQUENCE_HAS_FIELD_TEMPLATE_NAME, self.spec, "PathPrediction" + ) self.assertEqual(code, "") diff --git a/tools/tests/c_generator/test_sequence_internal_off.py b/tools/tests/c_generator/test_sequence_internal_off.py index 6893611..5986648 100644 --- a/tools/tests/c_generator/test_sequence_internal_off.py +++ b/tools/tests/c_generator/test_sequence_internal_off.py @@ -22,48 +22,24 @@ from unittest import TestCase -from tools.j2735_c_generator_jinja import ( - create_jinja_env, - get_template, -) -from tools.j2735_spec_constraints import SequenceType -from tools.j2735_spec_parser import J2735Specification from tools.tests.conftest import ( SpecLoadingTestBase, - get_sequence_typedef, + generate_sequence_code, make_extensible_mock_spec, make_nested_mock_spec, make_optional_mock_spec, ) -_TEMPLATE_NAME = "sequence/sequence_internal_off.j2" - - -def generate_sequence_off(type_name: str, spec: J2735Specification) -> str: - """Generate C #define macros for field offsets of a SEQUENCE. - - Args: - type_name: Name of the SEQUENCE type. - spec: The parsed J2735 specification. - - Returns: - C code with #define macros for each field. - - Raises: - ValueError: If type_name is not found or not a SEQUENCE. - """ - typedef = get_sequence_typedef(type_name, spec) - assert isinstance(typedef.constraint, SequenceType) - return get_template(create_jinja_env(), _TEMPLATE_NAME).render(typedef=typedef) +_SEQUENCE_OFF_TEMPLATE_NAME = "sequence/sequence_internal_off.j2" class TestOffGeneration(TestCase): - """Tests for generate_sequence_off function.""" + """Tests for sequence_internal_off.j2 template with mock specs.""" def test_fixed_layout_sequence(self) -> None: """SEQUENCE with all required fields uses BW constants.""" spec = make_nested_mock_spec() - code = generate_sequence_off("PositionalAccuracy", spec) + code = generate_sequence_code(_SEQUENCE_OFF_TEMPLATE_NAME, spec, "PositionalAccuracy") # First field uses PREFIX_BITS self.assertIn("J2735_INTERNAL_OFF_POSITIONAL_ACCURACY_SEMI_MAJOR(buf)", code) @@ -75,7 +51,7 @@ def test_fixed_layout_sequence(self) -> None: def test_extensible_sequence(self) -> None: """Extensible SEQUENCE uses PREFIX_BITS and BW constants.""" spec = make_extensible_mock_spec() - code = generate_sequence_off("PathPrediction", spec) + code = generate_sequence_code(_SEQUENCE_OFF_TEMPLATE_NAME, spec, "PathPrediction") self.assertIn("J2735_INTERNAL_OFF_PATH_PREDICTION_RADIUS_OF_CURVE(buf)", code) self.assertIn("J2735_INTERNAL_PREFIX_BITS_PATH_PREDICTION", code) @@ -85,7 +61,7 @@ def test_extensible_sequence(self) -> None: def test_sequence_with_optional_field(self) -> None: """SEQUENCE with optional field uses WIDTH macro for offset chaining.""" spec = make_optional_mock_spec() - code = generate_sequence_off("IntersectionReferenceID", spec) + code = generate_sequence_code(_SEQUENCE_OFF_TEMPLATE_NAME, spec, "IntersectionReferenceID") # First field (optional) uses PREFIX_BITS self.assertIn("J2735_INTERNAL_OFF_INTERSECTION_REFERENCE_ID_REGION(buf)", code) @@ -96,19 +72,19 @@ def test_sequence_with_optional_field(self) -> None: def test_not_found_raises(self) -> None: """Unknown type raises ValueError.""" - spec = make_nested_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_off("UnknownType", spec) + generate_sequence_code( + _SEQUENCE_OFF_TEMPLATE_NAME, make_nested_mock_spec(), "UnknownType" + ) self.assertIn("not found", str(ctx.exception)) def test_non_sequence_raises(self) -> None: """Non-SEQUENCE type raises ValueError.""" - spec = make_extensible_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_off("RadiusOfCurvature", spec) + generate_sequence_code( + _SEQUENCE_OFF_TEMPLATE_NAME, make_nested_mock_spec(), "SemiMinorAxisAccuracy" + ) self.assertIn("not a SEQUENCE", str(ctx.exception)) @@ -118,7 +94,7 @@ class TestOffWithRealSpec(SpecLoadingTestBase): def test_real_bsm_core_data(self) -> None: """Real BSMcoreData has offset macros for all 14 fields.""" - code = generate_sequence_off("BSMcoreData", self.spec) + code = generate_sequence_code(_SEQUENCE_OFF_TEMPLATE_NAME, self.spec, "BSMcoreData") self.assertIn("J2735_INTERNAL_OFF_BSM_CORE_DATA_MSG_CNT(buf)", code) self.assertIn("J2735_INTERNAL_OFF_BSM_CORE_DATA_ID(buf)", code) @@ -127,7 +103,9 @@ def test_real_bsm_core_data(self) -> None: def test_real_intersection_reference_id(self) -> None: """Real IntersectionReferenceID uses WIDTH for optional chaining.""" - code = generate_sequence_off("IntersectionReferenceID", self.spec) + code = generate_sequence_code( + _SEQUENCE_OFF_TEMPLATE_NAME, self.spec, "IntersectionReferenceID" + ) self.assertIn("J2735_INTERNAL_OFF_INTERSECTION_REFERENCE_ID_REGION(buf)", code) self.assertIn("J2735_INTERNAL_OFF_INTERSECTION_REFERENCE_ID_ID(buf)", code) diff --git a/tools/tests/c_generator/test_sequence_internal_opt.py b/tools/tests/c_generator/test_sequence_internal_opt.py index bc6125c..495e90a 100644 --- a/tools/tests/c_generator/test_sequence_internal_opt.py +++ b/tools/tests/c_generator/test_sequence_internal_opt.py @@ -22,48 +22,24 @@ from unittest import TestCase -from tools.j2735_c_generator_jinja import ( - create_jinja_env, - get_template, -) -from tools.j2735_spec_constraints import SequenceType -from tools.j2735_spec_parser import J2735Specification from tools.tests.conftest import ( SpecLoadingTestBase, - get_sequence_typedef, + generate_sequence_code, make_extensible_mock_spec, make_nested_mock_spec, make_optional_mock_spec, ) -_TEMPLATE_NAME = "sequence/sequence_internal_opt.j2" - - -def generate_sequence_opt(type_name: str, spec: J2735Specification) -> str: - """Generate C #define constants for optional field indices of a SEQUENCE. - - Args: - type_name: Name of the SEQUENCE type. - spec: The parsed J2735 specification. - - Returns: - C code with #define constants, or empty string if no optionals. - - Raises: - ValueError: If type_name is not found or not a SEQUENCE. - """ - typedef = get_sequence_typedef(type_name, spec) - assert isinstance(typedef.constraint, SequenceType) - return get_template(create_jinja_env(), _TEMPLATE_NAME).render(typedef=typedef) +_SEQUENCE_OPT_TEMPLATE_NAME = "sequence/sequence_internal_opt.j2" class TestOptGeneration(TestCase): - """Tests for generate_sequence_opt function.""" + """Tests for sequence_internal_opt.j2 template with mock specs.""" def test_sequence_with_optional_field(self) -> None: """SEQUENCE with 1 optional field generates index constant.""" spec = make_optional_mock_spec() - code = generate_sequence_opt("IntersectionReferenceID", spec) + code = generate_sequence_code(_SEQUENCE_OPT_TEMPLATE_NAME, spec, "IntersectionReferenceID") self.assertIn("J2735_INTERNAL_OPT_INTERSECTION_REFERENCE_ID_REGION", code) self.assertIn("0U", code) @@ -72,32 +48,32 @@ def test_sequence_with_optional_field(self) -> None: def test_sequence_without_optional_returns_empty(self) -> None: """SEQUENCE with no optional fields returns empty string.""" spec = make_nested_mock_spec() - code = generate_sequence_opt("PositionalAccuracy", spec) + code = generate_sequence_code(_SEQUENCE_OPT_TEMPLATE_NAME, spec, "PositionalAccuracy") self.assertEqual(code, "") def test_extensible_without_optional_returns_empty(self) -> None: """Extensible SEQUENCE with no optional fields returns empty string.""" spec = make_extensible_mock_spec() - code = generate_sequence_opt("PathPrediction", spec) + code = generate_sequence_code(_SEQUENCE_OPT_TEMPLATE_NAME, spec, "PathPrediction") self.assertEqual(code, "") def test_not_found_raises(self) -> None: """Unknown type raises ValueError.""" - spec = make_optional_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_opt("UnknownType", spec) + generate_sequence_code( + _SEQUENCE_OPT_TEMPLATE_NAME, make_optional_mock_spec(), "UnknownType" + ) self.assertIn("not found", str(ctx.exception)) def test_non_sequence_raises(self) -> None: """Non-SEQUENCE type raises ValueError.""" - spec = make_optional_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_opt("RoadRegulatorID", spec) + generate_sequence_code( + _SEQUENCE_OPT_TEMPLATE_NAME, make_optional_mock_spec(), "RoadRegulatorID" + ) self.assertIn("not a SEQUENCE", str(ctx.exception)) @@ -107,19 +83,21 @@ class TestOptWithRealSpec(SpecLoadingTestBase): def test_real_intersection_reference_id(self) -> None: """Real IntersectionReferenceID has 1 optional field (region).""" - code = generate_sequence_opt("IntersectionReferenceID", self.spec) + code = generate_sequence_code( + _SEQUENCE_OPT_TEMPLATE_NAME, self.spec, "IntersectionReferenceID" + ) self.assertIn("J2735_INTERNAL_OPT_INTERSECTION_REFERENCE_ID_REGION", code) self.assertIn("0U", code) def test_real_bsm_core_data_returns_empty(self) -> None: """Real BSMcoreData (no optionals) returns empty string.""" - code = generate_sequence_opt("BSMcoreData", self.spec) + code = generate_sequence_code(_SEQUENCE_OPT_TEMPLATE_NAME, self.spec, "BSMcoreData") self.assertEqual(code, "") def test_real_path_prediction_returns_empty(self) -> None: """Real PathPrediction (no optionals) returns empty string.""" - code = generate_sequence_opt("PathPrediction", self.spec) + code = generate_sequence_code(_SEQUENCE_OPT_TEMPLATE_NAME, self.spec, "PathPrediction") self.assertEqual(code, "") diff --git a/tools/tests/c_generator/test_sequence_internal_prefix_bits.py b/tools/tests/c_generator/test_sequence_internal_prefix_bits.py index 8353ccd..3271780 100644 --- a/tools/tests/c_generator/test_sequence_internal_prefix_bits.py +++ b/tools/tests/c_generator/test_sequence_internal_prefix_bits.py @@ -22,48 +22,26 @@ from unittest import TestCase -from tools.j2735_c_generator_jinja import ( - create_jinja_env, - get_template, -) -from tools.j2735_spec_constraints import SequenceType -from tools.j2735_spec_parser import J2735Specification from tools.tests.conftest import ( SpecLoadingTestBase, - get_sequence_typedef, + generate_sequence_code, make_extensible_mock_spec, make_nested_mock_spec, make_optional_mock_spec, ) -_TEMPLATE_NAME = "sequence/sequence_internal_prefix_bits.j2" - - -def generate_sequence_prefix_bits(type_name: str, spec: J2735Specification) -> str: - """Generate C #define constant for prefix bits of a SEQUENCE. - - Args: - type_name: Name of the SEQUENCE type. - spec: The parsed J2735 specification. - - Returns: - C code with #define constant. - - Raises: - ValueError: If type_name is not found or not a SEQUENCE. - """ - typedef = get_sequence_typedef(type_name, spec) - assert isinstance(typedef.constraint, SequenceType) - return get_template(create_jinja_env(), _TEMPLATE_NAME).render(typedef=typedef) +_SEQUENCE_PREFIX_BITS_TEMPLATE_NAME = "sequence/sequence_internal_prefix_bits.j2" class TestPrefixBitsGeneration(TestCase): - """Tests for generate_sequence_prefix_bits function.""" + """Tests for sequence_internal_prefix_bits.j2 template with mock specs.""" def test_non_extensible_no_optional(self) -> None: """Non-extensible SEQUENCE with no optionals has 0 prefix bits.""" spec = make_nested_mock_spec() - code = generate_sequence_prefix_bits("PositionalAccuracy", spec) + code = generate_sequence_code( + _SEQUENCE_PREFIX_BITS_TEMPLATE_NAME, spec, "PositionalAccuracy" + ) self.assertIn("J2735_INTERNAL_PREFIX_BITS_POSITIONAL_ACCURACY", code) self.assertIn("0U + J2735_INTERNAL_PREAMBLE_BITS(0U)", code) @@ -72,7 +50,7 @@ def test_non_extensible_no_optional(self) -> None: def test_extensible_no_optional(self) -> None: """Extensible SEQUENCE with no optionals has 1 prefix bit.""" spec = make_extensible_mock_spec() - code = generate_sequence_prefix_bits("PathPrediction", spec) + code = generate_sequence_code(_SEQUENCE_PREFIX_BITS_TEMPLATE_NAME, spec, "PathPrediction") self.assertIn("J2735_INTERNAL_PREFIX_BITS_PATH_PREDICTION", code) self.assertIn("1U + J2735_INTERNAL_PREAMBLE_BITS(0U)", code) @@ -81,7 +59,9 @@ def test_extensible_no_optional(self) -> None: def test_non_extensible_with_optional(self) -> None: """Non-extensible SEQUENCE with 1 optional has 1 prefix bit.""" spec = make_optional_mock_spec() - code = generate_sequence_prefix_bits("IntersectionReferenceID", spec) + code = generate_sequence_code( + _SEQUENCE_PREFIX_BITS_TEMPLATE_NAME, spec, "IntersectionReferenceID" + ) self.assertIn("J2735_INTERNAL_PREFIX_BITS_INTERSECTION_REFERENCE_ID", code) self.assertIn("0U + J2735_INTERNAL_PREAMBLE_BITS(1U)", code) @@ -89,19 +69,21 @@ def test_non_extensible_with_optional(self) -> None: def test_not_found_raises(self) -> None: """Unknown type raises ValueError.""" - spec = make_nested_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_prefix_bits("UnknownType", spec) + generate_sequence_code( + _SEQUENCE_PREFIX_BITS_TEMPLATE_NAME, make_nested_mock_spec(), "UnknownType" + ) self.assertIn("not found", str(ctx.exception)) def test_non_sequence_raises(self) -> None: """Non-SEQUENCE type raises ValueError.""" - spec = make_extensible_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_prefix_bits("RadiusOfCurvature", spec) + generate_sequence_code( + _SEQUENCE_PREFIX_BITS_TEMPLATE_NAME, + make_nested_mock_spec(), + "SemiMajorAxisOrientation", + ) self.assertIn("not a SEQUENCE", str(ctx.exception)) @@ -111,21 +93,25 @@ class TestPrefixBitsWithRealSpec(SpecLoadingTestBase): def test_real_bsm_core_data(self) -> None: """Real BSMcoreData (non-extensible, no optionals) has 0 prefix bits.""" - code = generate_sequence_prefix_bits("BSMcoreData", self.spec) + code = generate_sequence_code(_SEQUENCE_PREFIX_BITS_TEMPLATE_NAME, self.spec, "BSMcoreData") self.assertIn("J2735_INTERNAL_PREFIX_BITS_BSM_CORE_DATA", code) self.assertIn("0 ext + 0 opt = 0 bits", code) def test_real_path_prediction(self) -> None: """Real PathPrediction (extensible, no optionals) has 1 prefix bit.""" - code = generate_sequence_prefix_bits("PathPrediction", self.spec) + code = generate_sequence_code( + _SEQUENCE_PREFIX_BITS_TEMPLATE_NAME, self.spec, "PathPrediction" + ) self.assertIn("J2735_INTERNAL_PREFIX_BITS_PATH_PREDICTION", code) self.assertIn("1 ext + 0 opt = 1 bit", code) def test_real_intersection_reference_id(self) -> None: """Real IntersectionReferenceID (non-extensible, 1 optional) has 1 prefix bit.""" - code = generate_sequence_prefix_bits("IntersectionReferenceID", self.spec) + code = generate_sequence_code( + _SEQUENCE_PREFIX_BITS_TEMPLATE_NAME, self.spec, "IntersectionReferenceID" + ) self.assertIn("J2735_INTERNAL_PREFIX_BITS_INTERSECTION_REFERENCE_ID", code) self.assertIn("0 ext + 1 opt = 1 bit", code) diff --git a/tools/tests/c_generator/test_sequence_internal_width.py b/tools/tests/c_generator/test_sequence_internal_width.py index 0e8c928..8c0c59a 100644 --- a/tools/tests/c_generator/test_sequence_internal_width.py +++ b/tools/tests/c_generator/test_sequence_internal_width.py @@ -22,48 +22,26 @@ from unittest import TestCase -from tools.j2735_c_generator_jinja import ( - create_jinja_env, - get_template, -) -from tools.j2735_spec_constraints import SequenceType -from tools.j2735_spec_parser import J2735Specification from tools.tests.conftest import ( SpecLoadingTestBase, - get_sequence_typedef, + generate_sequence_code, make_extensible_mock_spec, make_nested_mock_spec, make_optional_mock_spec, ) -_TEMPLATE_NAME = "sequence/sequence_internal_width.j2" - - -def generate_sequence_width(type_name: str, spec: J2735Specification) -> str: - """Generate C #define macros for optional field widths of a SEQUENCE. - - Args: - type_name: Name of the SEQUENCE type. - spec: The parsed J2735 specification. - - Returns: - C code with #define macros, or empty string if no optionals. - - Raises: - ValueError: If type_name is not found or not a SEQUENCE. - """ - typedef = get_sequence_typedef(type_name, spec) - assert isinstance(typedef.constraint, SequenceType) - return get_template(create_jinja_env(), _TEMPLATE_NAME).render(typedef=typedef) +_SEQUENCE_WIDTH_TEMPLATE_NAME = "sequence/sequence_internal_width.j2" class TestWidthGeneration(TestCase): - """Tests for generate_sequence_width function.""" + """Tests for sequence_internal_width.j2 template with mock specs.""" def test_sequence_with_optional_field(self) -> None: """SEQUENCE with 1 optional field generates width macro.""" spec = make_optional_mock_spec() - code = generate_sequence_width("IntersectionReferenceID", spec) + code = generate_sequence_code( + _SEQUENCE_WIDTH_TEMPLATE_NAME, spec, "IntersectionReferenceID" + ) self.assertIn("J2735_INTERNAL_WIDTH_INTERSECTION_REFERENCE_ID_REGION", code) self.assertIn("J2735_INTERSECTION_REFERENCE_ID_HAS_REGION(buf)", code) @@ -73,32 +51,32 @@ def test_sequence_with_optional_field(self) -> None: def test_sequence_without_optional_returns_empty(self) -> None: """SEQUENCE with no optional fields returns empty string.""" spec = make_nested_mock_spec() - code = generate_sequence_width("PositionalAccuracy", spec) + code = generate_sequence_code(_SEQUENCE_WIDTH_TEMPLATE_NAME, spec, "PositionalAccuracy") self.assertEqual(code, "") def test_extensible_without_optional_returns_empty(self) -> None: """Extensible SEQUENCE with no optional fields returns empty string.""" spec = make_extensible_mock_spec() - code = generate_sequence_width("PathPrediction", spec) + code = generate_sequence_code(_SEQUENCE_WIDTH_TEMPLATE_NAME, spec, "PathPrediction") self.assertEqual(code, "") def test_not_found_raises(self) -> None: """Unknown type raises ValueError.""" - spec = make_optional_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_width("UnknownType", spec) + generate_sequence_code( + _SEQUENCE_WIDTH_TEMPLATE_NAME, make_optional_mock_spec(), "UnknownType" + ) self.assertIn("not found", str(ctx.exception)) def test_non_sequence_raises(self) -> None: """Non-SEQUENCE type raises ValueError.""" - spec = make_optional_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_width("RoadRegulatorID", spec) + generate_sequence_code( + _SEQUENCE_WIDTH_TEMPLATE_NAME, make_extensible_mock_spec(), "RadiusOfCurvature" + ) self.assertIn("not a SEQUENCE", str(ctx.exception)) @@ -108,7 +86,9 @@ class TestWidthWithRealSpec(SpecLoadingTestBase): def test_real_intersection_reference_id(self) -> None: """Real IntersectionReferenceID has width macro for region.""" - code = generate_sequence_width("IntersectionReferenceID", self.spec) + code = generate_sequence_code( + _SEQUENCE_WIDTH_TEMPLATE_NAME, self.spec, "IntersectionReferenceID" + ) self.assertIn("J2735_INTERNAL_WIDTH_INTERSECTION_REFERENCE_ID_REGION", code) self.assertIn("J2735_INTERSECTION_REFERENCE_ID_HAS_REGION(buf)", code) @@ -116,12 +96,12 @@ def test_real_intersection_reference_id(self) -> None: def test_real_bsm_core_data_returns_empty(self) -> None: """Real BSMcoreData (no optionals) returns empty string.""" - code = generate_sequence_width("BSMcoreData", self.spec) + code = generate_sequence_code(_SEQUENCE_WIDTH_TEMPLATE_NAME, self.spec, "BSMcoreData") self.assertEqual(code, "") def test_real_path_prediction_returns_empty(self) -> None: """Real PathPrediction (no optionals) returns empty string.""" - code = generate_sequence_width("PathPrediction", self.spec) + code = generate_sequence_code(_SEQUENCE_WIDTH_TEMPLATE_NAME, self.spec, "PathPrediction") self.assertEqual(code, "") diff --git a/tools/tests/c_generator/test_sequence_root_size.py b/tools/tests/c_generator/test_sequence_root_size.py index a7c603b..5eb99e9 100644 --- a/tools/tests/c_generator/test_sequence_root_size.py +++ b/tools/tests/c_generator/test_sequence_root_size.py @@ -16,67 +16,34 @@ # SPDX-FileCopyrightText: 2026 Yogev Neumann """Tests for root size constant generation. -Tests cover generate_sequence_root_size function for extensible SEQUENCE types. +Tests cover sequence_internal_root_size_bits.j2 template for extensible SEQUENCE types. """ from unittest import TestCase -from tools.j2735_c_generator_jinja import ( - create_jinja_env, - get_template, -) -from tools.j2735_spec_constraints import SequenceType -from tools.j2735_spec_parser import J2735Specification from tools.tests.conftest import ( SpecLoadingTestBase, - get_sequence_typedef, + generate_sequence_code, make_extensible_mock_spec, make_nested_mock_spec, ) -_TEMPLATE_NAME = "sequence/sequence_internal_root_size_bits.j2" - - -def generate_sequence_root_size(type_name: str, spec: J2735Specification) -> str: - """Generate C #define constant for root size of an extensible SEQUENCE. - - Only generates output for extensible SEQUENCE types with fixed-width - root components (no OPTIONAL fields). - - Args: - type_name: Name of the SEQUENCE type (e.g., "PathPrediction"). - spec: The parsed J2735 specification. - - Returns: - C code with #define constant, or empty string if not applicable. - - Raises: - ValueError: If type_name is not found or not a SEQUENCE. - """ - typedef = get_sequence_typedef(type_name, spec) - assert isinstance(typedef.constraint, SequenceType) # Guaranteed by getter, required by Mypy - if not typedef.constraint.is_extensible or typedef.constraint.root_uper_bit_width is None: - return "" - template = get_template(create_jinja_env(), _TEMPLATE_NAME) - - # Build list of field type names for symbolic expression - field_type_names = [ - field.type_name for field in typedef.constraint.fields if not field.is_optional - ] - - return template.render( - field_type_names=field_type_names, - typedef=typedef, - ) +_SEQUENCE_ROOT_SIZE_BITS_TEMPLATE_NAME = "sequence/sequence_internal_root_size_bits.j2" class TestRootSizeGeneration(TestCase): - """Tests for generate_sequence_root_size function.""" + """Tests for sequence_internal_root_size_bits.j2 template with mock specs.""" def test_extensible_sequence_exact_output(self) -> None: """Extensible SEQUENCE generates expected macro.""" - spec = make_extensible_mock_spec() - code = generate_sequence_root_size("PathPrediction", spec) + code = generate_sequence_code( + _SEQUENCE_ROOT_SIZE_BITS_TEMPLATE_NAME, + make_extensible_mock_spec(), + "PathPrediction", + require_extensible=True, + require_fixed_root=True, + set_field_type_names=True, + ) # PathPrediction: 1 preamble + 16 radius + 8 confidence = 25 bits # Uses symbolic expression for clarity (clang-format handles line breaking) @@ -89,7 +56,14 @@ def test_extensible_sequence_exact_output(self) -> None: def test_non_extensible_returns_empty(self) -> None: """Non-extensible SEQUENCE returns empty string.""" spec = make_nested_mock_spec() - code = generate_sequence_root_size("PositionalAccuracy", spec) + code = generate_sequence_code( + _SEQUENCE_ROOT_SIZE_BITS_TEMPLATE_NAME, + spec, + "PositionalAccuracy", + require_extensible=True, + require_fixed_root=True, + set_field_type_names=True, + ) self.assertEqual(code, "") @@ -98,7 +72,7 @@ def test_not_found_raises(self) -> None: spec = make_extensible_mock_spec() with self.assertRaises(ValueError) as ctx: - generate_sequence_root_size("UnknownType", spec) + generate_sequence_code(_SEQUENCE_ROOT_SIZE_BITS_TEMPLATE_NAME, spec, "UnknownType") self.assertIn("not found", str(ctx.exception)) @@ -107,7 +81,7 @@ def test_non_sequence_raises(self) -> None: spec = make_extensible_mock_spec() with self.assertRaises(ValueError) as ctx: - generate_sequence_root_size("RadiusOfCurvature", spec) + generate_sequence_code(_SEQUENCE_ROOT_SIZE_BITS_TEMPLATE_NAME, spec, "Confidence") self.assertIn("not a SEQUENCE", str(ctx.exception)) @@ -117,7 +91,14 @@ class TestRootSizeWithRealSpec(SpecLoadingTestBase): def test_real_path_prediction(self) -> None: """Real PathPrediction from spec.""" - code = generate_sequence_root_size("PathPrediction", self.spec) + code = generate_sequence_code( + _SEQUENCE_ROOT_SIZE_BITS_TEMPLATE_NAME, + self.spec, + "PathPrediction", + require_extensible=True, + require_fixed_root=True, + set_field_type_names=True, + ) # Uses symbolic expression for clarity (clang-format handles line breaking) self.assertIn("#define J2735_INTERNAL_ROOT_SIZE_BITS_PATH_PREDICTION", code) @@ -128,6 +109,13 @@ def test_real_path_prediction(self) -> None: def test_real_bsm_core_data_returns_empty(self) -> None: """Real BSMcoreData (non-extensible) returns empty string.""" - code = generate_sequence_root_size("BSMcoreData", self.spec) + code = generate_sequence_code( + _SEQUENCE_ROOT_SIZE_BITS_TEMPLATE_NAME, + self.spec, + "BSMcoreData", + require_extensible=True, + require_fixed_root=True, + set_field_type_names=True, + ) self.assertEqual(code, "") diff --git a/tools/tests/c_generator/test_sequence_size_func.py b/tools/tests/c_generator/test_sequence_size_func.py index 46a8720..f12a222 100644 --- a/tools/tests/c_generator/test_sequence_size_func.py +++ b/tools/tests/c_generator/test_sequence_size_func.py @@ -16,57 +16,35 @@ # SPDX-FileCopyrightText: 2026 Yogev Neumann """Tests for size function generation. -Tests cover generate_sequence_size_func function for extensible SEQUENCE types. +Tests cover sequence_size.j2 template for extensible SEQUENCE types. """ from unittest import TestCase -from tools.j2735_c_generator_jinja import ( - create_jinja_env, - get_template, -) -from tools.j2735_spec_constraints import SequenceType -from tools.j2735_spec_parser import J2735Specification from tools.tests.conftest import ( SpecLoadingTestBase, - get_sequence_typedef, + generate_sequence_code, make_extensible_mock_spec, make_nested_mock_spec, + make_optional_mock_spec, ) -_TEMPLATE_NAME = "sequence/sequence_size.j2" - - -def generate_sequence_size_func(type_name: str, spec: J2735Specification) -> str: - """Generate C inline function for calculating total size of a SEQUENCE. - - Only generates output for extensible SEQUENCE types with fixed-width - root components (no OPTIONAL fields). - - Args: - type_name: Name of the SEQUENCE type (e.g., "PathPrediction"). - spec: The parsed J2735 specification. - - Returns: - C code with inline function, or empty string if not applicable. - - Raises: - ValueError: If type_name is not found or not a SEQUENCE. - """ - typedef = get_sequence_typedef(type_name, spec) - assert isinstance(typedef.constraint, SequenceType) # Guaranteed by getter, required by Mypy - if not typedef.constraint.is_extensible or typedef.constraint.root_uper_bit_width is None: - return "" - return get_template(create_jinja_env(), _TEMPLATE_NAME).render(typedef=typedef) +_SEQUENCE_SIZE_TEMPLATE_NAME = "sequence/sequence_size.j2" class TestSizeFuncGeneration(TestCase): - """Tests for generate_sequence_size_func function.""" + """Tests for sequence_size.j2 template with mock specs.""" def test_extensible_sequence_function_signature(self) -> None: """Extensible SEQUENCE generates correct function signature.""" spec = make_extensible_mock_spec() - code = generate_sequence_size_func("PathPrediction", spec) + code = generate_sequence_code( + _SEQUENCE_SIZE_TEMPLATE_NAME, + spec, + "PathPrediction", + require_extensible=True, + require_fixed_root=True, + ) self.assertIn("static inline int j2735_inline_path_prediction_size(", code) self.assertIn("uint8_t const *const buf", code) @@ -75,28 +53,52 @@ def test_extensible_sequence_function_signature(self) -> None: def test_extensible_sequence_uses_root_size_constant(self) -> None: """Generated function uses ROOT_SIZE_BITS constant.""" spec = make_extensible_mock_spec() - code = generate_sequence_size_func("PathPrediction", spec) + code = generate_sequence_code( + _SEQUENCE_SIZE_TEMPLATE_NAME, + spec, + "PathPrediction", + require_extensible=True, + require_fixed_root=True, + ) self.assertIn("J2735_INTERNAL_ROOT_SIZE_BITS_PATH_PREDICTION", code) def test_extensible_sequence_uses_has_extension_macro(self) -> None: """Generated function uses HAS_EXTENSION macro.""" spec = make_extensible_mock_spec() - code = generate_sequence_size_func("PathPrediction", spec) + code = generate_sequence_code( + _SEQUENCE_SIZE_TEMPLATE_NAME, + spec, + "PathPrediction", + require_extensible=True, + require_fixed_root=True, + ) self.assertIn("J2735_PATH_PREDICTION_HAS_EXTENSION(buf)", code) def test_extensible_sequence_calls_skip_extensions(self) -> None: """Generated function calls j2735_internal_inline_skip_extensions.""" spec = make_extensible_mock_spec() - code = generate_sequence_size_func("PathPrediction", spec) + code = generate_sequence_code( + _SEQUENCE_SIZE_TEMPLATE_NAME, + spec, + "PathPrediction", + require_extensible=True, + require_fixed_root=True, + ) self.assertIn("j2735_internal_inline_skip_extensions(", code) def test_extensible_sequence_has_doxygen_comment(self) -> None: """Generated function has Doxygen documentation.""" spec = make_extensible_mock_spec() - code = generate_sequence_size_func("PathPrediction", spec) + code = generate_sequence_code( + _SEQUENCE_SIZE_TEMPLATE_NAME, + spec, + "PathPrediction", + require_extensible=True, + require_fixed_root=True, + ) self.assertIn("@brief", code) self.assertIn("@param[in] buf", code) @@ -105,26 +107,31 @@ def test_extensible_sequence_has_doxygen_comment(self) -> None: def test_non_extensible_returns_empty(self) -> None: """Non-extensible SEQUENCE returns empty string.""" - spec = make_nested_mock_spec() - code = generate_sequence_size_func("PositionalAccuracy", spec) + code = generate_sequence_code( + _SEQUENCE_SIZE_TEMPLATE_NAME, + make_optional_mock_spec(), + "IntersectionReferenceID", + require_extensible=True, + require_fixed_root=True, + ) self.assertEqual(code, "") def test_not_found_raises(self) -> None: """Unknown type raises ValueError.""" - spec = make_extensible_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_size_func("UnknownType", spec) + generate_sequence_code( + _SEQUENCE_SIZE_TEMPLATE_NAME, make_extensible_mock_spec(), "UnknownType" + ) self.assertIn("not found", str(ctx.exception)) def test_non_sequence_raises(self) -> None: """Non-SEQUENCE type raises ValueError.""" - spec = make_extensible_mock_spec() - with self.assertRaises(ValueError) as ctx: - generate_sequence_size_func("RadiusOfCurvature", spec) + generate_sequence_code( + _SEQUENCE_SIZE_TEMPLATE_NAME, make_nested_mock_spec(), "SemiMinorAxisAccuracy" + ) self.assertIn("not a SEQUENCE", str(ctx.exception)) @@ -132,21 +139,39 @@ def test_non_sequence_raises(self) -> None: class TestSizeFuncWithRealSpec(SpecLoadingTestBase): """Tests using the real J2735 specification file.""" - def test_real_path_prediction_function_name(self) -> None: - """Real PathPrediction generates correct function name.""" - code = generate_sequence_size_func("PathPrediction", self.spec) - - self.assertIn("j2735_inline_path_prediction_size", code) - - def test_real_path_prediction_root_size(self) -> None: - """Real PathPrediction uses correct root size constant.""" - code = generate_sequence_size_func("PathPrediction", self.spec) - - # Should reference 25-bit root size - self.assertIn("J2735_INTERNAL_ROOT_SIZE_BITS_PATH_PREDICTION", code) - - def test_real_bsm_core_data_returns_empty(self) -> None: - """Real BSMcoreData (non-extensible) returns empty string.""" - code = generate_sequence_size_func("BSMcoreData", self.spec) + def test_real_pivot_point_description_function_name(self) -> None: + """Real PivotPointDescription generates correct function name.""" + code = generate_sequence_code( + _SEQUENCE_SIZE_TEMPLATE_NAME, + self.spec, + "PivotPointDescription", + require_extensible=True, + require_fixed_root=True, + ) + + self.assertIn("j2735_inline_pivot_point_description_size", code) + + def test_real_pivot_point_description_root_size(self) -> None: + """Real PivotPointDescription uses correct root size constant.""" + code = generate_sequence_code( + _SEQUENCE_SIZE_TEMPLATE_NAME, + self.spec, + "PivotPointDescription", + require_extensible=True, + require_fixed_root=True, + ) + + # Should reference 28-bit root size + self.assertIn("J2735_INTERNAL_ROOT_SIZE_BITS_PIVOT_POINT_DESCRIPTION", code) + + def test_real_positional_accuracy_returns_empty(self) -> None: + """Real PositionalAccuracy (non-extensible) returns empty string.""" + code = generate_sequence_code( + _SEQUENCE_SIZE_TEMPLATE_NAME, + self.spec, + "PositionalAccuracy", + require_extensible=True, + require_fixed_root=True, + ) self.assertEqual(code, "") diff --git a/tools/tests/conftest.py b/tools/tests/conftest.py index af00140..43d5d6a 100644 --- a/tools/tests/conftest.py +++ b/tools/tests/conftest.py @@ -54,7 +54,7 @@ # BIT STRING Data Element types that have no UPER extension marker on the wire. # These types take a different template code path than extensible types: no -# extension bit, no nsnnwn length field, and SIZE == ROOT_SIZE (not 1+ROOT_SIZE). +# extension bit, no nsnnwn length field, and SIZE == ROOT_SIZE_BITS (not 1+ROOT_SIZE_BITS). # Each tuple is (ASN.1 type name, C macro prefix). NON_EXTENSIBLE_BITSTRING_TYPES: list[tuple[str, str]] = [ ("LaneDirection", "LANE_DIRECTION"), @@ -661,6 +661,48 @@ def generate_bitstring_code(template_path: str, spec: J2735Specification, type_n return get_template(env, template_path).render(typedef=typedef) +def generate_sequence_code( # pylint: disable=too-many-arguments + template_path: str, + spec: J2735Specification, + type_name: str, + *, + require_extensible: bool = False, + require_fixed_root: bool = False, + set_field_type_names: bool = False, +) -> str: + """Generate SEQUENCE C code for a given template. + + Args: + template_path: Path to the Jinja2 template for SEQUENCE code generation. + spec: The parsed J2735 specification. + type_name: Name of the SEQUENCE type (e.g., "BSMcoreData"). + require_extensible: Return ``""`` if the SEQUENCE is not extensible. + require_fixed_root: Return ``""`` if ``root_uper_bit_width`` is ``None``. + set_field_type_names: If ``True``, include ``field_type_names`` in the template context. + + Returns: + C code from the rendered template, or ``""`` if guards not met. + + Raises: + ValueError: If type_name is not found or not a SEQUENCE. + jinja2.TemplateNotFound: If template_path does not exist. + """ + typedef = get_sequence_typedef(type_name, spec) # Note, can raise ValueError + if not isinstance(typedef.constraint, SequenceType): + raise TypeError(f"Type '{type_name}' is not constrained by a SequenceType.") + if require_extensible and not typedef.constraint.is_extensible: + return "" + if require_fixed_root and typedef.constraint.root_uper_bit_width is None: + return "" + env = create_jinja_env() + context: dict[str, object] = {"typedef": typedef} + if set_field_type_names: + context["field_type_names"] = [ + field.type_name for field in typedef.constraint.fields if not field.is_optional + ] + return get_template(env, template_path).render(**context) + + def get_sequence_typedef(type_name: str, spec: J2735Specification) -> ASN1TypeDefinition: """Lookup and validate a SEQUENCE type from the specification. diff --git a/tools/tests/spec/test_properties.py b/tools/tests/spec/test_properties.py index 8e06cf5..b42edfe 100644 --- a/tools/tests/spec/test_properties.py +++ b/tools/tests/spec/test_properties.py @@ -353,8 +353,8 @@ def test_optional_field_means_none_width(self, widths: list[int], data: st.DataO max_size=10, ), ) - def test_extensible_sequence_has_none_width(self, widths: list[int]) -> None: - """Extensible SEQUENCE always has None bit-width.""" + def test_extensible_sequence_has_root_field_sum(self, widths: list[int]) -> None: + """Extensible SEQUENCE returns root field sum (not None).""" fields = tuple( SequenceField( name=f"field{i}", @@ -367,7 +367,7 @@ def test_extensible_sequence_has_none_width(self, widths: list[int]) -> None: for i, w in enumerate(widths) ) constraint = SequenceType(fields=fields, is_extensible=True) - self.assertIsNone(constraint.uper_bit_width) + self.assertEqual(constraint.uper_bit_width, sum(widths)) @given( optional_mask=st.lists( @@ -443,10 +443,10 @@ def test_empty_sequence_zero_width(self) -> None: seq = SequenceType(fields=(), is_extensible=False) self.assertEqual(seq.uper_bit_width, 0) - def test_empty_extensible_sequence_none_width(self) -> None: - """Empty extensible SEQUENCE has None bit-width.""" + def test_empty_extensible_sequence_zero_width(self) -> None: + """Empty extensible SEQUENCE has 0 bit-width (no fields).""" seq = SequenceType(fields=(), is_extensible=True) - self.assertIsNone(seq.uper_bit_width) + self.assertEqual(seq.uper_bit_width, 0) def test_preamble_bits_many_optionals(self) -> None: """Preamble with many OPTIONAL fields."""