From 26a4f828b76a677d0b01ff917371d4ceb97bbde1 Mon Sep 17 00:00:00 2001 From: ZhouBox Date: Fri, 13 Nov 2026 11:03:35 +0800 Subject: [PATCH] fix(driver): accept UINT64 write values for numeric tags Sparkplug B encodes UInt64 metrics as an unsigned 64-bit value, which cannot be represented by an INT64 write value. Accept NEU_TYPE_UINT64 writes for numeric tags, evaluate the range with the unsigned value, and extend cal_decimal and float conversion accordingly. INT64 write values keep their signed semantics. --- src/adapter/driver/driver.c | 30 ++++++++++++++++++++++-------- tests/ut/driver_auto_test.cc | 2 ++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/adapter/driver/driver.c b/src/adapter/driver/driver.c index 12ba83170..56f4c294e 100644 --- a/src/adapter/driver/driver.c +++ b/src/adapter/driver/driver.c @@ -1312,9 +1312,14 @@ static void fix_value(neu_datatag_t *tag, neu_type_e value_type, static void cal_decimal(neu_type_e tag_type, neu_type_e value_type, neu_value_u *value, double decimal, double bias) { - long double result = value_type == NEU_TYPE_INT64 - ? (long double) value->i64 - : (long double) value->d64; + long double result; + if (value_type == NEU_TYPE_INT64) { + result = (long double) value->i64; + } else if (value_type == NEU_TYPE_UINT64) { + result = (long double) value->u64; + } else { + result = (long double) value->d64; + } result -= (long double) bias; if (decimal != 0) { result /= (long double) decimal; @@ -1477,7 +1482,7 @@ static int check_write_value(neu_type_e tag_type, int64_t value, double value_d, return valid ? NEU_ERR_SUCCESS : NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH; } } - if (write_type != NEU_TYPE_INT64 && + if (write_type != NEU_TYPE_INT64 && write_type != NEU_TYPE_UINT64 && (write_type != NEU_TYPE_DOUBLE || (integer && decimal == 0 && bias == 0))) { return NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH; @@ -1486,8 +1491,14 @@ static int check_write_value(neu_type_e tag_type, int64_t value, double value_d, (!isfinite(decimal) || !isfinite(bias))) { return NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE; } - long double result = write_type == NEU_TYPE_INT64 ? (long double) value - : (long double) value_d; + long double result; + if (write_type == NEU_TYPE_INT64) { + result = (long double) value; + } else if (write_type == NEU_TYPE_UINT64) { + result = (long double) (uint64_t) value; + } else { + result = (long double) value_d; + } result -= (long double) bias; if (decimal != 0) { result /= (long double) decimal; @@ -1571,8 +1582,11 @@ static int prepare_write_tag(neu_adapter_driver_t *driver, group_t *group, cal_decimal(tag->type, value->type, &value->value, tag->decimal, tag->bias); } else if ((tag->type == NEU_TYPE_FLOAT || tag->type == NEU_TYPE_DOUBLE) && - value->type == NEU_TYPE_INT64) { - value->value.d64 = (double) value->value.i64; + (value->type == NEU_TYPE_INT64 || + value->type == NEU_TYPE_UINT64)) { + value->value.d64 = value->type == NEU_TYPE_INT64 + ? (double) value->value.i64 + : (double) value->value.u64; } if (tag->type == NEU_TYPE_FLOAT || tag->type == NEU_TYPE_DOUBLE) { value->type = NEU_TYPE_DOUBLE; diff --git a/tests/ut/driver_auto_test.cc b/tests/ut/driver_auto_test.cc index 4b0a69142..73909140b 100644 --- a/tests/ut/driver_auto_test.cc +++ b/tests/ut/driver_auto_test.cc @@ -184,6 +184,8 @@ TEST(DriverAuto, NonfiniteAndWideBounds) is_value_in_range(NEU_TYPE_INT64, INT64_MAX, 0, NEU_TYPE_INT64, 0.5)); EXPECT_EQ(NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE, is_value_in_range(NEU_TYPE_UINT64, -1, 0, NEU_TYPE_INT64, 0)); + EXPECT_EQ(0, is_value_in_range(NEU_TYPE_UINT64, -1, 0, NEU_TYPE_UINT64, 0)); + EXPECT_EQ(0, is_value_in_range(NEU_TYPE_FLOAT, -1, 0, NEU_TYPE_UINT64, 0)); EXPECT_EQ(0, is_value_in_range(NEU_TYPE_FLOAT, 0, 1e30, NEU_TYPE_DOUBLE, 0)); EXPECT_EQ(NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE,