Fixed BVLC Write Broadcast Distribution Table for protocol revision 17 and later. (#1005)

* Fixed BVLC Write Broadcast Distribution Table for protocol revision 17 and later.

* Added check for Network Port object bbmd-accept-fd-registrations property in BBMD handler.

* Added bvlc_foreign_device_table_decode() function and unit test.

* Added BDT and FTD write property to network port for IPv4
This commit is contained in:
Steve Karg
2025-06-10 09:48:10 -05:00
committed by GitHub
parent f0ec05d085
commit 5d45d43da5
7 changed files with 711 additions and 48 deletions
+45
View File
@@ -50,6 +50,8 @@ static bool BVLC_NAT_Handling = false;
static BACNET_IP_ADDRESS Remote_BBMD; static BACNET_IP_ADDRESS Remote_BBMD;
/** if we are a foreign device, store the Time-To-Live Seconds here */ /** if we are a foreign device, store the Time-To-Live Seconds here */
static uint16_t Remote_BBMD_TTL_Seconds; static uint16_t Remote_BBMD_TTL_Seconds;
/** Dynamic enable or disable of accepting FD registrations */
static bool BBMD_Accept_FD_Registrations = 1;
#if BBMD_ENABLED || BBMD_CLIENT_ENABLED #if BBMD_ENABLED || BBMD_CLIENT_ENABLED
/* local buffer & length for sending */ /* local buffer & length for sending */
static uint8_t BVLC_Buffer[BIP_MPDU_MAX]; static uint8_t BVLC_Buffer[BIP_MPDU_MAX];
@@ -873,6 +875,22 @@ int bvlc_bbmd_enabled_handler(
} }
break; break;
case BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE: case BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE:
/* J.2.2.1 Write-Broadcast-Distribution-Table: Format
...
Prior to the introduction of the Network Port object
in Protocol_Revision 17, this message was the interoperable
means of updating BDTs. That function is now performed
by writes to the Network Port object
...
J.4.4.2 Use of the BVLL Write-Broadcast-Distribution-Table Message
Upon receipt of a BVLL Write-Broadcast-Distribution-Table message,
B/IP devices shall always return a BVLC-Result message to the
originating device with a result code of X'0010' indicating that
the Write-Broadcast-Distribution BVLL message is not supported.*/
#if (BACNET_PROTOCOL_REVISION >= 17)
result_code = BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK;
send_result = true;
#else
debug_print_bip("Received Write-BDT", addr); debug_print_bip("Received Write-BDT", addr);
function_len = bvlc_decode_write_broadcast_distribution_table( function_len = bvlc_decode_write_broadcast_distribution_table(
pdu, pdu_len, &BBMD_Table[0]); pdu, pdu_len, &BBMD_Table[0]);
@@ -886,6 +904,7 @@ int bvlc_bbmd_enabled_handler(
BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK; BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK;
send_result = true; send_result = true;
} }
#endif
/* not an NPDU */ /* not an NPDU */
offset = 0; offset = 0;
break; break;
@@ -971,6 +990,13 @@ int bvlc_bbmd_enabled_handler(
without the receipt of another BVLL Register-Foreign-Device without the receipt of another BVLL Register-Foreign-Device
message from the same foreign device, the FDT entry for this message from the same foreign device, the FDT entry for this
device shall be cleared. */ device shall be cleared. */
#if (BACNET_PROTOCOL_REVISION >= 17)
if (!BBMD_Accept_FD_Registrations) {
result_code = BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK;
send_result = true;
break;
}
#endif
function_len = function_len =
bvlc_decode_register_foreign_device(pdu, pdu_len, &ttl_seconds); bvlc_decode_register_foreign_device(pdu, pdu_len, &ttl_seconds);
if (function_len) { if (function_len) {
@@ -1203,6 +1229,25 @@ int bvlc_broadcast_handler(
return offset; return offset;
} }
/**
* @brief Get the status of the BBMD_Accept_FD_Registrations flag.
* @return true if BBMD_Accept_FD_Registrations is enabled, false otherwise.
*/
bool bvlc_bbmd_accept_fd_registrations(void)
{
return BBMD_Accept_FD_Registrations;
}
/**
* @brief Set the status of the BBMD_Accept_FD_Registrations flag.
* @param flag - true to enable accepting foreign device registrations,
* false to disable.
*/
void bvlc_bbmd_accept_fd_registrations_set(bool flag)
{
BBMD_Accept_FD_Registrations = flag;
}
#if BBMD_CLIENT_ENABLED #if BBMD_CLIENT_ENABLED
/** Register as a foreign device with the indicated BBMD. /** Register as a foreign device with the indicated BBMD.
* @param bbmd_addr - IPv4 address of BBMD with which to register * @param bbmd_addr - IPv4 address of BBMD with which to register
+5
View File
@@ -98,6 +98,11 @@ void bvlc_remote_bbmd_address(BACNET_IP_ADDRESS *address);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
uint16_t bvlc_remote_bbmd_lifetime(void); uint16_t bvlc_remote_bbmd_lifetime(void);
BACNET_STACK_EXPORT
bool bvlc_bbmd_accept_fd_registrations(void);
BACNET_STACK_EXPORT
void bvlc_bbmd_accept_fd_registrations_set(bool flag);
/* Local interface to manage BBMD. /* Local interface to manage BBMD.
* The interface user needs to handle mutual exclusion if needed i.e. * The interface user needs to handle mutual exclusion if needed i.e.
* BACnet packet is not being handled when the BBMD table is modified. * BACnet packet is not being handled when the BBMD table is modified.
+245
View File
@@ -1869,6 +1869,110 @@ static int BBMD_Broadcast_Distribution_Table_Encode(
return apdu_len; return apdu_len;
} }
/**
* @brief Get the BACnetLIST capacity
* @param object_instance [in] BACnet network port object instance number
* @return capacity of the BACnetList (number of possible entries) or
* zero on error
*/
static size_t
BBMD_Broadcast_Distribution_Table_Capacity(uint32_t object_instance)
{
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_list;
size_t capacity = 0;
unsigned index = 0;
index = Network_Port_Instance_To_Index(object_instance);
if (index < BACNET_NETWORK_PORTS_MAX) {
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
bdt_list = Object_List[index].Network.IPv4.BBMD_BD_Table;
capacity = bvlc_broadcast_distribution_table_count(bdt_list);
}
}
return capacity;
}
/**
* @brief Decode a BACnetLIST property element to determine the element length
* @param object_instance [in] BACnet network port object instance number
* @param apdu [in] Buffer in which the APDU contents are extracted
* @param apdu_size [in] The size of the APDU buffer
* @return The length of the decoded apdu, or BACNET_STATUS_ERROR on error
*/
static int BBMD_Broadcast_Distribution_Table_Element_Length(
uint32_t object_instance, uint8_t *apdu, size_t apdu_size)
{
int len = 0;
unsigned index = 0;
index = Network_Port_Instance_To_Index(object_instance);
if (index < BACNET_NETWORK_PORTS_MAX) {
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
len = bvlc_decode_broadcast_distribution_table_entry(
apdu, apdu_size, NULL);
}
}
return len;
}
/**
* @brief Write a value to a BACnetLIST property element value
* using a BACnetARRAY write utility function
* @param object_instance [in] BACnet network port object instance number
* @param array_index [in] array index to write:
* 0=array size, 1 to N for individual array members
* @param application_data [in] encoded element value
* @param application_data_len [in] The size of the encoded element value
* @return BACNET_ERROR_CODE value
*/
static BACNET_ERROR_CODE BBMD_Broadcast_Distribution_Table_Element_Write(
uint32_t object_instance,
BACNET_ARRAY_INDEX array_index,
uint8_t *application_data,
size_t application_data_len)
{
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY bdt_entry = { 0 };
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_list;
uint16_t capacity = 0;
int len;
bool status = false;
unsigned index = 0;
index = Network_Port_Instance_To_Index(object_instance);
if (index < BACNET_NETWORK_PORTS_MAX) {
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
bdt_list = Object_List[index].Network.IPv4.BBMD_BD_Table;
capacity = bvlc_broadcast_distribution_table_count(bdt_list);
if (array_index == 0) {
error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
} else if (array_index <= capacity) {
len = bvlc_decode_broadcast_distribution_table_entry(
application_data, application_data_len, &bdt_entry);
if (len > 0) {
status = bvlc_broadcast_distribution_table_entry_insert(
bdt_list, &bdt_entry, array_index);
if (status) {
error_code = ERROR_CODE_SUCCESS;
} else {
error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else {
error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
}
} else {
error_code = ERROR_CODE_ABORT_OTHER;
}
}
return error_code;
}
/** /**
* For a given object instance-number, sets the BBMD-BD-Table head * For a given object instance-number, sets the BBMD-BD-Table head
* property value * property value
@@ -1980,6 +2084,108 @@ static int BBMD_Foreign_Device_Table_Encode(
return apdu_len; return apdu_len;
} }
/**
* @brief Get the BACnetLIST capacity
* @param object_instance [in] BACnet network port object instance number
* @return capacity of the BACnetList (number of possible entries) or
* zero on error
*/
static size_t BBMD_Foreign_Device_Table_Capacity(uint32_t object_instance)
{
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_list;
size_t capacity = 0;
unsigned index = 0;
index = Network_Port_Instance_To_Index(object_instance);
if (index < BACNET_NETWORK_PORTS_MAX) {
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
fdt_list = Object_List[index].Network.IPv4.BBMD_FD_Table;
capacity = bvlc_foreign_device_table_count(fdt_list);
}
}
return capacity;
}
/**
* @brief Decode a BACnetLIST property element to determine the element length
* @param object_instance [in] BACnet network port object instance number
* @param apdu [in] Buffer in which the APDU contents are extracted
* @param apdu_size [in] The size of the APDU buffer
* @return The length of the decoded apdu, or BACNET_STATUS_ERROR on error
*/
static int BBMD_Foreign_Device_Table_Element_Length(
uint32_t object_instance, uint8_t *apdu, size_t apdu_size)
{
int len = 0;
unsigned index = 0;
index = Network_Port_Instance_To_Index(object_instance);
if (index < BACNET_NETWORK_PORTS_MAX) {
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
len = bvlc_decode_foreign_device_table_entry(apdu, apdu_size, NULL);
}
}
return len;
}
/**
* @brief Write a value to a BACnetLIST property element value
* using a BACnetARRAY write utility function
* @param object_instance [in] BACnet network port object instance number
* @param array_index [in] array index to write:
* 0=array size, 1 to N for individual array members
* @param application_data [in] encoded element value
* @param application_data_len [in] The size of the encoded element value
* @return BACNET_ERROR_CODE value
*/
static BACNET_ERROR_CODE BBMD_Foreign_Device_Table_Element_Write(
uint32_t object_instance,
BACNET_ARRAY_INDEX array_index,
uint8_t *application_data,
size_t application_data_len)
{
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY fdt_entry = { 0 };
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_list;
uint16_t capacity = 0;
int len;
bool status = false;
unsigned index = 0;
index = Network_Port_Instance_To_Index(object_instance);
if (index < BACNET_NETWORK_PORTS_MAX) {
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
fdt_list = Object_List[index].Network.IPv4.BBMD_FD_Table;
capacity = bvlc_foreign_device_table_count(fdt_list);
if (array_index == 0) {
error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
} else if (array_index <= capacity) {
len = bvlc_decode_foreign_device_table_entry(
application_data, application_data_len, &fdt_entry);
if (len > 0) {
status = bvlc_foreign_device_table_entry_insert(
fdt_list, &fdt_entry, array_index - 1);
if (status) {
error_code = ERROR_CODE_SUCCESS;
} else {
error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else {
error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
}
} else {
error_code = ERROR_CODE_ABORT_OTHER;
}
}
return error_code;
}
/** /**
* @brief For a given object instance-number, gets the HostNPort * @brief For a given object instance-number, gets the HostNPort
* @note depends on Network_Type being set for this object * @note depends on Network_Type being set for this object
@@ -4100,6 +4306,7 @@ bool Network_Port_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
uint32_t capacity;
BACNET_APPLICATION_DATA_VALUE value = { 0 }; BACNET_APPLICATION_DATA_VALUE value = { 0 };
if (!Network_Port_Valid_Instance(wp_data->object_instance)) { if (!Network_Port_Valid_Instance(wp_data->object_instance)) {
@@ -4181,6 +4388,44 @@ bool Network_Port_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
} }
break; break;
case PROP_BBMD_ACCEPT_FD_REGISTRATIONS:
status = write_property_type_valid(
wp_data, &value, BACNET_APPLICATION_TAG_BOOLEAN);
if (status) {
status = Network_Port_BBMD_Accept_FD_Registrations_Set(
wp_data->object_instance, value.type.Boolean);
if (!status) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
}
break;
case PROP_BBMD_BROADCAST_DISTRIBUTION_TABLE:
/* BACnetLIST */
capacity = BBMD_Broadcast_Distribution_Table_Capacity(
wp_data->object_instance);
wp_data->error_code = bacnet_array_write(
wp_data->object_instance, wp_data->array_index,
BBMD_Broadcast_Distribution_Table_Element_Length,
BBMD_Broadcast_Distribution_Table_Element_Write, capacity,
wp_data->application_data, wp_data->application_data_len);
if (wp_data->error_code == ERROR_CODE_SUCCESS) {
status = true;
}
break;
case PROP_BBMD_FOREIGN_DEVICE_TABLE:
/* BACnetLIST */
capacity =
BBMD_Foreign_Device_Table_Capacity(wp_data->object_instance);
wp_data->error_code = bacnet_array_write(
wp_data->object_instance, wp_data->array_index,
BBMD_Foreign_Device_Table_Element_Length,
BBMD_Foreign_Device_Table_Element_Write, capacity,
wp_data->application_data, wp_data->application_data_len);
if (wp_data->error_code == ERROR_CODE_SUCCESS) {
status = true;
}
break;
default: default:
if (Property_List_Member( if (Property_List_Member(
wp_data->object_instance, wp_data->object_property)) { wp_data->object_instance, wp_data->object_property)) {
+216 -30
View File
@@ -356,6 +356,37 @@ bool bvlc_broadcast_distribution_table_entry_append(
return status; return status;
} }
/**
* @brief Append an entry to the Broadcast-Distribution-Table
* @param bdt_list - first entry in list of BDT entries
* @param bdt_entry - entry to insert into to list of BDT entries
* @param bdt_index - 0..N where N is count-1
* @return true if the Broadcast-Distribution-Table entry was inserted
*/
bool bvlc_broadcast_distribution_table_entry_insert(
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_list,
const BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_entry,
uint16_t bdt_index)
{
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_node = NULL;
uint16_t count = 0;
bool status = false;
bdt_node = bdt_list;
while (bdt_node) {
if (count == bdt_index) {
status = true;
bvlc_broadcast_distribution_table_entry_copy(bdt_node, bdt_entry);
bdt_node->valid = true;
break;
}
bdt_node = bdt_node->next;
count++;
}
return status;
}
/** /**
* @brief Set an entry to the Broadcast-Distribution-Table * @brief Set an entry to the Broadcast-Distribution-Table
* @param bdt_entry - first element in list of BDT entries * @param bdt_entry - first element in list of BDT entries
@@ -831,17 +862,15 @@ int bvlc_encode_write_broadcast_distribution_table(
* @param pdu_len - length of the buffer that needs decoding * @param pdu_len - length of the buffer that needs decoding
* @param bdt_list - BDT Entry list * @param bdt_list - BDT Entry list
* *
* @return number of bytes decoded * @return number of bytes decoded, or 0 for none or error
*/ */
int bvlc_decode_write_broadcast_distribution_table( int bvlc_decode_write_broadcast_distribution_table(
const uint8_t *pdu, const uint8_t *pdu,
uint16_t pdu_len, uint16_t pdu_size,
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_list) BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_list)
{ {
int bytes_consumed = 0;
int len = 0; int len = 0;
uint16_t offset = 0; uint16_t pdu_len = 0;
uint16_t pdu_bytes = 0;
uint16_t bdt_entry_count = 0; uint16_t bdt_entry_count = 0;
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_entry = NULL; BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_entry = NULL;
uint16_t list_len = 0; uint16_t list_len = 0;
@@ -850,26 +879,40 @@ int bvlc_decode_write_broadcast_distribution_table(
bdt_entry_count = bvlc_broadcast_distribution_table_count(bdt_list); bdt_entry_count = bvlc_broadcast_distribution_table_count(bdt_list);
list_len = bdt_entry_count * BACNET_IP_BDT_ENTRY_SIZE; list_len = bdt_entry_count * BACNET_IP_BDT_ENTRY_SIZE;
/* will the entries fit */ /* will the entries fit */
if (pdu && (pdu_len <= list_len)) { if (pdu && (pdu_size <= list_len)) {
/* check payload for valid entries */
while (pdu_len < pdu_size) {
len = bvlc_decode_broadcast_distribution_table_entry(
&pdu[pdu_len], pdu_size - pdu_len, NULL);
if (len > 0) {
pdu_len += len;
} else {
return 0;
}
}
pdu_len = 0;
bdt_entry = bdt_list; bdt_entry = bdt_list;
while (bdt_entry) { while (bdt_entry) {
pdu_bytes = pdu_len - offset; if (pdu_len < pdu_size) {
if (pdu_bytes >= BACNET_IP_BDT_ENTRY_SIZE) { /* decode valid entries */
len = bvlc_decode_broadcast_distribution_table_entry( len = bvlc_decode_broadcast_distribution_table_entry(
&pdu[offset], pdu_bytes, bdt_entry); &pdu[pdu_len], pdu_size - pdu_len, bdt_entry);
if (len > 0) { if (len > 0) {
pdu_len += len;
bdt_entry->valid = true; bdt_entry->valid = true;
} else {
/* set the available entries as invalid */
bdt_entry->valid = false;
} }
offset += len;
} else { } else {
/* set the available entries as invalid */
bdt_entry->valid = false; bdt_entry->valid = false;
} }
bdt_entry = bdt_entry->next; bdt_entry = bdt_entry->next;
} }
bytes_consumed = (int)offset;
} }
return bytes_consumed; return pdu_len;
} }
/** /**
@@ -1274,6 +1317,92 @@ int bvlc_foreign_device_table_encode(
return len; return len;
} }
/**
* @brief Decode the Foreign_Device-Table for Network Port object
* @param apdu - the APDU buffer
* @param apdu_size - the APDU buffer length
* @param fdt_head - head of a FDT linked list
* @return length of the APDU buffer decoded, or ERROR, REJECT, or ABORT
*/
int bvlc_foreign_device_table_decode(
const uint8_t *apdu,
uint16_t apdu_size,
BACNET_ERROR_CODE *error_code,
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_head)
{
int len = 0, apdu_len = 0;
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_entry = NULL;
BACNET_UNSIGNED_INTEGER unsigned_value = 0;
BACNET_OCTET_STRING octet_string = { 0 };
/* default reject code */
if (error_code) {
*error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
/* check for value pointers */
if ((apdu_size == 0) || (!apdu)) {
return BACNET_STATUS_REJECT;
}
fdt_entry = fdt_head;
while (fdt_entry) {
/* bacnetip-address [0] OCTET STRING */
len = bacnet_octet_string_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 0, &octet_string);
if (len <= 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
}
return BACNET_STATUS_REJECT;
}
bvlc_decode_address(
octetstring_value(&octet_string), octetstring_length(&octet_string),
&fdt_entry->dest_address);
apdu_len += len;
/* time-to-live [1] Unsigned16 */
len = bacnet_unsigned_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 1, &unsigned_value);
if (len <= 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
}
return BACNET_STATUS_REJECT;
}
apdu_len += len;
if (unsigned_value <= UINT16_MAX) {
fdt_entry->ttl_seconds = unsigned_value;
} else {
if (error_code) {
*error_code = ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE;
}
return BACNET_STATUS_REJECT;
}
/* remaining-time-to-live [2] Unsigned16 */
len = bacnet_unsigned_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 2, &unsigned_value);
if (len <= 0) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
}
return BACNET_STATUS_REJECT;
}
apdu_len += len;
if (unsigned_value <= UINT16_MAX) {
fdt_entry->ttl_seconds_remaining = unsigned_value;
} else {
if (error_code) {
*error_code = ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE;
}
return BACNET_STATUS_REJECT;
}
/* mark as valid */
fdt_entry->valid = true;
/* next entry */
fdt_entry = fdt_entry->next;
}
return apdu_len;
}
/** /**
* @brief J.2.7 Read-Foreign-Device-Table: encode * @brief J.2.7 Read-Foreign-Device-Table: encode
* *
@@ -1461,6 +1590,53 @@ bool bvlc_foreign_device_table_entry_add(
return status; return status;
} }
/**
* @brief Append an entry to the Foreign-Device-Table
* @param bdt_list - first entry in list of FDT entries
* @param bdt_entry - entry to insert into to list of FDT entries
* @param bdt_index - 0..N where N is count-1
* @return true if the entry was inserted
*/
bool bvlc_foreign_device_table_entry_insert(
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_list,
const BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_entry,
uint16_t array_index)
{
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_node = NULL;
uint16_t count = 0;
bool status = false;
fdt_node = fdt_list;
while (fdt_node) {
if (count == array_index) {
status = bvlc_foreign_device_table_entry_copy(fdt_node, fdt_entry);
fdt_node->valid = true;
break;
}
fdt_node = fdt_node->next;
count++;
}
return status;
}
/**
* @brief Clear all Write-Broadcast-Distribution-Table entries
* @param bdt_list - first element in array BDT entries
*/
void bvlc_foreign_device_table_valid_clear(
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_list)
{
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_entry;
/* clear the valid entries */
fdt_entry = fdt_list;
while (fdt_entry) {
fdt_entry->valid = false;
fdt_entry = fdt_entry->next;
}
}
/** /**
* @brief Count the number of valid Foreign-Device-Table entries * @brief Count the number of valid Foreign-Device-Table entries
* @param fdt_list - first element in list of FDT entries * @param fdt_list - first element in list of FDT entries
@@ -2143,6 +2319,7 @@ bool bvlc_address_mask(
dst->address[i] = src->address[i] | ~mask->address[i]; dst->address[i] = src->address[i] | ~mask->address[i];
} }
dst->port = src->port; dst->port = src->port;
status = true;
} }
return status; return status;
@@ -2569,37 +2746,46 @@ int bvlc_encode_broadcast_distribution_table_entry(
* IP subnet served by the BBMD * IP subnet served by the BBMD
* *
* @param pdu - buffer from which to decode the message * @param pdu - buffer from which to decode the message
* @param pdu_len - length of the buffer that needs decoding * @param pdu_size - length of the buffer that needs decoding
* @param bdt_entry - BDT Entry * @param bdt_entry - BDT Entry, or NULL for length only
* *
* @return number of bytes decoded * @return number of bytes decoded, or 0 if error
*/ */
int bvlc_decode_broadcast_distribution_table_entry( int bvlc_decode_broadcast_distribution_table_entry(
const uint8_t *pdu, const uint8_t *pdu,
uint16_t pdu_len, uint16_t pdu_size,
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_entry) BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_entry)
{ {
int bytes_consumed = 0; int pdu_len = 0;
int len = 0; int len = 0;
int offset = 0; BACNET_IP_ADDRESS dest_address;
BACNET_IP_BROADCAST_DISTRIBUTION_MASK broadcast_mask;
if (pdu && (pdu_len >= BACNET_IP_BDT_ENTRY_SIZE)) { if (pdu) {
if (bdt_entry) { len = bvlc_decode_address(
len = bvlc_decode_address( &pdu[pdu_len], pdu_size - pdu_len, &dest_address);
&pdu[offset], pdu_len - offset, &bdt_entry->dest_address); if (len > 0) {
if (len > 0) { pdu_len += len;
offset += len; if (bdt_entry) {
len = bvlc_decode_broadcast_distribution_mask( bvlc_address_copy(&bdt_entry->dest_address, &dest_address);
&pdu[offset], pdu_len - offset, &bdt_entry->broadcast_mask);
} }
if (len > 0) { } else {
offset += len; return 0;
bytes_consumed = offset; }
len = bvlc_decode_broadcast_distribution_mask(
&pdu[pdu_len], pdu_size - pdu_len, &broadcast_mask);
if (len > 0) {
pdu_len += len;
if (bdt_entry) {
bvlc_broadcast_distribution_mask_copy(
&bdt_entry->broadcast_mask, &broadcast_mask);
} }
} else {
return 0;
} }
} }
return bytes_consumed; return pdu_len;
} }
/** /**
+20
View File
@@ -272,6 +272,12 @@ bool bvlc_broadcast_distribution_table_entry_append(
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_list, BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_list,
const BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_entry); const BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_entry);
BACNET_STACK_EXPORT
bool bvlc_broadcast_distribution_table_entry_insert(
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_list,
const BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_entry,
uint16_t array_index);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
bool bvlc_broadcast_distribution_table_entry_set( bool bvlc_broadcast_distribution_table_entry_set(
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_entry, BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_entry,
@@ -380,6 +386,9 @@ void bvlc_foreign_device_table_maintenance_timer(
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_list, uint16_t seconds); BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_list, uint16_t seconds);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void bvlc_foreign_device_table_valid_clear(
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_list);
BACNET_STACK_EXPORT
uint16_t bvlc_foreign_device_table_valid_count( uint16_t bvlc_foreign_device_table_valid_count(
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_list); BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_list);
@@ -412,6 +421,12 @@ bool bvlc_foreign_device_table_entry_add(
const BACNET_IP_ADDRESS *ip_address, const BACNET_IP_ADDRESS *ip_address,
uint16_t ttl_seconds); uint16_t ttl_seconds);
BACNET_STACK_EXPORT
bool bvlc_foreign_device_table_entry_insert(
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_list,
const BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_entry,
uint16_t array_index);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
int bvlc_encode_foreign_device_table_entry( int bvlc_encode_foreign_device_table_entry(
uint8_t *pdu, uint8_t *pdu,
@@ -435,6 +450,11 @@ int bvlc_foreign_device_table_encode(
uint8_t *apdu, uint8_t *apdu,
uint16_t apdu_size, uint16_t apdu_size,
const BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_head); const BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_head);
int bvlc_foreign_device_table_decode(
const uint8_t *apdu,
uint16_t apdu_len,
BACNET_ERROR_CODE *error_code,
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_head);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
int bvlc_encode_read_foreign_device_table(uint8_t *pdu, uint16_t pdu_size); int bvlc_encode_read_foreign_device_table(uint8_t *pdu, uint16_t pdu_size);
+38
View File
@@ -321,6 +321,38 @@ static int bbmd6_register_as_foreign_device(void)
return retval; return retval;
} }
/**
* @brief
*
* @param instance
*/
static void bip_network_port_activate_changes(uint32_t instance)
{
#if defined(BACDL_BIP)
bvlc_bbmd_accept_fd_registrations_set(
Network_Port_BBMD_Accept_FD_Registrations(instance));
#else
/* if we are not using BIP, then we don't have any changes to discard */
(void)instance;
#endif
}
/**
* @brief
*
* @param instance
*/
static void bip_network_port_discard_changes(uint32_t instance)
{
#if defined(BACDL_BIP)
Network_Port_BBMD_Accept_FD_Registrations_Set(
instance, bvlc_bbmd_accept_fd_registrations());
#else
/* if we are not using BIP, then we don't have any changes to discard */
(void)instance;
#endif
}
/** /**
* Datalink network port object settings * Datalink network port object settings
*/ */
@@ -401,6 +433,8 @@ static void dlenv_network_port_bip_init(uint32_t instance)
instance, addr0, addr1, addr2, addr3); instance, addr0, addr1, addr2, addr3);
Network_Port_Remote_BBMD_BIP_Port_Set(instance, BBMD_Address.port); Network_Port_Remote_BBMD_BIP_Port_Set(instance, BBMD_Address.port);
Network_Port_Remote_BBMD_BIP_Lifetime_Set(instance, BBMD_TTL_Seconds); Network_Port_Remote_BBMD_BIP_Lifetime_Set(instance, BBMD_TTL_Seconds);
Network_Port_BBMD_Accept_FD_Registrations_Set(
instance, bvlc_bbmd_accept_fd_registrations());
#endif #endif
/* common NP data */ /* common NP data */
Network_Port_Reliability_Set(instance, RELIABILITY_NO_FAULT_DETECTED); Network_Port_Reliability_Set(instance, RELIABILITY_NO_FAULT_DETECTED);
@@ -411,6 +445,10 @@ static void dlenv_network_port_bip_init(uint32_t instance)
/* last thing - clear pending changes - we don't want to set these /* last thing - clear pending changes - we don't want to set these
since they are already set */ since they are already set */
Network_Port_Changes_Pending_Set(instance, false); Network_Port_Changes_Pending_Set(instance, false);
Network_Port_Changes_Pending_Activate_Callback_Set(
instance, bip_network_port_activate_changes);
Network_Port_Changes_Pending_Discard_Callback_Set(
instance, bip_network_port_discard_changes);
} }
/** /**
+142 -18
View File
@@ -97,13 +97,14 @@ static void test_BVLC_Result_Code(uint16_t result_code)
int len = 0, test_len = 0; int len = 0, test_len = 0;
len = bvlc_encode_result(pdu, sizeof(pdu), result_code); len = bvlc_encode_result(pdu, sizeof(pdu), result_code);
zassert_equal(len, 6, NULL); zassert_equal(len, 6, "result-code=%s", bvlc_result_code_name(result_code));
test_len = test_BVLC_Header(pdu, len, &message_type, &length); test_len = test_BVLC_Header(pdu, len, &message_type, &length);
zassert_equal(test_len, 4, NULL); zassert_equal(test_len, 4, NULL);
zassert_equal(message_type, BVLC_RESULT, NULL); zassert_equal(message_type, BVLC_RESULT, NULL);
zassert_equal(length, 6, NULL); zassert_equal(length, 6, NULL);
test_len += bvlc_decode_result(&pdu[4], length - 4, &test_result_code); test_len += bvlc_decode_result(&pdu[4], length - 4, &test_result_code);
zassert_equal(len, test_len, NULL); zassert_equal(
len, test_len, "result-code=%s", bvlc_result_code_name(result_code));
zassert_equal(result_code, test_result_code, NULL); zassert_equal(result_code, test_result_code, NULL);
} }
@@ -493,6 +494,9 @@ static void test_BVLC_Broadcast_Distribution_Table_Encode(void)
uint16_t i = 0; uint16_t i = 0;
uint16_t count = 0; uint16_t count = 0;
uint16_t test_count = 0; uint16_t test_count = 0;
uint8_t message_type = 0;
uint16_t message_length = 0;
int test_message_len = 0;
bool status = false; bool status = false;
BACNET_ERROR_CODE error_code; BACNET_ERROR_CODE error_code;
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY bdt_list[5] = { 0 }; BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY bdt_list[5] = { 0 };
@@ -540,6 +544,25 @@ static void test_BVLC_Broadcast_Distribution_Table_Encode(void)
&bdt_list[i], &test_bdt_list[i]); &bdt_list[i], &test_bdt_list[i]);
zassert_false(status, NULL); zassert_false(status, NULL);
} }
apdu_len = bvlc_encode_read_broadcast_distribution_table_ack(
apdu, sizeof(apdu), &bdt_list[0]);
zassert_not_equal(apdu_len, 0, NULL);
test_message_len =
test_BVLC_Header(apdu, apdu_len, &message_type, &message_length);
zassert_equal(test_message_len, 4, NULL);
zassert_equal(message_type, BVLC_READ_BROADCAST_DIST_TABLE_ACK, NULL);
test_apdu_len = bvlc_decode_read_broadcast_distribution_table_ack(
&apdu[test_message_len], apdu_len, &test_bdt_list[0]);
zassert_equal(
test_message_len + test_apdu_len, apdu_len,
"apdu_len=%u test_apdu_len=%u", apdu_len, test_apdu_len);
count = bvlc_broadcast_distribution_table_count(&test_bdt_list[0]);
zassert_equal(test_count, count, NULL);
for (i = 0; i < count; i++) {
status = bvlc_broadcast_distribution_table_entry_different(
&bdt_list[i], &test_bdt_list[i]);
zassert_false(status, NULL);
}
} }
static void test_BVLC_Write_Broadcast_Distribution_Table_Message( static void test_BVLC_Write_Broadcast_Distribution_Table_Message(
@@ -552,6 +575,8 @@ static void test_BVLC_Write_Broadcast_Distribution_Table_Message(
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *test_bdt_list = NULL; BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *test_bdt_list = NULL;
uint16_t i = 0; uint16_t i = 0;
uint16_t count = 0; uint16_t count = 0;
BACNET_IP_ADDRESS dest_address = { { 1, 1, 1, 1 }, 47808 };
bool status = false;
count = bvlc_broadcast_distribution_table_valid_count(bdt_list); count = bvlc_broadcast_distribution_table_valid_count(bdt_list);
test_bdt_list = test_bdt_list =
@@ -573,6 +598,15 @@ static void test_BVLC_Write_Broadcast_Distribution_Table_Message(
test_BVLC_Broadcast_Distribution_Table_Entry( test_BVLC_Broadcast_Distribution_Table_Entry(
&bdt_list[i], &test_bdt_list[i]); &bdt_list[i], &test_bdt_list[i]);
} }
status = bvlc_broadcast_distribution_table_entry_forward_address(
&dest_address, bdt_list);
zassert_true(status, NULL);
status = bvlc_broadcast_distribution_table_entry_forward_address(
&dest_address, NULL);
zassert_false(status, NULL);
status =
bvlc_broadcast_distribution_table_entry_forward_address(NULL, NULL);
zassert_false(status, NULL);
} }
#if defined(CONFIG_ZTEST_NEW_API) #if defined(CONFIG_ZTEST_NEW_API)
@@ -622,6 +656,10 @@ static void test_BVLC_Write_Broadcast_Distribution_Table(void)
zassert_true(status, NULL); zassert_true(status, NULL);
} }
test_BVLC_Write_Broadcast_Distribution_Table_Message(&bdt_list[0]); test_BVLC_Write_Broadcast_Distribution_Table_Message(&bdt_list[0]);
/* cleanup */
bvlc_broadcast_distribution_table_valid_clear(&bdt_list[0]);
test_count = bvlc_broadcast_distribution_table_valid_count(&bdt_list[0]);
zassert_equal(test_count, 0, NULL);
} }
static void test_BVLC_Read_Foreign_Device_Table_Ack_Message( static void test_BVLC_Read_Foreign_Device_Table_Ack_Message(
@@ -654,33 +692,28 @@ static void test_BVLC_Read_Foreign_Device_Table_Ack_Message(
} }
} }
#if defined(CONFIG_ZTEST_NEW_API) static int test_BVLC_Foreign_Device_Table_Setup(
ZTEST(bvlc_tests, test_BVLC_Read_Foreign_Device_Table_Ack) BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_list, int count)
#else
static void test_BVLC_Read_Foreign_Device_Table_Ack(void)
#endif
{ {
uint16_t i = 0; uint16_t i = 0;
uint16_t count = 0;
uint16_t test_count = 0; uint16_t test_count = 0;
uint16_t test_port_start = 0xBAC1; uint16_t test_port_start = 0xBAC1;
uint16_t ttl_seconds = 12345;
bool status = false; bool status = false;
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY fdt_list[5] = { 0 };
BACNET_IP_ADDRESS dest_address = { 0 }; BACNET_IP_ADDRESS dest_address = { 0 };
status = bvlc_address_from_ascii(&dest_address, "192.168.0.1"); status = bvlc_address_from_ascii(&dest_address, "192.168.0.1");
zassert_true(status, NULL); zassert_true(status, NULL);
/* configure a FDT entry */ /* configure a FDT entry */
count = sizeof(fdt_list) / sizeof(fdt_list[0]);
bvlc_foreign_device_table_link_array(fdt_list, count); bvlc_foreign_device_table_link_array(fdt_list, count);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
dest_address.port = test_port_start + i; dest_address.port = test_port_start + i;
status = bvlc_foreign_device_table_entry_add( status = bvlc_foreign_device_table_entry_add(
&fdt_list[0], &dest_address, 12345); fdt_list, &dest_address, ttl_seconds);
zassert_true(status, NULL); zassert_true(status, NULL);
/* add again should only update TTL */ /* add again should only update TTL */
status = bvlc_foreign_device_table_entry_add( status = bvlc_foreign_device_table_entry_add(
&fdt_list[0], &dest_address, 12345); fdt_list, &dest_address, ttl_seconds);
zassert_true(status, NULL); zassert_true(status, NULL);
} }
test_count = bvlc_foreign_device_table_count(fdt_list); test_count = bvlc_foreign_device_table_count(fdt_list);
@@ -690,15 +723,100 @@ static void test_BVLC_Read_Foreign_Device_Table_Ack(void)
} }
test_count = bvlc_foreign_device_table_valid_count(fdt_list); test_count = bvlc_foreign_device_table_valid_count(fdt_list);
zassert_equal(test_count, count, NULL); zassert_equal(test_count, count, NULL);
return count;
}
#if defined(CONFIG_ZTEST_NEW_API)
ZTEST(bvlc_tests, test_BVLC_Read_Foreign_Device_Table_Ack)
#else
static void test_BVLC_Read_Foreign_Device_Table_Ack(void)
#endif
{
uint16_t count = 0;
uint16_t test_count = 0;
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY fdt_list[5] = { 0 };
count = sizeof(fdt_list) / sizeof(fdt_list[0]);
test_count = test_BVLC_Foreign_Device_Table_Setup(fdt_list, count);
zassert_equal(test_count, count, NULL);
if (test_count != count) {
printf("size=%u count=%u\n", count, test_count);
}
test_count = bvlc_foreign_device_table_valid_count(fdt_list);
zassert_equal(test_count, count, NULL);
test_BVLC_Read_Foreign_Device_Table_Ack_Message(fdt_list); test_BVLC_Read_Foreign_Device_Table_Ack_Message(fdt_list);
/* cleanup */ /* cleanup */
for (i = 0; i < count; i++) { bvlc_foreign_device_table_valid_clear(&fdt_list[0]);
dest_address.port = test_port_start + i; test_count = bvlc_foreign_device_table_valid_count(fdt_list);
status = zassert_equal(test_count, 0, NULL);
bvlc_foreign_device_table_entry_delete(&fdt_list[0], &dest_address); }
zassert_true(status, NULL);
#if defined(CONFIG_ZTEST_NEW_API)
ZTEST(bvlc_tests, test_BVLC_Network_Port_Foreign_Device)
#else
static void test_BVLC_Network_Port_Foreign_Device(void)
#endif
{
uint8_t apdu[480] = { 0 };
int apdu_len = 0, test_apdu_len = 0;
BACNET_ERROR_CODE error_code;
uint16_t i = 0;
uint16_t count = 0;
uint16_t test_count = 0;
uint16_t test_ttl_seconds = 0;
int len;
bool status = false;
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY fdt_list[5] = { 0 },
test_fdt_list[5] = { 0 },
test_entry = { 0 };
count = sizeof(fdt_list) / sizeof(fdt_list[0]);
test_count = test_BVLC_Foreign_Device_Table_Setup(fdt_list, count);
zassert_equal(test_count, count, NULL);
if (test_count != count) {
printf("size=%u count=%u\n", count, test_count);
} }
test_count = bvlc_foreign_device_table_valid_count(fdt_list); test_count = bvlc_foreign_device_table_valid_count(fdt_list);
zassert_equal(test_count, count, NULL);
/* test the encode/decode pair */
apdu_len = bvlc_foreign_device_table_encode(apdu, sizeof(apdu), fdt_list);
zassert_not_equal(apdu_len, 0, NULL);
test_count = sizeof(test_fdt_list) / sizeof(test_fdt_list[0]);
bvlc_foreign_device_table_link_array(&test_fdt_list[0], test_count);
test_apdu_len = bvlc_foreign_device_table_decode(
&apdu[0], apdu_len, &error_code, &test_fdt_list[0]);
zassert_equal(test_apdu_len, apdu_len, NULL);
count = bvlc_foreign_device_table_count(&test_fdt_list[0]);
zassert_equal(test_count, count, NULL);
/* test timer */
test_ttl_seconds = fdt_list[0].ttl_seconds_remaining;
bvlc_foreign_device_table_maintenance_timer(fdt_list, 60);
test_ttl_seconds -= 60;
for (i = 0; i < count; i++) {
zassert_equal(
fdt_list[i].ttl_seconds_remaining, test_ttl_seconds,
"entry[%u].seconds_remaining=%u expected=%u", i,
fdt_list[i].ttl_seconds_remaining, test_ttl_seconds);
}
bvlc_foreign_device_table_maintenance_timer(fdt_list, 60);
test_ttl_seconds -= 60;
for (i = 0; i < count; i++) {
zassert_equal(
fdt_list[i].ttl_seconds_remaining, test_ttl_seconds,
"entry[%u].seconds_remaining=%u expected=%u", i,
fdt_list[i].ttl_seconds_remaining, test_ttl_seconds);
}
status = bvlc_foreign_device_table_entry_copy(&test_entry, &fdt_list[0]);
zassert_true(status, NULL);
status =
bvlc_foreign_device_table_entry_different(&fdt_list[0], &test_entry);
zassert_false(status, NULL);
len = bvlc_encode_read_foreign_device_table(NULL, 0);
zassert_equal(len, 0, NULL);
/* cleanup */
bvlc_foreign_device_table_valid_clear(&fdt_list[0]);
test_count = bvlc_foreign_device_table_valid_count(fdt_list);
zassert_equal(test_count, 0, NULL); zassert_equal(test_count, 0, NULL);
} }
@@ -811,6 +929,9 @@ static void test_BVLC_Address_Get_Set(void)
(unsigned)test_octet2, (unsigned)test_octet3); (unsigned)test_octet2, (unsigned)test_octet3);
} }
zassert_false(status, NULL); zassert_false(status, NULL);
bvlc_address_from_network(&dst, 0x7F000000);
status = bvlc_address_different(&dst, &src);
zassert_false(status, NULL);
/* BACnet to IPv4 address conversions */ /* BACnet to IPv4 address conversions */
status = bvlc_address_port_from_ascii(&src, "192.168.0.1", "0xBAC0"); status = bvlc_address_port_from_ascii(&src, "192.168.0.1", "0xBAC0");
zassert_true(status, NULL); zassert_true(status, NULL);
@@ -848,6 +969,8 @@ static void test_BVLC_Address_Get_Set(void)
zassert_equal(octet1, test_octet1, NULL); zassert_equal(octet1, test_octet1, NULL);
zassert_equal(octet2, test_octet2, NULL); zassert_equal(octet2, test_octet2, NULL);
zassert_equal(octet3, test_octet3, NULL); zassert_equal(octet3, test_octet3, NULL);
status = bvlc_address_mask(&dst, &src, &mask);
zassert_true(status, NULL);
} }
#if defined(CONFIG_ZTEST_NEW_API) #if defined(CONFIG_ZTEST_NEW_API)
@@ -907,7 +1030,8 @@ void test_main(void)
ztest_unit_test(test_BVLC_Secure_BVLL), ztest_unit_test(test_BVLC_Secure_BVLL),
ztest_unit_test(test_BVLC_Address_Copy), ztest_unit_test(test_BVLC_Address_Copy),
ztest_unit_test(test_BVLC_Address_Get_Set), ztest_unit_test(test_BVLC_Address_Get_Set),
ztest_unit_test(test_BVLC_BBMD_Address)); ztest_unit_test(test_BVLC_BBMD_Address),
ztest_unit_test(test_BVLC_Network_Port_Foreign_Device));
ztest_run_test_suite(bvlc_tests); ztest_run_test_suite(bvlc_tests);
} }