[WIP] fixing BACnetAccessRule encoding and decoding.

This commit is contained in:
Steve Karg
2024-09-02 08:21:48 -05:00
parent f806c5829b
commit f1eaa4e154
2 changed files with 156 additions and 85 deletions
+143 -84
View File
@@ -10,143 +10,202 @@
#include "bacnet/access_rule.h" #include "bacnet/access_rule.h"
#include "bacnet/bacdcode.h" #include "bacnet/bacdcode.h"
/**
* @brief Encode the BACnetAccessRule
*
* BACnetAccessRule ::= SEQUENCE {
* time-range-specifier [0] ENUMERATED {
* specified (0),
* always (1)
* },
* time-range[1] BACnetDeviceObjectPropertyReference OPTIONAL,
* -- to be present if time-range-specifier has the value "specified"
* location-specifier [2] ENUMERATED {
* specified (0),
* all (1)
* },
* location [3] BACnetDeviceObjectReference OPTIONAL,
* -- to be present if location-specifier has the value "specified"
* enable [4] BOOLEAN
* }
*
* @param apdu Pointer to the buffer for encoding, or NULL for length
* @param rule Pointer to the data to be encoded
* @return number of bytes encoded
*/
int bacapp_encode_access_rule(uint8_t *apdu, const BACNET_ACCESS_RULE *rule) int bacapp_encode_access_rule(uint8_t *apdu, const BACNET_ACCESS_RULE *rule)
{ {
int len; int len;
int apdu_len = 0; int apdu_len = 0;
len = encode_context_enumerated(&apdu[0], 0, rule->time_range_specifier); len = encode_context_enumerated(apdu, 0, rule->time_range_specifier);
apdu_len += len; apdu_len += len;
if (apdu) {
apdu += len;
}
if (rule->time_range_specifier == TIME_RANGE_SPECIFIER_SPECIFIED) { if (rule->time_range_specifier == TIME_RANGE_SPECIFIER_SPECIFIED) {
len = bacapp_encode_context_device_obj_property_ref( len = bacapp_encode_context_device_obj_property_ref(
&apdu[apdu_len], 1, &rule->time_range); apdu, 1, &rule->time_range);
if (len > 0) { apdu_len += len;
apdu_len += len; if (apdu) {
} else { apdu += len;
return -1;
} }
} }
len = encode_context_enumerated(apdu, 2, rule->location_specifier);
len =
encode_context_enumerated(&apdu[apdu_len], 2, rule->location_specifier);
apdu_len += len; apdu_len += len;
if (apdu) {
apdu += len;
}
if (rule->location_specifier == LOCATION_SPECIFIER_SPECIFIED) { if (rule->location_specifier == LOCATION_SPECIFIER_SPECIFIED) {
len = bacapp_encode_context_device_obj_property_ref( len = bacapp_encode_context_device_obj_ref(apdu, 3, &rule->location);
&apdu[apdu_len], 3, &rule->location); apdu_len += len;
if (len > 0) { if (apdu) {
apdu_len += len; apdu += len;
} else {
return -1;
} }
} }
len = encode_context_boolean(apdu, 4, rule->enable);
len = encode_context_boolean(&apdu[apdu_len], 4, rule->enable);
apdu_len += len; apdu_len += len;
return apdu_len; 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( int bacapp_encode_context_access_rule(
uint8_t *apdu, uint8_t tag_number, const BACNET_ACCESS_RULE *rule) uint8_t *apdu, uint8_t tag_number, const BACNET_ACCESS_RULE *rule)
{ {
int len; int len;
int apdu_len = 0; int apdu_len = 0;
len = encode_opening_tag(&apdu[apdu_len], tag_number); len = encode_opening_tag(apdu, tag_number);
apdu_len += len; apdu_len += len;
if (apdu) {
len = bacapp_encode_access_rule(&apdu[apdu_len], rule); apdu += len;
}
len = bacapp_encode_access_rule(apdu, rule);
apdu_len += len; apdu_len += len;
if (apdu) {
len = encode_closing_tag(&apdu[apdu_len], tag_number); apdu += len;
}
len = encode_closing_tag(apdu, tag_number);
apdu_len += len; apdu_len += len;
return apdu_len; return apdu_len;
} }
int bacapp_decode_access_rule(const uint8_t *apdu, BACNET_ACCESS_RULE *rule) /**
* @brief Decode the BACnetAccessRule
* @param apdu Pointer to the buffer for decoding.
* @param apdu_size The size of the buffer for decoding.
* @param data Pointer to the data to be stored
* @return number of bytes decoded or BACNET_STATUS_ERROR on error
*/
int bacnet_access_rule_decode(
const uint8_t *apdu, size_t apdu_size, BACNET_ACCESS_RULE *data)
{ {
int len; int len;
int apdu_len = 0; int apdu_len = 0;
uint32_t time_range_specifier = rule->time_range_specifier; uint32_t enumerated_value = 0, time_range_specifier = 0,
uint32_t location_specifier = rule->location_specifier; location_specifier = 0;
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *reference = NULL;
BACNET_DEVICE_OBJECT_REFERENCE *location_reference = NULL;
bool boolean_value = false;
if (decode_is_context_tag(&apdu[apdu_len], 0)) { /* time-range-specifier [0] ENUMERATED {
len = decode_context_enumerated( specified (0),
&apdu[apdu_len], 0, &time_range_specifier); always (1)
if (len < 0) { }
return -1; */
} else if (time_range_specifier < TIME_RANGE_SPECIFIER_MAX) { len = bacnet_enumerated_context_decode(
apdu_len += len; &apdu[apdu_len], apdu_size - apdu_len, 0, &enumerated_value);
rule->time_range_specifier = if (len <= 0) {
return BACNET_STATUS_ERROR;
} else if (enumerated_value < TIME_RANGE_SPECIFIER_MAX) {
time_range_specifier = enumerated_value;
if (data) {
data->time_range_specifier =
(BACNET_ACCESS_RULE_TIME_RANGE_SPECIFIER)time_range_specifier; (BACNET_ACCESS_RULE_TIME_RANGE_SPECIFIER)time_range_specifier;
} else {
return -1;
} }
} else { } else {
return -1; return BACNET_STATUS_ERROR;
} }
apdu_len += len;
if (rule->time_range_specifier == TIME_RANGE_SPECIFIER_SPECIFIED) { /* time-range[1] BACnetDeviceObjectPropertyReference OPTIONAL,
if (decode_is_context_tag(&apdu[apdu_len], 1)) { -- to be present if time-range-specifier has the value "specified" */
len = bacapp_decode_context_device_obj_property_ref( if (time_range_specifier == TIME_RANGE_SPECIFIER_SPECIFIED) {
&apdu[apdu_len], 1, &rule->time_range); if (data) {
if (len < 0) { reference = &data->time_range;
return -1;
} else {
apdu_len += len;
}
} else {
return -1;
} }
len = bacnet_device_object_property_reference_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 1, reference);
if (len <= 0) {
return BACNET_STATUS_ERROR;
}
apdu_len += len;
} }
/* time-range-specifier [0] ENUMERATED {
if (decode_is_context_tag(&apdu[apdu_len], 2)) { specified (0),
len = always (1)
decode_context_enumerated(&apdu[apdu_len], 2, &location_specifier); }
if (len < 0) { */
return -1; len = bacnet_enumerated_context_decode(
} else if (location_specifier < LOCATION_SPECIFIER_MAX) { &apdu[apdu_len], apdu_size - apdu_len, 2, &enumerated_value);
apdu_len += len; if (len <= 0) {
rule->location_specifier = return BACNET_STATUS_ERROR;
} else if (enumerated_value < LOCATION_SPECIFIER_MAX) {
location_specifier = enumerated_value;
if (data) {
data->location_specifier =
(BACNET_ACCESS_RULE_LOCATION_SPECIFIER)location_specifier; (BACNET_ACCESS_RULE_LOCATION_SPECIFIER)location_specifier;
} else {
return -1;
} }
} else { } else {
return -1; return BACNET_STATUS_ERROR;
} }
apdu_len += len;
if (rule->location_specifier == LOCATION_SPECIFIER_SPECIFIED) { /* location [3] BACnetDeviceObjectReference OPTIONAL,
if (decode_is_context_tag(&apdu[apdu_len], 3)) { -- to be present if location-specifier has the value "specified" */
len = bacapp_decode_context_device_obj_property_ref( if (location_specifier == LOCATION_SPECIFIER_SPECIFIED) {
&apdu[apdu_len], 3, &rule->location); if (data) {
if (len < 0) { location_reference = &data->location;
return -1;
} else {
apdu_len += len;
}
} else {
return -1;
} }
} len = bacnet_device_object_reference_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 3, location_reference);
if (decode_is_context_tag(&apdu[apdu_len], 4)) { if (len <= 0) {
len = decode_context_boolean2(&apdu[apdu_len], 4, &rule->enable); return BACNET_STATUS_ERROR;
if (len < 0) {
return -1;
} else {
apdu_len += len;
} }
} else { apdu_len += len;
return -1;
} }
/* enable [4] BOOLEAN */
len = bacnet_boolean_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 4, &boolean_value);
if (len <= 0) {
return BACNET_STATUS_ERROR;
}
if (data) {
data->enable = boolean_value;
}
apdu_len += len;
return apdu_len; return apdu_len;
} }
/**
* @brief Decode the BACnetAccessRule
* @param apdu Pointer to the buffer for decoding.
* @param rule Pointer to the data to be stored
* @return number of bytes decoded
* @deprecated Use bacapp_access_rule_decode() instead
*/
int bacapp_decode_access_rule(const uint8_t *apdu, BACNET_ACCESS_RULE *rule)
{
return bacnet_access_rule_decode(apdu, MAX_APDU, rule);
}
int bacapp_decode_context_access_rule( int bacapp_decode_context_access_rule(
const uint8_t *apdu, uint8_t tag_number, BACNET_ACCESS_RULE *rule) const uint8_t *apdu, uint8_t tag_number, BACNET_ACCESS_RULE *rule)
{ {
+13 -1
View File
@@ -32,7 +32,7 @@ typedef struct {
BACNET_ACCESS_RULE_TIME_RANGE_SPECIFIER time_range_specifier; BACNET_ACCESS_RULE_TIME_RANGE_SPECIFIER time_range_specifier;
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE time_range; BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE time_range;
BACNET_ACCESS_RULE_LOCATION_SPECIFIER location_specifier; BACNET_ACCESS_RULE_LOCATION_SPECIFIER location_specifier;
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE location; BACNET_DEVICE_OBJECT_REFERENCE location;
bool enable; bool enable;
} BACNET_ACCESS_RULE; } BACNET_ACCESS_RULE;
@@ -45,12 +45,24 @@ int bacapp_encode_access_rule(uint8_t *apdu, const BACNET_ACCESS_RULE *rule);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
int bacapp_encode_context_access_rule( int bacapp_encode_context_access_rule(
uint8_t *apdu, uint8_t tag_number, const BACNET_ACCESS_RULE *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 BACNET_STACK_EXPORT
int bacapp_decode_access_rule(const uint8_t *apdu, BACNET_ACCESS_RULE *rule); 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 BACNET_STACK_EXPORT
int bacapp_decode_context_access_rule( int bacapp_decode_context_access_rule(
const uint8_t *apdu, uint8_t tag_number, BACNET_ACCESS_RULE *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);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */