Feature/apdu null length returned (#285)

* Add APDU as NULL to get BACnet type lengths.

* Fix bacapp copy test to succeed

* fix BACnet REAL and DOUBLE decode

* Add unit test for NULL APDU encoding for length

* Add unit tests for bacapp context

* refactor host-n-port to hostnport.c module

* fix BVLC decoder

* additional unit testing for bacapp

* include bacdevobjpropref module in builds

* simplify bacapp snprintf to be able to return length

* adjust compiler for variable-length arrays

* fix bug found by scan-build

Authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
Steve Karg
2022-06-01 15:42:50 -05:00
committed by GitHub
parent 810bfefb34
commit f147283293
76 changed files with 3474 additions and 2791 deletions
+25 -105
View File
@@ -39,6 +39,7 @@
#include "bacnet/bacdcode.h"
#include "bacnet/bacint.h"
#include "bacnet/bacdef.h"
#include "bacnet/hostnport.h"
#include "bacnet/datalink/bvlc.h"
/**
@@ -2623,15 +2624,6 @@ const char *bvlc_result_code_name(uint16_t result_code)
/**
* @brief Encode a BBMD Address for Network Port object
*
* BACnetHostNPort ::= SEQUENCE {
* host [0] BACnetHostAddress,
* BACnetHostAddress ::= CHOICE {
* ip-address [1] OCTET STRING, -- 4 octets for B/IP
* }
* port [1] Unsigned16
* }
*
* @param apdu - the APDU buffer
* @param apdu_size - the APDU buffer size
* @param ip_address - IP address and port number
@@ -2641,27 +2633,17 @@ int bvlc_foreign_device_bbmd_host_address_encode(uint8_t *apdu,
uint16_t apdu_size,
BACNET_IP_ADDRESS *ip_address)
{
int len = 0;
BACNET_HOST_N_PORT address = { 0 };
int apdu_len = 0;
BACNET_OCTET_STRING octet_string;
if (apdu && (apdu_size >= 9) && ip_address) {
/* host [0] BACnetHostAddress - opening */
len = encode_opening_tag(&apdu[apdu_len], 0);
apdu_len += len;
/* CHOICE - ip-address [1] OCTET STRING */
octetstring_init(&octet_string,
&ip_address->address[0], IP_ADDRESS_MAX);
len = encode_context_octet_string(&apdu[apdu_len], 1,
&octet_string);
apdu_len += len;
/* host [0] BACnetHostAddress - closing */
len = encode_closing_tag(&apdu[apdu_len], 0);
apdu_len += len;
/* port [1] Unsigned16 */
len = encode_context_unsigned(
&apdu[apdu_len], 1, ip_address->port);
apdu_len += len;
address.host_ip_address = true;
address.host_name = false;
octetstring_init(&address.host.ip_address, &ip_address->address[0],
IP_ADDRESS_MAX);
address.port = ip_address->port;
apdu_len = host_n_port_encode(NULL, &address);
if (apdu_len <= apdu_size) {
apdu_len = host_n_port_encode(apdu, &address);
}
return apdu_len;
@@ -2669,15 +2651,6 @@ int bvlc_foreign_device_bbmd_host_address_encode(uint8_t *apdu,
/**
* @brief Decode the Broadcast-Distribution-Table for Network Port object
*
* BACnetHostNPort ::= SEQUENCE {
* host [0] BACnetHostAddress,
* BACnetHostAddress ::= CHOICE {
* ip-address [1] OCTET STRING, -- 4 octets for B/IP
* }
* port [1] Unsigned16
* }
*
* @param apdu - the APDU buffer
* @param apdu_len - the APDU buffer length
* @param ip_address - IP address and port number
@@ -2688,77 +2661,24 @@ int bvlc_foreign_device_bbmd_host_address_decode(uint8_t *apdu,
BACNET_ERROR_CODE *error_code,
BACNET_IP_ADDRESS *ip_address)
{
BACNET_HOST_N_PORT address = { 0 };
int len = 0;
BACNET_OCTET_STRING octet_string = { 0 };
uint8_t tag_number = 0;
uint32_t len_value_type = 0;
BACNET_UNSIGNED_INTEGER unsigned_value = 0;
/* default reject code */
if (error_code) {
*error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
}
/* check for value pointers */
if ((apdu_len == 0) || (!apdu)) {
return BACNET_STATUS_REJECT;
}
/* host [0] BACnetHostAddress - opening */
if (!decode_is_opening_tag_number(&apdu[len++], 0)) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
len = host_n_port_decode(apdu, apdu_len, error_code, &address);
if (len > 0) {
if (address.host_ip_address) {
ip_address->port = address.port;
(void)octetstring_copy_value(
&ip_address->address[0],
IP_ADDRESS_MAX,
&address.host.ip_address);
} else {
len = BACNET_STATUS_REJECT;
if (error_code) {
*error_code = ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE;
}
}
return BACNET_STATUS_REJECT;
}
if (len > apdu_len) {
return BACNET_STATUS_REJECT;
}
/* CHOICE - ip-address [1] OCTET STRING */
len += decode_tag_number_and_value(
&apdu[len], &tag_number, &len_value_type);
if (tag_number != 1) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
}
return BACNET_STATUS_REJECT;
}
len += decode_octet_string(&apdu[len], len_value_type,
&octet_string);
if (len > apdu_len) {
return BACNET_STATUS_REJECT;
}
(void)octetstring_copy_value(&ip_address->address[0],
IP_ADDRESS_MAX, &octet_string);
/* host [0] BACnetHostAddress - closing */
if (!decode_is_closing_tag_number(&apdu[len++], 0)) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
}
return BACNET_STATUS_REJECT;
}
if (len > apdu_len) {
return BACNET_STATUS_REJECT;
}
/* port [1] Unsigned16 */
len += decode_tag_number_and_value(
&apdu[len], &tag_number, &len_value_type);
if (tag_number != 1) {
if (error_code) {
*error_code = ERROR_CODE_REJECT_INVALID_TAG;
}
return BACNET_STATUS_REJECT;
}
len += decode_unsigned(&apdu[len], len_value_type, &unsigned_value);
if (len > apdu_len) {
return BACNET_STATUS_REJECT;
}
if (unsigned_value <= UINT16_MAX) {
ip_address->port = unsigned_value;
} else {
if (error_code) {
*error_code = ERROR_CODE_REJECT_PARAMETER_OUT_OF_RANGE;
}
return BACNET_STATUS_REJECT;
}
return apdu_len;
return len;
}
+1 -1
View File
@@ -55,7 +55,7 @@ typedef struct dlmstp_statistics {
} DLMSTP_STATISTICS;
/* callback to signify the receipt of a preamble */
typedef void (*dlmstp_hook_frame_rx_start_cb)();
typedef void (*dlmstp_hook_frame_rx_start_cb)(void);
/* callback on for receiving every valid frame */
typedef void (*dlmstp_hook_frame_rx_complete_cb)(