[WIP] fixing BACnetAccessRule encoding and decoding.
This commit is contained in:
+143
-84
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user