Fixed BACnetAccessRule application integration into Access Rights object. Improved unit testing and code coverage. (#790)
This commit is contained in:
+42
-68
@@ -69,35 +69,6 @@ int bacapp_encode_access_rule(uint8_t *apdu, const BACNET_ACCESS_RULE *rule)
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Encode the BACnetAccessRule as Context Tagged
|
||||
* @param apdu Pointer to the buffer for encoding, or NULL for length
|
||||
* @param tag_number Tag number
|
||||
* @param rule Pointer to the data to be encoded
|
||||
* @return number of bytes encoded
|
||||
*/
|
||||
int bacapp_encode_context_access_rule(
|
||||
uint8_t *apdu, uint8_t tag_number, const BACNET_ACCESS_RULE *rule)
|
||||
{
|
||||
int len;
|
||||
int apdu_len = 0;
|
||||
|
||||
len = encode_opening_tag(apdu, tag_number);
|
||||
apdu_len += len;
|
||||
if (apdu) {
|
||||
apdu += len;
|
||||
}
|
||||
len = bacapp_encode_access_rule(apdu, rule);
|
||||
apdu_len += len;
|
||||
if (apdu) {
|
||||
apdu += len;
|
||||
}
|
||||
len = encode_closing_tag(apdu, tag_number);
|
||||
apdu_len += len;
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Decode the BACnetAccessRule
|
||||
* @param apdu Pointer to the buffer for decoding.
|
||||
@@ -207,52 +178,55 @@ int bacapp_decode_access_rule(const uint8_t *apdu, BACNET_ACCESS_RULE *data)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Decode the BACnetAccessRule as Context Tagged
|
||||
* @param apdu Pointer to the buffer for decoding.
|
||||
* @param apdu_size The size of the buffer for decoding.
|
||||
* @param tag_number Tag number
|
||||
* @param data Pointer to the data to be stored
|
||||
* @return number of bytes decoded or BACNET_STATUS_ERROR on error
|
||||
* @brief Parse a string into a BACnetAccessRule value
|
||||
* @param value [out] The BACnetAccessRule value
|
||||
* @param argv [in] The string to parse
|
||||
* @return True on success, else False
|
||||
*/
|
||||
int bacnet_access_rule_context_decode(
|
||||
const uint8_t *apdu,
|
||||
size_t apdu_size,
|
||||
uint8_t tag_number,
|
||||
BACNET_ACCESS_RULE *data)
|
||||
bool bacnet_access_rule_from_ascii(BACNET_ACCESS_RULE *value, const char *argv)
|
||||
{
|
||||
int len = 0;
|
||||
int apdu_len = 0;
|
||||
bool status = false;
|
||||
|
||||
if (!bacnet_is_opening_tag_number(
|
||||
&apdu[apdu_len], apdu_size - apdu_len, tag_number, &len)) {
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
apdu_len += len;
|
||||
len =
|
||||
bacnet_access_rule_decode(&apdu[apdu_len], apdu_size - apdu_len, data);
|
||||
if (len <= 0) {
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
apdu_len += len;
|
||||
if (!bacnet_is_closing_tag_number(
|
||||
&apdu[apdu_len], apdu_size - apdu_len, tag_number, &len)) {
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
apdu_len += len;
|
||||
(void)value;
|
||||
(void)argv;
|
||||
|
||||
return apdu_len;
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Decode the BACnetAccessRule as Context Tagged
|
||||
* @param apdu Pointer to the buffer for decoding.
|
||||
* @param tag_number Tag number
|
||||
* @param data Pointer to the data to be stored
|
||||
* @return number of bytes decoded or BACNET_STATUS_ERROR on error
|
||||
* @deprecated Use bacnet_access_rule_context_decode() instead
|
||||
* @brief Compare two BACnetAccessRule values
|
||||
* @param value1 [in] The first BACnetAccessRule value
|
||||
* @param value2 [in] The second BACnetAccessRule value
|
||||
* @return True if the values are the same, else False
|
||||
*/
|
||||
int bacapp_decode_context_access_rule(
|
||||
const uint8_t *apdu, uint8_t tag_number, BACNET_ACCESS_RULE *data)
|
||||
bool bacnet_access_rule_same(
|
||||
const BACNET_ACCESS_RULE *value1, const BACNET_ACCESS_RULE *value2)
|
||||
{
|
||||
return bacnet_access_rule_context_decode(apdu, MAX_APDU, tag_number, data);
|
||||
bool status;
|
||||
|
||||
if (value1->time_range_specifier != value2->time_range_specifier) {
|
||||
return false;
|
||||
}
|
||||
if (value1->time_range_specifier == TIME_RANGE_SPECIFIER_SPECIFIED) {
|
||||
status = bacnet_device_object_property_reference_same(
|
||||
&value1->time_range, &value2->time_range);
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (value1->location_specifier != value2->location_specifier) {
|
||||
return false;
|
||||
}
|
||||
if (value1->location_specifier == LOCATION_SPECIFIER_SPECIFIED) {
|
||||
status = bacnet_device_object_reference_same(
|
||||
&value1->location, &value2->location);
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (value1->enable != value2->enable) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
/* BACnet Stack defines - first */
|
||||
#include "bacnet/bacdef.h"
|
||||
/* BACnet Stack API */
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/bacdevobjpropref.h"
|
||||
|
||||
typedef enum {
|
||||
@@ -28,7 +27,7 @@ typedef enum {
|
||||
LOCATION_SPECIFIER_MAX = 2
|
||||
} BACNET_ACCESS_RULE_LOCATION_SPECIFIER;
|
||||
|
||||
typedef struct {
|
||||
typedef struct BACnetAccessRule {
|
||||
BACNET_ACCESS_RULE_TIME_RANGE_SPECIFIER time_range_specifier;
|
||||
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE time_range;
|
||||
BACNET_ACCESS_RULE_LOCATION_SPECIFIER location_specifier;
|
||||
@@ -42,26 +41,19 @@ extern "C" {
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
int bacapp_encode_access_rule(uint8_t *apdu, const BACNET_ACCESS_RULE *rule);
|
||||
BACNET_STACK_EXPORT
|
||||
int bacapp_encode_context_access_rule(
|
||||
uint8_t *apdu, uint8_t tag_number, const BACNET_ACCESS_RULE *rule);
|
||||
BACNET_STACK_DEPRECATED("Use bacnet_access_rule_decode() instead")
|
||||
BACNET_STACK_EXPORT
|
||||
int bacapp_decode_access_rule(const uint8_t *apdu, BACNET_ACCESS_RULE *rule);
|
||||
BACNET_STACK_DEPRECATED("Use bacnet_access_rule_context_decode() instead")
|
||||
BACNET_STACK_EXPORT
|
||||
int bacapp_decode_context_access_rule(
|
||||
const uint8_t *apdu, uint8_t tag_number, BACNET_ACCESS_RULE *rule);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
int bacnet_access_rule_decode(
|
||||
const uint8_t *apdu, size_t apdu_size, BACNET_ACCESS_RULE *data);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
int bacnet_access_rule_context_decode(
|
||||
const uint8_t *apdu,
|
||||
size_t apdu_size,
|
||||
uint8_t tag_number,
|
||||
BACNET_ACCESS_RULE *data);
|
||||
bool bacnet_access_rule_from_ascii(BACNET_ACCESS_RULE *value, const char *argv);
|
||||
BACNET_STACK_EXPORT
|
||||
bool bacnet_access_rule_same(
|
||||
const BACNET_ACCESS_RULE *value1, const BACNET_ACCESS_RULE *value2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#endif
|
||||
#include "bacnet/access_rule.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacint.h"
|
||||
@@ -502,6 +503,13 @@ int bacapp_encode_application_data(
|
||||
apdu_len =
|
||||
bacnet_shed_level_encode(apdu, &value->type.Shed_Level);
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_ACCESS_RULE)
|
||||
case BACNET_APPLICATION_TAG_ACCESS_RULE:
|
||||
/* BACnetAccessRule */
|
||||
apdu_len =
|
||||
bacapp_encode_access_rule(apdu, &value->type.Access_Rule);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
@@ -919,6 +927,7 @@ int bacapp_encode_context_data_value(
|
||||
case BACNET_APPLICATION_TAG_ACTION_COMMAND:
|
||||
case BACNET_APPLICATION_TAG_SCALE:
|
||||
case BACNET_APPLICATION_TAG_SHED_LEVEL:
|
||||
case BACNET_APPLICATION_TAG_ACCESS_RULE:
|
||||
/* complex data is enclosed in open/close tags */
|
||||
len = encode_opening_tag(apdu, context_tag_number);
|
||||
apdu_len += len;
|
||||
@@ -1291,6 +1300,10 @@ int bacapp_known_property_tag(
|
||||
case PROP_BBMD_FOREIGN_DEVICE_TABLE:
|
||||
/* BACnetFDTEntry */
|
||||
return BACNET_APPLICATION_TAG_FDT_ENTRY;
|
||||
case PROP_POSITIVE_ACCESS_RULES:
|
||||
case PROP_NEGATIVE_ACCESS_RULES:
|
||||
/* BACnetAccessRule */
|
||||
return BACNET_APPLICATION_TAG_ACCESS_RULE;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
@@ -1587,6 +1600,13 @@ int bacapp_decode_application_tag_value(
|
||||
apdu_len = bacnet_shed_level_decode(
|
||||
apdu, apdu_size, &value->type.Shed_Level);
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_ACCESS_RULE)
|
||||
case BACNET_APPLICATION_TAG_ACCESS_RULE:
|
||||
/* BACnetAccessRule */
|
||||
apdu_len = bacnet_access_rule_decode(
|
||||
apdu, apdu_size, &value->type.Access_Rule);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
@@ -2500,6 +2520,51 @@ static int bacapp_snprintf_object_property_reference(
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BACAPP_ACCESS_RULE)
|
||||
/**
|
||||
* @brief Print a value to a string for EPICS
|
||||
* @param str - destination string, or NULL for length only
|
||||
* @param str_len - length of the destination string, or 0 for length only
|
||||
* @param value - value to be printed
|
||||
* @return number of characters written to the string
|
||||
*/
|
||||
static int bacapp_snprintf_access_rule(
|
||||
char *str, size_t str_len, const BACNET_ACCESS_RULE *value)
|
||||
{
|
||||
int slen;
|
||||
int ret_val = 0;
|
||||
|
||||
slen = bacapp_snprintf(str, str_len, "{");
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
/* specified (0), always (1) */
|
||||
if (value->time_range_specifier == TIME_RANGE_SPECIFIER_SPECIFIED) {
|
||||
slen = bacapp_snprintf(str, str_len, "specified, ");
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
slen = bacapp_snprintf_device_object_property_reference(
|
||||
str, str_len, &value->time_range);
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
} else {
|
||||
slen = bacapp_snprintf(str, str_len, "always, ");
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
}
|
||||
/* specified (0), all (1) */
|
||||
if (value->location_specifier == LOCATION_SPECIFIER_SPECIFIED) {
|
||||
slen = bacapp_snprintf(str, str_len, "specified, ");
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
slen = bacapp_snprintf_device_object_reference(
|
||||
str, str_len, &value->location);
|
||||
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
|
||||
} else {
|
||||
slen = bacapp_snprintf(str, str_len, "all");
|
||||
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
|
||||
|
||||
#if defined(BACAPP_WEEKLY_SCHEDULE)
|
||||
/**
|
||||
* @brief Print a weekly schedule value to a string for EPICS
|
||||
@@ -3279,6 +3344,12 @@ int bacapp_snprintf_value(
|
||||
ret_val = bacapp_snprintf_shed_level(
|
||||
str, str_len, &value->type.Shed_Level);
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_ACCESS_RULE)
|
||||
case BACNET_APPLICATION_TAG_ACCESS_RULE:
|
||||
ret_val = bacapp_snprintf_access_rule(
|
||||
str, str_len, &value->type.Access_Rule);
|
||||
break;
|
||||
#endif
|
||||
case BACNET_APPLICATION_TAG_EMPTYLIST:
|
||||
ret_val = bacapp_snprintf(str, str_len, "{}");
|
||||
@@ -3892,6 +3963,12 @@ bool bacapp_parse_application_data(
|
||||
status =
|
||||
bacnet_shed_level_from_ascii(&value->type.Shed_Level, argv);
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_ACCESS_RULE)
|
||||
case BACNET_APPLICATION_TAG_ACCESS_RULE:
|
||||
/* BACnetAccessRule - not implemented */
|
||||
bacnet_access_rule_from_ascii(&value->type.Access_Rule, argv);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
@@ -4444,6 +4521,12 @@ bool bacapp_same_value(
|
||||
status = bacnet_shed_level_same(
|
||||
&value->type.Shed_Level, &test_value->type.Shed_Level);
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_ACCESS_RULE)
|
||||
case BACNET_APPLICATION_TAG_ACCESS_RULE:
|
||||
status = bacnet_access_rule_same(
|
||||
&value->type.Access_Rule, &test_value->type.Access_Rule);
|
||||
break;
|
||||
#endif
|
||||
case BACNET_APPLICATION_TAG_EMPTYLIST:
|
||||
status = true;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
/* BACnet Stack defines - first */
|
||||
#include "bacnet/bacdef.h"
|
||||
/* BACnet Stack API */
|
||||
#include "bacnet/access_rule.h"
|
||||
#include "bacnet/bacaction.h"
|
||||
#include "bacnet/bacdest.h"
|
||||
#include "bacnet/bacint.h"
|
||||
@@ -159,6 +160,9 @@ typedef struct BACnet_Application_Data_Value {
|
||||
#endif
|
||||
#if defined(BACAPP_SHED_LEVEL)
|
||||
BACNET_SHED_LEVEL Shed_Level;
|
||||
#endif
|
||||
#if defined(BACAPP_ACCESS_RULE)
|
||||
BACNET_ACCESS_RULE Access_Rule;
|
||||
#endif
|
||||
} type;
|
||||
/* simple linked list if needed */
|
||||
|
||||
@@ -1608,7 +1608,9 @@ typedef enum {
|
||||
/* BACnetScale */
|
||||
BACNET_APPLICATION_TAG_SCALE,
|
||||
/* BACnetShedLevel */
|
||||
BACNET_APPLICATION_TAG_SHED_LEVEL
|
||||
BACNET_APPLICATION_TAG_SHED_LEVEL,
|
||||
/* BACnetAccessRule */
|
||||
BACNET_APPLICATION_TAG_ACCESS_RULE
|
||||
} BACNET_APPLICATION_TAG;
|
||||
|
||||
/* note: these are not the real values, */
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
/* BACnet Stack API */
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/property.h"
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
/* me! */
|
||||
@@ -23,16 +24,19 @@ static bool Access_Rights_Initialized = false;
|
||||
static ACCESS_RIGHTS_DESCR ar_descr[MAX_ACCESS_RIGHTSS];
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME,
|
||||
PROP_OBJECT_TYPE,
|
||||
PROP_GLOBAL_IDENTIFIER,
|
||||
PROP_STATUS_FLAGS,
|
||||
PROP_RELIABILITY,
|
||||
PROP_ENABLE,
|
||||
PROP_NEGATIVE_ACCESS_RULES,
|
||||
PROP_POSITIVE_ACCESS_RULES,
|
||||
-1 };
|
||||
static const int Properties_Required[] = {
|
||||
/* unordered list of required properties */
|
||||
PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME,
|
||||
PROP_OBJECT_TYPE,
|
||||
PROP_GLOBAL_IDENTIFIER,
|
||||
PROP_STATUS_FLAGS,
|
||||
PROP_RELIABILITY,
|
||||
PROP_ENABLE,
|
||||
PROP_NEGATIVE_ACCESS_RULES,
|
||||
PROP_POSITIVE_ACCESS_RULES,
|
||||
-1
|
||||
};
|
||||
|
||||
static const int Properties_Optional[] = { -1 };
|
||||
|
||||
@@ -133,22 +137,80 @@ bool Access_Rights_Object_Name(
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Encode a BACnetARRAY property element
|
||||
* @param object_instance [in] BACnet network port object instance number
|
||||
* @param index [in] array index requested:
|
||||
* 0 to N for individual array members
|
||||
* @param apdu [out] Buffer in which the APDU contents are built, or NULL to
|
||||
* return the length of buffer if it had been built
|
||||
* @return The length of the apdu encoded or
|
||||
* BACNET_STATUS_ERROR for ERROR_CODE_INVALID_ARRAY_INDEX
|
||||
*/
|
||||
static int Negative_Access_Rules_Encode(
|
||||
uint32_t object_instance, BACNET_ARRAY_INDEX index, uint8_t *apdu)
|
||||
{
|
||||
int apdu_len = BACNET_STATUS_ERROR;
|
||||
BACNET_ACCESS_RULE *rule;
|
||||
uint32_t count;
|
||||
|
||||
if (object_instance < MAX_ACCESS_RIGHTSS) {
|
||||
count = ar_descr[object_instance].negative_access_rules_count;
|
||||
if (index < count) {
|
||||
rule = &ar_descr[object_instance].negative_access_rules[index];
|
||||
apdu_len = bacapp_encode_access_rule(&apdu[0], rule);
|
||||
}
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Encode a BACnetARRAY property element
|
||||
* @param object_instance [in] BACnet network port object instance number
|
||||
* @param index [in] array index requested:
|
||||
* 0 to N for individual array members
|
||||
* @param apdu [out] Buffer in which the APDU contents are built, or NULL to
|
||||
* return the length of buffer if it had been built
|
||||
* @return The length of the apdu encoded or
|
||||
* BACNET_STATUS_ERROR for ERROR_CODE_INVALID_ARRAY_INDEX
|
||||
*/
|
||||
static int Positive_Access_Rules_Encode(
|
||||
uint32_t object_instance, BACNET_ARRAY_INDEX index, uint8_t *apdu)
|
||||
{
|
||||
int apdu_len = BACNET_STATUS_ERROR;
|
||||
BACNET_ACCESS_RULE *rule;
|
||||
uint32_t count;
|
||||
|
||||
if (object_instance < MAX_ACCESS_RIGHTSS) {
|
||||
count = ar_descr[object_instance].positive_access_rules_count;
|
||||
if (index < count) {
|
||||
rule = &ar_descr[object_instance].positive_access_rules[index];
|
||||
apdu_len = bacapp_encode_access_rule(&apdu[0], rule);
|
||||
}
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/* return apdu len, or BACNET_STATUS_ERROR on error */
|
||||
int Access_Rights_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
{
|
||||
int len = 0;
|
||||
int apdu_len = 0; /* return value */
|
||||
int apdu_size = 0;
|
||||
BACNET_BIT_STRING bit_string;
|
||||
BACNET_CHARACTER_STRING char_string;
|
||||
unsigned object_index = 0;
|
||||
unsigned i = 0;
|
||||
BACNET_UNSIGNED_INTEGER count;
|
||||
uint8_t *apdu = NULL;
|
||||
bool is_array = false;
|
||||
|
||||
if ((rpdata == NULL) || (rpdata->application_data == NULL) ||
|
||||
(rpdata->application_data_len == 0)) {
|
||||
return 0;
|
||||
}
|
||||
apdu = rpdata->application_data;
|
||||
apdu_size = rpdata->application_data_len;
|
||||
object_index = Access_Rights_Instance_To_Index(rpdata->object_instance);
|
||||
switch (rpdata->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
@@ -185,73 +247,29 @@ int Access_Rights_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
&apdu[0], ar_descr[object_index].enable);
|
||||
break;
|
||||
case PROP_NEGATIVE_ACCESS_RULES:
|
||||
if (rpdata->array_index == 0) {
|
||||
apdu_len = encode_application_unsigned(
|
||||
&apdu[0],
|
||||
ar_descr[object_index].negative_access_rules_count);
|
||||
} else if (rpdata->array_index == BACNET_ARRAY_ALL) {
|
||||
for (i = 0;
|
||||
i < ar_descr[object_index].negative_access_rules_count;
|
||||
i++) {
|
||||
len = bacapp_encode_access_rule(
|
||||
&apdu[0],
|
||||
&ar_descr[object_index].negative_access_rules[i]);
|
||||
if (apdu_len + len < MAX_APDU) {
|
||||
apdu_len += len;
|
||||
} else {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
apdu_len = BACNET_STATUS_ABORT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (rpdata->array_index <=
|
||||
ar_descr[object_index].negative_access_rules_count) {
|
||||
apdu_len = bacapp_encode_access_rule(
|
||||
&apdu[0],
|
||||
&ar_descr[object_index]
|
||||
.negative_access_rules[rpdata->array_index - 1]);
|
||||
} else {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
}
|
||||
count = ar_descr[object_index].negative_access_rules_count;
|
||||
apdu_len = bacnet_array_encode(
|
||||
rpdata->object_instance, rpdata->array_index,
|
||||
Negative_Access_Rules_Encode, count, apdu, apdu_size);
|
||||
if (apdu_len == BACNET_STATUS_ABORT) {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
} else if (apdu_len == BACNET_STATUS_ERROR) {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
}
|
||||
break;
|
||||
case PROP_POSITIVE_ACCESS_RULES:
|
||||
if (rpdata->array_index == 0) {
|
||||
apdu_len = encode_application_unsigned(
|
||||
&apdu[0],
|
||||
ar_descr[object_index].positive_access_rules_count);
|
||||
} else if (rpdata->array_index == BACNET_ARRAY_ALL) {
|
||||
for (i = 0;
|
||||
i < ar_descr[object_index].positive_access_rules_count;
|
||||
i++) {
|
||||
len = bacapp_encode_access_rule(
|
||||
&apdu[0],
|
||||
&ar_descr[object_index].positive_access_rules[i]);
|
||||
if (apdu_len + len < MAX_APDU) {
|
||||
apdu_len += len;
|
||||
} else {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
apdu_len = BACNET_STATUS_ABORT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (rpdata->array_index <=
|
||||
ar_descr[object_index].positive_access_rules_count) {
|
||||
apdu_len = bacapp_encode_access_rule(
|
||||
&apdu[0],
|
||||
&ar_descr[object_index]
|
||||
.positive_access_rules[rpdata->array_index - 1]);
|
||||
} else {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
}
|
||||
count = ar_descr[object_index].positive_access_rules_count;
|
||||
apdu_len = bacnet_array_encode(
|
||||
rpdata->object_instance, rpdata->array_index,
|
||||
Positive_Access_Rules_Encode, count, apdu, apdu_size);
|
||||
if (apdu_len == BACNET_STATUS_ABORT) {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
} else if (apdu_len == BACNET_STATUS_ERROR) {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -261,9 +279,9 @@ int Access_Rights_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
break;
|
||||
}
|
||||
/* only array properties can have array options */
|
||||
if ((apdu_len >= 0) &&
|
||||
(rpdata->object_property != PROP_NEGATIVE_ACCESS_RULES) &&
|
||||
(rpdata->object_property != PROP_POSITIVE_ACCESS_RULES) &&
|
||||
is_array = property_list_bacnet_array_member(
|
||||
rpdata->object_type, rpdata->object_property);
|
||||
if ((apdu_len >= 0) && (!is_array) &&
|
||||
(rpdata->array_index != BACNET_ARRAY_ALL)) {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
@@ -277,6 +295,7 @@ int Access_Rights_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
bool Access_Rights_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
bool is_array = false;
|
||||
int len = 0;
|
||||
BACNET_APPLICATION_DATA_VALUE value;
|
||||
unsigned object_index = 0;
|
||||
@@ -292,9 +311,9 @@ bool Access_Rights_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
return false;
|
||||
}
|
||||
/* only array properties can have array options */
|
||||
if ((wp_data->object_property != PROP_NEGATIVE_ACCESS_RULES) &&
|
||||
(wp_data->object_property != PROP_POSITIVE_ACCESS_RULES) &&
|
||||
(wp_data->array_index != BACNET_ARRAY_ALL)) {
|
||||
is_array = property_list_bacnet_array_member(
|
||||
wp_data->object_type, wp_data->object_property);
|
||||
if (is_array && (wp_data->array_index != BACNET_ARRAY_ALL)) {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
return false;
|
||||
@@ -309,20 +328,16 @@ bool Access_Rights_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
value.type.Unsigned_Int;
|
||||
}
|
||||
break;
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
case PROP_OBJECT_NAME:
|
||||
case PROP_OBJECT_TYPE:
|
||||
case PROP_STATUS_FLAGS:
|
||||
case PROP_RELIABILITY:
|
||||
case PROP_ENABLE:
|
||||
case PROP_NEGATIVE_ACCESS_RULES:
|
||||
case PROP_POSITIVE_ACCESS_RULES:
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
break;
|
||||
default:
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
if (property_lists_member(
|
||||
Properties_Required, Properties_Optional,
|
||||
Properties_Proprietary, wp_data->object_property)) {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -203,6 +203,7 @@
|
||||
defined(BACAPP_ACTION_COMMAND) || \
|
||||
defined(BACAPP_SCALE) || \
|
||||
defined(BACAPP_SHED_LEVEL) || \
|
||||
defined(BACAPP_ACCESS_RULE) || \
|
||||
defined(BACAPP_TYPES_EXTRA))
|
||||
#define BACAPP_ALL
|
||||
#endif
|
||||
@@ -249,6 +250,7 @@
|
||||
#define BACAPP_ACTION_COMMAND
|
||||
#define BACAPP_SCALE
|
||||
#define BACAPP_SHED_LEVEL
|
||||
#define BACAPP_ACCESS_RULE
|
||||
#endif
|
||||
|
||||
/* clang-format off */
|
||||
@@ -270,7 +272,8 @@
|
||||
defined(BACAPP_FDT_ENTRY) || \
|
||||
defined(BACAPP_ACTION_COMMAND) || \
|
||||
defined(BACAPP_SCALE) || \
|
||||
defined(BACAPP_SHED_LEVEL)
|
||||
defined(BACAPP_SHED_LEVEL) || \
|
||||
defined(BACAPP_ACCESS_RULE)
|
||||
#define BACAPP_COMPLEX_TYPES
|
||||
#endif
|
||||
/* clang-format on */
|
||||
|
||||
Reference in New Issue
Block a user