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:
@@ -50,6 +50,8 @@ static bool BVLC_NAT_Handling = false;
|
||||
static BACNET_IP_ADDRESS Remote_BBMD;
|
||||
/** if we are a foreign device, store the Time-To-Live Seconds here */
|
||||
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
|
||||
/* local buffer & length for sending */
|
||||
static uint8_t BVLC_Buffer[BIP_MPDU_MAX];
|
||||
@@ -873,6 +875,22 @@ int bvlc_bbmd_enabled_handler(
|
||||
}
|
||||
break;
|
||||
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);
|
||||
function_len = bvlc_decode_write_broadcast_distribution_table(
|
||||
pdu, pdu_len, &BBMD_Table[0]);
|
||||
@@ -886,6 +904,7 @@ int bvlc_bbmd_enabled_handler(
|
||||
BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK;
|
||||
send_result = true;
|
||||
}
|
||||
#endif
|
||||
/* not an NPDU */
|
||||
offset = 0;
|
||||
break;
|
||||
@@ -971,6 +990,13 @@ int bvlc_bbmd_enabled_handler(
|
||||
without the receipt of another BVLL Register-Foreign-Device
|
||||
message from the same foreign device, the FDT entry for this
|
||||
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 =
|
||||
bvlc_decode_register_foreign_device(pdu, pdu_len, &ttl_seconds);
|
||||
if (function_len) {
|
||||
@@ -1203,6 +1229,25 @@ int bvlc_broadcast_handler(
|
||||
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
|
||||
/** Register as a foreign device with the indicated BBMD.
|
||||
* @param bbmd_addr - IPv4 address of BBMD with which to register
|
||||
|
||||
@@ -98,6 +98,11 @@ void bvlc_remote_bbmd_address(BACNET_IP_ADDRESS *address);
|
||||
BACNET_STACK_EXPORT
|
||||
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.
|
||||
* The interface user needs to handle mutual exclusion if needed i.e.
|
||||
* BACnet packet is not being handled when the BBMD table is modified.
|
||||
|
||||
@@ -1869,6 +1869,110 @@ static int BBMD_Broadcast_Distribution_Table_Encode(
|
||||
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
|
||||
* property value
|
||||
@@ -1980,6 +2084,108 @@ static int BBMD_Foreign_Device_Table_Encode(
|
||||
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
|
||||
* @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 */
|
||||
int len = 0;
|
||||
uint32_t capacity;
|
||||
BACNET_APPLICATION_DATA_VALUE value = { 0 };
|
||||
|
||||
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);
|
||||
}
|
||||
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:
|
||||
if (Property_List_Member(
|
||||
wp_data->object_instance, wp_data->object_property)) {
|
||||
|
||||
+216
-30
@@ -356,6 +356,37 @@ bool bvlc_broadcast_distribution_table_entry_append(
|
||||
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
|
||||
* @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 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(
|
||||
const uint8_t *pdu,
|
||||
uint16_t pdu_len,
|
||||
uint16_t pdu_size,
|
||||
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_list)
|
||||
{
|
||||
int bytes_consumed = 0;
|
||||
int len = 0;
|
||||
uint16_t offset = 0;
|
||||
uint16_t pdu_bytes = 0;
|
||||
uint16_t pdu_len = 0;
|
||||
uint16_t bdt_entry_count = 0;
|
||||
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_entry = NULL;
|
||||
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);
|
||||
list_len = bdt_entry_count * BACNET_IP_BDT_ENTRY_SIZE;
|
||||
/* 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;
|
||||
while (bdt_entry) {
|
||||
pdu_bytes = pdu_len - offset;
|
||||
if (pdu_bytes >= BACNET_IP_BDT_ENTRY_SIZE) {
|
||||
if (pdu_len < pdu_size) {
|
||||
/* decode valid entries */
|
||||
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) {
|
||||
pdu_len += len;
|
||||
bdt_entry->valid = true;
|
||||
} else {
|
||||
/* set the available entries as invalid */
|
||||
bdt_entry->valid = false;
|
||||
}
|
||||
offset += len;
|
||||
} else {
|
||||
/* set the available entries as invalid */
|
||||
bdt_entry->valid = false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
@@ -1461,6 +1590,53 @@ bool bvlc_foreign_device_table_entry_add(
|
||||
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
|
||||
* @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->port = src->port;
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -2569,37 +2746,46 @@ int bvlc_encode_broadcast_distribution_table_entry(
|
||||
* IP subnet served by the BBMD
|
||||
*
|
||||
* @param pdu - buffer from which to decode the message
|
||||
* @param pdu_len - length of the buffer that needs decoding
|
||||
* @param bdt_entry - BDT Entry
|
||||
* @param pdu_size - length of the buffer that needs decoding
|
||||
* @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(
|
||||
const uint8_t *pdu,
|
||||
uint16_t pdu_len,
|
||||
uint16_t pdu_size,
|
||||
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_entry)
|
||||
{
|
||||
int bytes_consumed = 0;
|
||||
int pdu_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 (bdt_entry) {
|
||||
len = bvlc_decode_address(
|
||||
&pdu[offset], pdu_len - offset, &bdt_entry->dest_address);
|
||||
if (len > 0) {
|
||||
offset += len;
|
||||
len = bvlc_decode_broadcast_distribution_mask(
|
||||
&pdu[offset], pdu_len - offset, &bdt_entry->broadcast_mask);
|
||||
if (pdu) {
|
||||
len = bvlc_decode_address(
|
||||
&pdu[pdu_len], pdu_size - pdu_len, &dest_address);
|
||||
if (len > 0) {
|
||||
pdu_len += len;
|
||||
if (bdt_entry) {
|
||||
bvlc_address_copy(&bdt_entry->dest_address, &dest_address);
|
||||
}
|
||||
if (len > 0) {
|
||||
offset += len;
|
||||
bytes_consumed = offset;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -272,6 +272,12 @@ bool bvlc_broadcast_distribution_table_entry_append(
|
||||
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *bdt_list,
|
||||
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
|
||||
bool bvlc_broadcast_distribution_table_entry_set(
|
||||
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_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(
|
||||
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,
|
||||
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
|
||||
int bvlc_encode_foreign_device_table_entry(
|
||||
uint8_t *pdu,
|
||||
@@ -435,6 +450,11 @@ int bvlc_foreign_device_table_encode(
|
||||
uint8_t *apdu,
|
||||
uint16_t apdu_size,
|
||||
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
|
||||
int bvlc_encode_read_foreign_device_table(uint8_t *pdu, uint16_t pdu_size);
|
||||
|
||||
@@ -321,6 +321,38 @@ static int bbmd6_register_as_foreign_device(void)
|
||||
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
|
||||
*/
|
||||
@@ -401,6 +433,8 @@ static void dlenv_network_port_bip_init(uint32_t instance)
|
||||
instance, addr0, addr1, addr2, addr3);
|
||||
Network_Port_Remote_BBMD_BIP_Port_Set(instance, BBMD_Address.port);
|
||||
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
|
||||
/* common NP data */
|
||||
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
|
||||
since they are already set */
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -97,13 +97,14 @@ static void test_BVLC_Result_Code(uint16_t result_code)
|
||||
int len = 0, test_len = 0;
|
||||
|
||||
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);
|
||||
zassert_equal(test_len, 4, NULL);
|
||||
zassert_equal(message_type, BVLC_RESULT, NULL);
|
||||
zassert_equal(length, 6, NULL);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -493,6 +494,9 @@ static void test_BVLC_Broadcast_Distribution_Table_Encode(void)
|
||||
uint16_t i = 0;
|
||||
uint16_t 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;
|
||||
BACNET_ERROR_CODE error_code;
|
||||
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]);
|
||||
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(
|
||||
@@ -552,6 +575,8 @@ static void test_BVLC_Write_Broadcast_Distribution_Table_Message(
|
||||
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *test_bdt_list = NULL;
|
||||
uint16_t i = 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);
|
||||
test_bdt_list =
|
||||
@@ -573,6 +598,15 @@ static void test_BVLC_Write_Broadcast_Distribution_Table_Message(
|
||||
test_BVLC_Broadcast_Distribution_Table_Entry(
|
||||
&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)
|
||||
@@ -622,6 +656,10 @@ static void test_BVLC_Write_Broadcast_Distribution_Table(void)
|
||||
zassert_true(status, NULL);
|
||||
}
|
||||
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(
|
||||
@@ -654,33 +692,28 @@ static void test_BVLC_Read_Foreign_Device_Table_Ack_Message(
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
||||
static int test_BVLC_Foreign_Device_Table_Setup(
|
||||
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *fdt_list, int count)
|
||||
{
|
||||
uint16_t i = 0;
|
||||
uint16_t count = 0;
|
||||
uint16_t test_count = 0;
|
||||
uint16_t test_port_start = 0xBAC1;
|
||||
uint16_t ttl_seconds = 12345;
|
||||
bool status = false;
|
||||
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY fdt_list[5] = { 0 };
|
||||
BACNET_IP_ADDRESS dest_address = { 0 };
|
||||
|
||||
status = bvlc_address_from_ascii(&dest_address, "192.168.0.1");
|
||||
zassert_true(status, NULL);
|
||||
/* configure a FDT entry */
|
||||
count = sizeof(fdt_list) / sizeof(fdt_list[0]);
|
||||
bvlc_foreign_device_table_link_array(fdt_list, count);
|
||||
for (i = 0; i < count; i++) {
|
||||
dest_address.port = test_port_start + i;
|
||||
status = bvlc_foreign_device_table_entry_add(
|
||||
&fdt_list[0], &dest_address, 12345);
|
||||
fdt_list, &dest_address, ttl_seconds);
|
||||
zassert_true(status, NULL);
|
||||
/* add again should only update TTL */
|
||||
status = bvlc_foreign_device_table_entry_add(
|
||||
&fdt_list[0], &dest_address, 12345);
|
||||
fdt_list, &dest_address, ttl_seconds);
|
||||
zassert_true(status, NULL);
|
||||
}
|
||||
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);
|
||||
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);
|
||||
/* cleanup */
|
||||
for (i = 0; i < count; i++) {
|
||||
dest_address.port = test_port_start + i;
|
||||
status =
|
||||
bvlc_foreign_device_table_entry_delete(&fdt_list[0], &dest_address);
|
||||
zassert_true(status, NULL);
|
||||
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);
|
||||
}
|
||||
|
||||
#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);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -811,6 +929,9 @@ static void test_BVLC_Address_Get_Set(void)
|
||||
(unsigned)test_octet2, (unsigned)test_octet3);
|
||||
}
|
||||
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 */
|
||||
status = bvlc_address_port_from_ascii(&src, "192.168.0.1", "0xBAC0");
|
||||
zassert_true(status, NULL);
|
||||
@@ -848,6 +969,8 @@ static void test_BVLC_Address_Get_Set(void)
|
||||
zassert_equal(octet1, test_octet1, NULL);
|
||||
zassert_equal(octet2, test_octet2, NULL);
|
||||
zassert_equal(octet3, test_octet3, NULL);
|
||||
status = bvlc_address_mask(&dst, &src, &mask);
|
||||
zassert_true(status, NULL);
|
||||
}
|
||||
|
||||
#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_Address_Copy),
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user