Added Who-Is-Router process for Notification Class recipient unknown router addresses. (#1243)

* Added Who-Is-Router-To-Network process in basic Notification Class when recipient address is missing the router MAC address.

* Added buffer_length parameter to octet string buffer decode functions

* Fixed BACnet address handling for I-Am-Router address updating the recipient list address for the next hop router.

* Changed VMAC encoding and decoding to use octet string buffer API to reduce stack RAM.
This commit is contained in:
Steve Karg
2026-02-25 09:58:38 -06:00
committed by GitHub
parent e11cd319da
commit cf4f62f7e0
14 changed files with 225 additions and 69 deletions
+25 -15
View File
@@ -150,6 +150,12 @@ static void test_BACNET_ADDRESS(void)
zassert_equal(dest.mac_len, 0, NULL);
zassert_equal(dest.len, 0, NULL);
zassert_equal(dest.net, 0, NULL);
/* copy the MAC to the ADR */
bacnet_address_from_ascii(&src, "{192.168.1.1:47808,0,0}");
zassert_equal(src.mac_len, 6, "len=%d", src.mac_len);
bacnet_address_router_set(&dest, &src);
zassert_equal(dest.mac_len, 6, "len=%d", dest.mac_len);
zassert_equal(dest.len, 0, NULL);
}
#if defined(CONFIG_ZTEST_NEW_API)
@@ -282,13 +288,13 @@ static void test_BACnetAddress_Codec(void)
zassert_equal(len, test_len, "len=%d test_len=%d", len, test_len);
test_len = bacnet_address_decode(apdu, sizeof(apdu), &test_value);
zassert_equal(len, test_len, NULL);
zassert_equal(value.net, test_value.net, NULL);
zassert_equal(value.mac_len, test_value.mac_len, NULL);
zassert_equal(value.len, test_value.len, NULL);
zassert_equal(value.len, 3, NULL);
zassert_equal(value.adr[0], test_value.adr[0], NULL);
zassert_equal(value.adr[1], test_value.adr[1], NULL);
zassert_equal(value.adr[2], test_value.adr[2], NULL);
zassert_equal(test_value.net, value.net, NULL);
zassert_equal(test_value.len, value.len, NULL);
zassert_equal(test_value.len, 3, NULL);
zassert_equal(test_value.adr[0], value.adr[0], NULL);
zassert_equal(test_value.adr[1], value.adr[1], NULL);
zassert_equal(test_value.adr[2], value.adr[2], NULL);
zassert_equal(test_value.mac_len, 0, NULL);
/* context tagged */
tag_number = 1;
len = encode_context_bacnet_address(NULL, tag_number, &value);
@@ -299,17 +305,21 @@ static void test_BACnetAddress_Codec(void)
test_len = bacnet_address_context_decode(
apdu, sizeof(apdu), tag_number, &test_value);
zassert_equal(len, test_len, NULL);
zassert_equal(value.net, test_value.net, NULL);
zassert_equal(value.mac_len, test_value.mac_len, NULL);
zassert_equal(value.mac_len, 6, NULL);
zassert_equal(test_value.len, value.len, NULL);
zassert_equal(test_value.len, 3, NULL);
zassert_equal(test_value.adr[0], value.adr[0], NULL);
zassert_equal(test_value.adr[1], value.adr[1], NULL);
zassert_equal(test_value.adr[2], value.adr[2], NULL);
zassert_equal(test_value.mac_len, 0, NULL);
/* validate deprecated function */
test_len = decode_context_bacnet_address(apdu, tag_number, &test_value);
zassert_equal(len, test_len, NULL);
zassert_equal(value.net, test_value.net, NULL);
zassert_equal(value.mac_len, test_value.mac_len, NULL);
zassert_equal(value.mac_len, 6, NULL);
test_len = bacnet_address_context_decode(
apdu, sizeof(apdu), tag_number, &test_value);
zassert_equal(test_value.len, value.len, NULL);
zassert_equal(test_value.len, 3, NULL);
zassert_equal(test_value.adr[0], value.adr[0], NULL);
zassert_equal(test_value.adr[1], value.adr[1], NULL);
zassert_equal(test_value.adr[2], value.adr[2], NULL);
zassert_equal(test_value.mac_len, 0, NULL);
/* negative tests - NULL value */
test_len =
bacnet_address_context_decode(apdu, sizeof(apdu), tag_number, NULL);
+6 -2
View File
@@ -2358,6 +2358,7 @@ static void test_octet_string_buffer(void)
uint8_t buffer[32] = { 0 }, test_buffer[32] = { 0 };
int apdu_len = 0, null_len = 0, test_len = 0;
size_t buffer_size = 0;
uint32_t buffer_length = 0;
uint8_t tag_number = 0;
unsigned i;
int diff = 0; /* for memcmp */
@@ -2381,10 +2382,11 @@ static void test_octet_string_buffer(void)
NULL, 0, buffer, buffer_size);
zassert_equal(null_len, 0, NULL);
test_len = bacnet_octet_string_buffer_application_decode(
apdu, apdu_len, test_buffer, sizeof(test_buffer));
apdu, apdu_len, test_buffer, sizeof(test_buffer), &buffer_length);
zassert_equal(
apdu_len, test_len, "apdu_len=%d test_len=%d i=%d", apdu_len,
test_len, i);
zassert_equal(buffer_size, buffer_length, NULL);
diff = memcmp(buffer, test_buffer, buffer_size);
zassert_equal(diff, 0, NULL);
/* context tagged */
@@ -2398,10 +2400,12 @@ static void test_octet_string_buffer(void)
NULL, 0, tag_number, buffer, buffer_size);
zassert_equal(null_len, 0, NULL);
test_len = bacnet_octet_string_buffer_context_decode(
apdu, apdu_len, tag_number, test_buffer, sizeof(test_buffer));
apdu, apdu_len, tag_number, test_buffer, sizeof(test_buffer),
&buffer_length);
zassert_equal(
apdu_len, test_len, "apdu_len=%d test_len=%d i=%d", apdu_len,
test_len, i);
zassert_equal(buffer_size, buffer_length, NULL);
diff = memcmp(buffer, test_buffer, buffer_size);
zassert_equal(diff, 0, NULL);
}
+5
View File
@@ -238,6 +238,11 @@ static void test_BACnetRecipient_ASCII(void)
zassert_true(status, "ascii=%s", ascii);
status = bacnet_recipient_same(&value, &test_value);
zassert_true(status, NULL);
status = bacnet_recipient_address_router_unknown(&value);
zassert_false(status, NULL);
value.type.address.mac_len = 0;
status = bacnet_recipient_address_router_unknown(&value);
zassert_true(status, NULL);
}
#if defined(CONFIG_ZTEST_NEW_API)
@@ -72,6 +72,8 @@ add_executable(${PROJECT_NAME}
# Test and test library files
./stubs.c
./src/main.c
${TST_DIR}/bacnet/basic/object/test/datetime_local.c
${TST_DIR}/bacnet/basic/object/test/device_mock.c
${ZTST_DIR}/ztest_mock.c
${ZTST_DIR}/ztest.c
)
+19 -11
View File
@@ -11,10 +11,19 @@
#include "bacnet/datetime.h"
#include "bacnet/bacdef.h"
#include "bacnet/npdu.h"
#include "bacnet/basic/npdu/h_npdu.h"
#include "bacnet/basic/object/nc.h"
uint32_t Device_Object_Instance_Number(void)
uint8_t Send_CEvent_Notify_Address(
uint8_t *pdu,
uint16_t pdu_size,
const BACNET_EVENT_NOTIFICATION_DATA *data,
BACNET_ADDRESS *dest)
{
(void)pdu;
(void)pdu_size;
(void)data;
(void)dest;
return 0;
}
@@ -43,15 +52,14 @@ void Send_WhoIs(int32_t low_limit, int32_t high_limit)
(void)high_limit;
}
bool datetime_local(
BACNET_DATE *bdate,
BACNET_TIME *btime,
int16_t *utc_offset_minutes,
bool *dst_active)
void Send_Who_Is_Router_To_Network(BACNET_ADDRESS *dst, int dnet)
{
(void)bdate;
(void)btime;
(void)utc_offset_minutes;
(void)dst_active;
return true;
(void)dst;
(void)dnet;
}
void npdu_set_i_am_router_to_network_handler(
i_am_router_to_network_function pFunction)
{
(void)pFunction;
}