Fixed EPICS values for recipient list, empty lists, and authentication factors (#1310)
* Add BACnet authentication factor support with comparison functions and text strings and parsing * Fix MyReadPropertyAckHandler to allow zero length for empty property list * Fix rp_ack_fully_decode_service_request to handle empty recipient list * Enhance PrintReadPropertyArray to handle empty lists with improved output formatting * Refactor command line argument handling for target-address to accept dotted IP if offered. * This commit introduces the inclusion of `authentication_factor.c` and `authentication_factor_format.c` in the CMakeLists.txt files for multiple BACnet tests to fix the broken test builds. * Refactor bacapp.c for improved readability and documentation; streamline code formatting and enhance function comments. * Fix return value assignment in bacapp_snprintf_value for authentication format * Enhance help message to clarify target MAC or IP address format and improve readability * Implement memory management for ReadProperty ACK service requests and improve error handling in decoding
This commit is contained in:
@@ -205,3 +205,25 @@ int bacapp_decode_context_authentication_factor(
|
||||
return bacnet_authentication_factor_context_decode(apdu, MAX_APDU, tag, af);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Compare two BACnetAuthenticationFactor values for equality
|
||||
* @param value Pointer to the first value to compare
|
||||
* @param test_value Pointer to the second value to compare
|
||||
* @return true if the values are the same, false otherwise
|
||||
*/
|
||||
bool bacnet_authentication_factor_same(
|
||||
const BACNET_AUTHENTICATION_FACTOR *value,
|
||||
const BACNET_AUTHENTICATION_FACTOR *test_value)
|
||||
{
|
||||
if (value == NULL || test_value == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (value->format_type != test_value->format_type) {
|
||||
return false;
|
||||
}
|
||||
if (value->format_class != test_value->format_class) {
|
||||
return false;
|
||||
}
|
||||
return octetstring_value_same(&value->value, &test_value->value);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
/* BACnet Stack defines - first */
|
||||
#include "bacnet/bacdef.h"
|
||||
/* BACnet Stack API */
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/bacstr.h"
|
||||
|
||||
typedef struct BACnetAuthenticationFactor {
|
||||
BACNET_AUTHENTICATION_FACTOR_TYPE format_type;
|
||||
@@ -51,6 +51,10 @@ BACNET_STACK_DEPRECATED(
|
||||
BACNET_STACK_EXPORT
|
||||
int bacapp_decode_context_authentication_factor(
|
||||
const uint8_t *apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR *af);
|
||||
BACNET_STACK_EXPORT
|
||||
bool bacnet_authentication_factor_same(
|
||||
const BACNET_AUTHENTICATION_FACTOR *value,
|
||||
const BACNET_AUTHENTICATION_FACTOR *test_value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -223,3 +223,34 @@ int bacapp_decode_context_authentication_factor_format(
|
||||
apdu, MAX_APDU, tag, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Compare two BACNET_AUTHENTICATION_FACTOR_FORMAT structures
|
||||
* @param data1 Pointer to the first structure to compare
|
||||
* @param data2 Pointer to the second structure to compare
|
||||
* @return true if the structures are the same, false otherwise
|
||||
* @details The structures are considered the same if they have the same format
|
||||
* type, and if the format type is CUSTOM, they must also have the same vendor
|
||||
* ID and vendor format.
|
||||
*/
|
||||
bool bacnet_authentication_factor_format_same(
|
||||
const BACNET_AUTHENTICATION_FACTOR_FORMAT *data1,
|
||||
const BACNET_AUTHENTICATION_FACTOR_FORMAT *data2)
|
||||
{
|
||||
if (!data1 || !data2) {
|
||||
return false;
|
||||
}
|
||||
if (data1->format_type != data2->format_type) {
|
||||
return false;
|
||||
}
|
||||
if (data1->format_type == AUTHENTICATION_FACTOR_CUSTOM) {
|
||||
if (data1->vendor_id != data2->vendor_id) {
|
||||
return false;
|
||||
}
|
||||
if (data1->vendor_format != data2->vendor_format) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,11 @@ int bacapp_decode_context_authentication_factor_format(
|
||||
uint8_t tag_number,
|
||||
BACNET_AUTHENTICATION_FACTOR_FORMAT *aff);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool bacnet_authentication_factor_format_same(
|
||||
const BACNET_AUTHENTICATION_FACTOR_FORMAT *data1,
|
||||
const BACNET_AUTHENTICATION_FACTOR_FORMAT *data2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
+173
-5
@@ -409,6 +409,18 @@ int bacapp_encode_application_data(
|
||||
apdu_len = bacnet_timer_value_no_value_encode(apdu);
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_AUTHENTICATION)
|
||||
case BACNET_APPLICATION_TAG_AUTHENTICATION_FORMAT:
|
||||
/* BACnetAuthenticationFactorFormat */
|
||||
apdu_len = bacapp_encode_authentication_factor_format(
|
||||
apdu, &value->type.Authentication_Format);
|
||||
break;
|
||||
case BACNET_APPLICATION_TAG_AUTHENTICATION_FACTOR:
|
||||
/* BACnetAuthenticationFactor */
|
||||
apdu_len = bacapp_encode_authentication_factor(
|
||||
apdu, &value->type.Authentication_Factor);
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_LOG_RECORD)
|
||||
case BACNET_APPLICATION_TAG_LOG_RECORD:
|
||||
/* BACnetLogRecord */
|
||||
@@ -1138,6 +1150,9 @@ int bacapp_known_property_tag(
|
||||
} else if (object_type == OBJECT_CHANNEL) {
|
||||
/* Properties using BACnetChannelValue */
|
||||
return BACNET_APPLICATION_TAG_CHANNEL_VALUE;
|
||||
} else if (object_type == OBJECT_CREDENTIAL_DATA_INPUT) {
|
||||
/* Properties using BACnetAuthenticationFactor */
|
||||
return BACNET_APPLICATION_TAG_AUTHENTICATION_FACTOR;
|
||||
}
|
||||
/* note: primitive application tagged present-values return '-1' */
|
||||
return -1;
|
||||
@@ -1193,7 +1208,9 @@ int bacapp_known_property_tag(
|
||||
case PROP_SLAVE_ADDRESS_BINDING:
|
||||
/* BACnetAddressBinding */
|
||||
return BACNET_APPLICATION_TAG_ADDRESS_BINDING;
|
||||
|
||||
case PROP_SUPPORTED_FORMATS:
|
||||
/* BACnetAuthenticationFactorFormat */
|
||||
return BACNET_APPLICATION_TAG_AUTHENTICATION_FORMAT;
|
||||
case PROP_LOG_BUFFER:
|
||||
/* BACnetLogRecord */
|
||||
return BACNET_APPLICATION_TAG_LOG_RECORD;
|
||||
@@ -1573,6 +1590,19 @@ int bacapp_decode_application_tag_value(
|
||||
apdu, apdu_size, &value->type.Address_Binding);
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_AUTHENTICATION)
|
||||
case BACNET_APPLICATION_TAG_AUTHENTICATION_FORMAT:
|
||||
/* BACnetAuthenticationFactorFormat */
|
||||
apdu_len = bacnet_authentication_factor_format_decode(
|
||||
apdu, apdu_size, &value->type.Authentication_Format);
|
||||
break;
|
||||
case BACNET_APPLICATION_TAG_AUTHENTICATION_FACTOR:
|
||||
/* BACnetAuthenticationFactor */
|
||||
apdu_len = bacnet_authentication_factor_decode(
|
||||
apdu, apdu_size, &value->type.Authentication_Factor);
|
||||
break;
|
||||
|
||||
#endif
|
||||
#if defined(BACAPP_LOG_RECORD)
|
||||
case BACNET_APPLICATION_TAG_LOG_RECORD:
|
||||
/* BACnetLogRecord */
|
||||
@@ -1629,7 +1659,7 @@ int bacapp_decode_known_array_property(
|
||||
int apdu_len = 0;
|
||||
int tag;
|
||||
|
||||
if (bacnet_is_closing_tag(apdu, apdu_size)) {
|
||||
if ((apdu_size == 0) || bacnet_is_closing_tag(apdu, apdu_size)) {
|
||||
if (value) {
|
||||
value->tag = BACNET_APPLICATION_TAG_EMPTYLIST;
|
||||
}
|
||||
@@ -3755,6 +3785,29 @@ static int bacapp_snprintf_action_command(
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BACAPP_AUTHENTICATION)
|
||||
int bacapp_snprintf_authentication_factor(
|
||||
char *str, size_t str_len, const BACNET_AUTHENTICATION_FACTOR *value)
|
||||
{
|
||||
int slen;
|
||||
int ret_val = 0;
|
||||
|
||||
slen = bacapp_snprintf(str, str_len, "{");
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
slen = bacapp_snprintf(
|
||||
str, str_len, "%s,%lu,",
|
||||
bactext_authentication_factor_type_name(value->format_type),
|
||||
(unsigned long)value->format_class);
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
slen = bacapp_snprintf_octet_string(str, str_len, &value->value);
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
slen = bacapp_snprintf(str, str_len, "}");
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Extract the value into a text string
|
||||
* @param str - the buffer to store the extracted value, or NULL for length
|
||||
@@ -4053,6 +4106,22 @@ int bacapp_snprintf_value(
|
||||
ret_val = bacnet_timer_value_no_value_to_ascii(str, str_len);
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_AUTHENTICATION)
|
||||
case BACNET_APPLICATION_TAG_AUTHENTICATION_FORMAT:
|
||||
ret_val = bacapp_snprintf(
|
||||
str, str_len, "{%s,%lu,%lu}",
|
||||
bactext_authentication_factor_type_name(
|
||||
value->type.Authentication_Format.format_type),
|
||||
(unsigned long)value->type.Authentication_Format.vendor_id,
|
||||
(unsigned long)
|
||||
value->type.Authentication_Format.vendor_format);
|
||||
break;
|
||||
case BACNET_APPLICATION_TAG_AUTHENTICATION_FACTOR:
|
||||
/* BACnetAuthenticationFactor */
|
||||
ret_val = bacapp_snprintf_authentication_factor(
|
||||
str, str_len, &value->type.Authentication_Factor);
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_LOG_RECORD)
|
||||
case BACNET_APPLICATION_TAG_LOG_RECORD:
|
||||
ret_val = bacapp_snprintf_log_record(
|
||||
@@ -4798,9 +4867,82 @@ special_event_from_ascii(BACNET_APPLICATION_DATA_VALUE *value, char *str)
|
||||
}
|
||||
#endif /* BACAPP_SPECIAL_EVENT */
|
||||
|
||||
/* used to load the app data struct with the proper data
|
||||
converted from a command line argument.
|
||||
"argv" is not const to allow using strtok internally. It MAY be modified. */
|
||||
#if defined(BACAPP_AUTHENTICATION)
|
||||
/**
|
||||
* @brief Parse a string into a BACnetAuthenticationFactorFormat value
|
||||
* @param value [out] The BACnetAuthenticationFactorFormat value
|
||||
* @param argv [in] The string to parse
|
||||
* @return True on success, else False
|
||||
*/
|
||||
static bool bacnet_authentication_format_from_ascii(
|
||||
BACNET_AUTHENTICATION_FACTOR_FORMAT *value, const char *argv)
|
||||
{
|
||||
bool status = false;
|
||||
int count;
|
||||
unsigned long format_type, vendor_id, vendor_format;
|
||||
|
||||
if (!status) {
|
||||
count = sscanf(
|
||||
argv, "%lu,%lu,%lu", &format_type, &vendor_id, &vendor_format);
|
||||
if (count == 3) {
|
||||
/* optional fields are required when Format-Type
|
||||
field has a value of CUSTOM. */
|
||||
value->format_type = (BACNET_AUTHENTICATION_FACTOR_TYPE)format_type;
|
||||
value->vendor_id = (uint32_t)vendor_id;
|
||||
value->vendor_format = (uint32_t)vendor_format;
|
||||
status = true;
|
||||
} else if (count == 1) {
|
||||
value->format_type = (BACNET_AUTHENTICATION_FACTOR_TYPE)format_type;
|
||||
value->vendor_id = 0;
|
||||
value->vendor_format = 0;
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
/**
|
||||
* @brief Parse a string into a BACnetAuthenticationFactor value
|
||||
* @param value [out] The BACnetAuthenticationFactor value
|
||||
* @param argv [in] The string to parse
|
||||
* @return True on success, else False
|
||||
*/
|
||||
static bool bacnet_authentication_factor_from_ascii(
|
||||
BACNET_AUTHENTICATION_FACTOR *value, const char *argv)
|
||||
{
|
||||
bool status = false;
|
||||
int count;
|
||||
unsigned long format_type, format_class;
|
||||
char factor_value[256] = { 0 };
|
||||
|
||||
count = sscanf(
|
||||
argv, "%lu,%lu,%255s", &format_type, &format_class, factor_value);
|
||||
if (count == 3) {
|
||||
value->format_type = (BACNET_AUTHENTICATION_FACTOR_TYPE)format_type;
|
||||
value->format_class = (uint32_t)format_class;
|
||||
octetstring_init_ascii_epics(&value->value, factor_value);
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Load the app data struct with the proper data converted from a command
|
||||
* line argument. "argv" is not const to allow using strtok internally. It MAY
|
||||
* be modified.
|
||||
* @param tag_number The expected application tag number of the value to parse.
|
||||
* This is used to determine how to parse the argv string.
|
||||
* @param argv The string to parse into the value struct. This is typically a
|
||||
* command line argument, and may be modified by this function.
|
||||
* @param value [out] The BACNET_APPLICATION_DATA_VALUE struct to load with the
|
||||
* parsed value. The tag field will be set to tag_number, and the type field
|
||||
* will be set based on the tag. The value field will be set to the parsed value
|
||||
* from argv.
|
||||
* @return true if the data was successfully parsed and loaded into the value
|
||||
* struct, else false
|
||||
*/
|
||||
bool bacapp_parse_application_data(
|
||||
BACNET_APPLICATION_TAG tag_number,
|
||||
char *argv,
|
||||
@@ -5108,6 +5250,18 @@ bool bacapp_parse_application_data(
|
||||
bacnet_timer_value_no_value_from_ascii(&value->tag, argv);
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_AUTHENTICATION)
|
||||
case BACNET_APPLICATION_TAG_AUTHENTICATION_FORMAT:
|
||||
/* BACnetAuthenticationFactorFormat */
|
||||
status = bacnet_authentication_format_from_ascii(
|
||||
&value->type.Authentication_Format, argv);
|
||||
break;
|
||||
case BACNET_APPLICATION_TAG_AUTHENTICATION_FACTOR:
|
||||
/* BACnetAuthenticationFactor */
|
||||
status = bacnet_authentication_factor_from_ascii(
|
||||
&value->type.Authentication_Factor, argv);
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_LOG_RECORD)
|
||||
case BACNET_APPLICATION_TAG_LOG_RECORD:
|
||||
status = bacnet_log_record_datum_from_ascii(
|
||||
@@ -5876,6 +6030,20 @@ bool bacapp_same_value(
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_AUTHENTICATION)
|
||||
case BACNET_APPLICATION_TAG_AUTHENTICATION_FORMAT:
|
||||
/* BACnetAuthenticationFactorFormat */
|
||||
status = bacnet_authentication_factor_format_same(
|
||||
&value->type.Authentication_Format,
|
||||
&test_value->type.Authentication_Format);
|
||||
break;
|
||||
case BACNET_APPLICATION_TAG_AUTHENTICATION_FACTOR:
|
||||
/* BACnetAuthenticationFactor */
|
||||
status = bacnet_authentication_factor_same(
|
||||
&value->type.Authentication_Factor,
|
||||
&test_value->type.Authentication_Factor);
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_LOG_RECORD)
|
||||
case BACNET_APPLICATION_TAG_LOG_RECORD:
|
||||
status = bacnet_log_record_same(
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "bacnet/bacdef.h"
|
||||
/* BACnet Stack API */
|
||||
#include "bacnet/access_rule.h"
|
||||
#include "bacnet/authentication_factor.h"
|
||||
#include "bacnet/authentication_factor_format.h"
|
||||
#include "bacnet/bacaction.h"
|
||||
#include "bacnet/bacaddr.h"
|
||||
#include "bacnet/bacdest.h"
|
||||
@@ -185,6 +187,10 @@ typedef struct BACnet_Application_Data_Value {
|
||||
BACNET_SC_HUB_FUNCTION_CONNECTION_STATUS SC_Hub_Function_Status;
|
||||
BACNET_SC_DIRECT_CONNECTION_STATUS SC_Direct_Status;
|
||||
BACNET_SC_HUB_CONNECTION_STATUS SC_Hub_Status;
|
||||
#endif
|
||||
#if defined(BACAPP_AUTHENTICATION)
|
||||
BACNET_AUTHENTICATION_FACTOR_FORMAT Authentication_Format;
|
||||
BACNET_AUTHENTICATION_FACTOR Authentication_Factor;
|
||||
#endif
|
||||
} type;
|
||||
/* simple linked list if needed */
|
||||
|
||||
@@ -1705,6 +1705,10 @@ typedef enum {
|
||||
BACNET_APPLICATION_TAG_ADDRESS_BINDING,
|
||||
/* no-value - context tagged null */
|
||||
BACNET_APPLICATION_TAG_NO_VALUE,
|
||||
/* BACnetAuthenticationFactorFormat */
|
||||
BACNET_APPLICATION_TAG_AUTHENTICATION_FORMAT,
|
||||
/* BACnetAuthenticationFactor */
|
||||
BACNET_APPLICATION_TAG_AUTHENTICATION_FACTOR,
|
||||
/* ABSTRACT-SYNTAX - constructed value */
|
||||
BACNET_APPLICATION_TAG_ABSTRACT_SYNTAX,
|
||||
/* == mark the end of this list == */
|
||||
@@ -2965,10 +2969,14 @@ typedef enum BACnetAuthenticationDisableReason {
|
||||
AUTHENTICATION_DISABLED_STOLEN = 3,
|
||||
AUTHENTICATION_DISABLED_DAMAGED = 4,
|
||||
AUTHENTICATION_DISABLED_DESTROYED = 5,
|
||||
AUTHENTICATION_DISABLED_MAX = 6
|
||||
AUTHENTICATION_DISABLED_MAX = 6,
|
||||
AUTHENTICATION_DISABLED_RESERVED_MIN = 6,
|
||||
AUTHENTICATION_DISABLED_RESERVED_MAX = 63,
|
||||
/* Enumerated values 0-63 are reserved for definition by ASHRAE.
|
||||
Enumerated values 64-65535 may be used by others subject to
|
||||
the procedures and constraints described in Clause 23. */
|
||||
AUTHENTICATION_DISABLED_PROPRIETARY_MIN = 64,
|
||||
AUTHENTICATION_DISABLED_PROPRIETARY_MAX = 65535
|
||||
} BACNET_AUTHENTICATION_DISABLE_REASON;
|
||||
|
||||
typedef enum BACnetAuthenticationFactorType {
|
||||
|
||||
@@ -191,6 +191,10 @@ INDTEXT_DATA bacnet_application_tag_names[] = {
|
||||
{ BACNET_APPLICATION_TAG_TIMER_VALUE, "BACnetTimerStateChangeValue" },
|
||||
{ BACNET_APPLICATION_TAG_ADDRESS_BINDING, "BACnetAddressBinding" },
|
||||
{ BACNET_APPLICATION_TAG_NO_VALUE, "BACnetNoValue" },
|
||||
{ BACNET_APPLICATION_TAG_AUTHENTICATION_FORMAT,
|
||||
"BACnetAuthenticationFormat" },
|
||||
{ BACNET_APPLICATION_TAG_AUTHENTICATION_FACTOR,
|
||||
"BACnetAuthenticationFactor" },
|
||||
{ BACNET_APPLICATION_TAG_ABSTRACT_SYNTAX, "ABSTRACT-SYNTAX" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
@@ -3379,6 +3383,65 @@ const char *bactext_authentication_status_name(uint32_t index)
|
||||
bactext_authentication_status_names, index, ASHRAE_Reserved_String);
|
||||
}
|
||||
|
||||
INDTEXT_DATA bactext_authentication_disable_reason_names[] = {
|
||||
/* BACnetAuthenticationDisableReason enumerations */
|
||||
{ AUTHENTICATION_NONE, "none" },
|
||||
{ AUTHENTICATION_DISABLED, "disabled" },
|
||||
{ AUTHENTICATION_DISABLED_LOST, "lost" },
|
||||
{ AUTHENTICATION_DISABLED_STOLEN, "stolen" },
|
||||
{ AUTHENTICATION_DISABLED_DAMAGED, "damaged" },
|
||||
{ AUTHENTICATION_DISABLED_DESTROYED, "destroyed" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
const char *bactext_authentication_disable_reason_name(uint32_t index)
|
||||
{
|
||||
/* Enumerated values 0-63 are reserved for definition by ASHRAE.
|
||||
Enumerated values 64-65535 may be used by others subject to
|
||||
the procedures and constraints described in Clause 23. */
|
||||
return indtext_by_index_split_default(
|
||||
bactext_authentication_disable_reason_names, index,
|
||||
AUTHENTICATION_DISABLED_PROPRIETARY_MIN, ASHRAE_Reserved_String,
|
||||
Vendor_Proprietary_String);
|
||||
}
|
||||
|
||||
INDTEXT_DATA bactext_authentication_factor_type_names[] = {
|
||||
/* BACnetAuthenticationFactorType enumerations */
|
||||
{ AUTHENTICATION_FACTOR_UNDEFINED, "undefined" },
|
||||
{ AUTHENTICATION_FACTOR_ERROR, "error" },
|
||||
{ AUTHENTICATION_FACTOR_CUSTOM, "custom" },
|
||||
{ AUTHENTICATION_FACTOR_SIMPLE_NUMBER16, "simple-number16" },
|
||||
{ AUTHENTICATION_FACTOR_SIMPLE_NUMBER32, "simple-number32" },
|
||||
{ AUTHENTICATION_FACTOR_SIMPLE_NUMBER56, "simple-number56" },
|
||||
{ AUTHENTICATION_FACTOR_SIMPLE_ALPHA_NUMERIC, "simple-alpha-numeric" },
|
||||
{ AUTHENTICATION_FACTOR_ABA_TRACK2, "aba-track2" },
|
||||
{ AUTHENTICATION_FACTOR_WIEGAND26, "wiegand26" },
|
||||
{ AUTHENTICATION_FACTOR_WIEGAND37, "wiegand37" },
|
||||
{ AUTHENTICATION_FACTOR_WIEGAND37_FACILITY, "wiegand37-facility" },
|
||||
{ AUTHENTICATION_FACTOR_FACILITY16_CARD32, "facility16-card32" },
|
||||
{ AUTHENTICATION_FACTOR_FACILITY32_CARD32, "facility32-card32" },
|
||||
{ AUTHENTICATION_FACTOR_FASC_N, "fasc-n" },
|
||||
{ AUTHENTICATION_FACTOR_FASC_N_BCD, "fasc-n-bcd" },
|
||||
{ AUTHENTICATION_FACTOR_FASC_N_LARGE, "fasc-n-large" },
|
||||
{ AUTHENTICATION_FACTOR_FASC_N_LARGE_BCD, "fasc-n-large-bcd" },
|
||||
{ AUTHENTICATION_FACTOR_GSA75, "gsa75" },
|
||||
{ AUTHENTICATION_FACTOR_CHUID, "chuid" },
|
||||
{ AUTHENTICATION_FACTOR_CHUID_FULL, "chuid-full" },
|
||||
{ AUTHENTICATION_FACTOR_GUID, "guid" },
|
||||
{ AUTHENTICATION_FACTOR_CBEFF_A, "cbeff-a" },
|
||||
{ AUTHENTICATION_FACTOR_CBEFF_B, "cbeff-b" },
|
||||
{ AUTHENTICATION_FACTOR_CBEFF_C, "cbeff-c" },
|
||||
{ AUTHENTICATION_FACTOR_USER_PASSWORD, "user-password" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
const char *bactext_authentication_factor_type_name(uint32_t index)
|
||||
{
|
||||
return indtext_by_index_default(
|
||||
bactext_authentication_factor_type_names, index,
|
||||
ASHRAE_Reserved_String);
|
||||
}
|
||||
|
||||
INDTEXT_DATA bactext_authorization_mode_names[] = {
|
||||
/* BACnetAuthorizationMode enumerations */
|
||||
{ AUTHORIZATION_MODE_AUTHORIZE, "authorize" },
|
||||
|
||||
@@ -385,6 +385,10 @@ bactext_access_event_name_default(uint32_t index, const char *default_string);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
const char *bactext_authentication_status_name(uint32_t index);
|
||||
BACNET_STACK_EXPORT
|
||||
const char *bactext_authentication_disable_reason_name(uint32_t index);
|
||||
BACNET_STACK_EXPORT
|
||||
const char *bactext_authentication_factor_type_name(uint32_t index);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
const char *bactext_authorization_mode_name(uint32_t index);
|
||||
|
||||
@@ -131,6 +131,25 @@ void handler_read_property_ack(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the memory allocated for a ReadProperty ACK service request.
|
||||
* @param value [in] The head of the linked list of values to free.
|
||||
* @param property [in] The property reference to free.
|
||||
*/
|
||||
static void rp_ack_service_request_free(
|
||||
BACNET_APPLICATION_DATA_VALUE *value, BACNET_PROPERTY_REFERENCE *property)
|
||||
{
|
||||
BACNET_APPLICATION_DATA_VALUE *old_value;
|
||||
|
||||
while (value) {
|
||||
/* free the linked list of values */
|
||||
old_value = value;
|
||||
value = value->next;
|
||||
free(old_value);
|
||||
}
|
||||
free(property);
|
||||
}
|
||||
|
||||
/** Decode the received RP data into a linked list of the results, with the
|
||||
* same data structure used by RPM ACK replies.
|
||||
* This function is provided to provide common handling for RP and RPM data,
|
||||
@@ -149,7 +168,7 @@ int rp_ack_fully_decode_service_request(
|
||||
uint8_t *apdu, int apdu_len, BACNET_READ_ACCESS_DATA *read_access_data)
|
||||
{
|
||||
int decoded_len = 0; /* return value */
|
||||
BACNET_READ_PROPERTY_DATA rp1data;
|
||||
BACNET_READ_PROPERTY_DATA rp1data = { 0 };
|
||||
BACNET_PROPERTY_REFERENCE *rp1_property; /* single property */
|
||||
BACNET_APPLICATION_DATA_VALUE *value, *old_value;
|
||||
uint8_t *vdata;
|
||||
@@ -170,33 +189,31 @@ int rp_ack_fully_decode_service_request(
|
||||
}
|
||||
rp1_property->propertyIdentifier = rp1data.object_property;
|
||||
rp1_property->propertyArrayIndex = rp1data.array_index;
|
||||
/* Is there no Error case possible here, as there is when decoding RPM?
|
||||
*/
|
||||
/* rp1_property->error.error_class = ?? */
|
||||
/* rp_ack_decode_service_request() processing already removed the
|
||||
* Opening and Closing '3' Tags.
|
||||
* note: if this is an array, there will be
|
||||
more than one element to decode */
|
||||
* Opening and Closing '3' Tags. */
|
||||
vdata = rp1data.application_data;
|
||||
vlen = rp1data.application_data_len;
|
||||
value = calloc(1, sizeof(BACNET_APPLICATION_DATA_VALUE));
|
||||
if (value == NULL) {
|
||||
/* can't proceed if calloc failed. */
|
||||
rp_ack_service_request_free(NULL, rp1_property);
|
||||
read_access_data->listOfProperties = NULL;
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
rp1_property->value = value;
|
||||
/* check for empty list */
|
||||
if (rp1data.application_data_len == 0) {
|
||||
bacapp_value_list_init(value, 1);
|
||||
value->tag = BACNET_APPLICATION_TAG_EMPTYLIST;
|
||||
return 0;
|
||||
}
|
||||
while (value && vdata && (vlen > 0)) {
|
||||
if (IS_CONTEXT_SPECIFIC(*vdata)) {
|
||||
len = bacapp_decode_context_data(
|
||||
vdata, vlen, value, rp1_property->propertyIdentifier);
|
||||
} else {
|
||||
len = bacapp_decode_application_data(vdata, vlen, value);
|
||||
}
|
||||
len = bacapp_decode_known_array_property(
|
||||
vdata, (unsigned)vlen, value, rp1data.object_type,
|
||||
rp1data.object_property, rp1data.array_index);
|
||||
if (len < 0) {
|
||||
/* unable to decode the data */
|
||||
while (value) {
|
||||
/* free the linked list of values */
|
||||
old_value = value;
|
||||
value = value->next;
|
||||
free(old_value);
|
||||
}
|
||||
free(rp1_property);
|
||||
rp_ack_service_request_free(value, rp1_property);
|
||||
read_access_data->listOfProperties = NULL;
|
||||
return len;
|
||||
}
|
||||
@@ -211,13 +228,7 @@ int rp_ack_fully_decode_service_request(
|
||||
} else {
|
||||
if (len == 0) {
|
||||
/* nothing decoded and no closing tag, so malformed */
|
||||
while (value) {
|
||||
/* free the linked list of values */
|
||||
old_value = value;
|
||||
value = value->next;
|
||||
free(old_value);
|
||||
}
|
||||
free(rp1_property);
|
||||
rp_ack_service_request_free(value, rp1_property);
|
||||
read_access_data->listOfProperties = NULL;
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
|
||||
@@ -241,6 +241,7 @@
|
||||
defined(BACAPP_RECIPIENT) || \
|
||||
defined(BACAPP_ADDRESS_BINDING) || \
|
||||
defined(BACAPP_NO_VALUE) || \
|
||||
defined(BACAPP_AUTHENTICATION) || \
|
||||
defined(BACAPP_LOG_RECORD) || \
|
||||
defined(BACAPP_SECURE_CONNECT) || \
|
||||
defined(BACAPP_TYPES_EXTRA))
|
||||
@@ -335,6 +336,8 @@
|
||||
#define BACAPP_ADDRESS_BINDING
|
||||
#undef BACAPP_NO_VALUE
|
||||
#define BACAPP_NO_VALUE
|
||||
#undef BACAPP_AUTHENTICATION
|
||||
#define BACAPP_AUTHENTICATION
|
||||
#undef BACAPP_LOG_RECORD
|
||||
#define BACAPP_LOG_RECORD
|
||||
#undef BACAPP_SECURE_CONNECT
|
||||
@@ -368,6 +371,7 @@
|
||||
defined(BACAPP_RECIPIENT) || \
|
||||
defined(BACAPP_ADDRESS_BINDING) || \
|
||||
defined(BACAPP_NO_VALUE) || \
|
||||
defined(BACAPP_AUTHENTICATION) || \
|
||||
defined(BACAPP_LOG_RECORD)
|
||||
#undef BACAPP_COMPLEX_TYPES
|
||||
#define BACAPP_COMPLEX_TYPES
|
||||
|
||||
Reference in New Issue
Block a user