Changed date encoding when year is out of range to use wildcard. Updated APDU encoding pattern (#897)

This commit is contained in:
Steve Karg
2025-01-27 08:42:43 -06:00
committed by GitHub
parent 44c2bccdeb
commit d4a32171b7
+158 -120
View File
@@ -1692,21 +1692,23 @@ int encode_bitstring(uint8_t *apdu, const BACNET_BIT_STRING *bit_string)
*/
int encode_application_bitstring(uint8_t *apdu, const BACNET_BIT_STRING *value)
{
int apdu_len = 0;
int len = 0;
uint32_t bit_string_encoded_length = 1; /* 1 for the bits remaining octet */
uint8_t *apdu_offset = NULL;
/* bit string may use more than 1 octet for the tag, so find out how many */
bit_string_encoded_length += bitstring_bytes_used(value);
len = encode_tag(
apdu, BACNET_APPLICATION_TAG_BIT_STRING, false,
bit_string_encoded_length);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bitstring(apdu_offset, value);
len = encode_bitstring(apdu, value);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -1723,19 +1725,21 @@ int encode_application_bitstring(uint8_t *apdu, const BACNET_BIT_STRING *value)
int encode_context_bitstring(
uint8_t *apdu, uint8_t tag_number, const BACNET_BIT_STRING *value)
{
int apdu_len = 0;
int len = 0;
uint32_t bit_string_encoded_length = 1; /* 1 for the bits remaining octet */
uint8_t *apdu_offset = NULL;
/* bit string may use more than 1 octet for the tag, so find out how many */
bit_string_encoded_length += bitstring_bytes_used(value);
len = encode_tag(apdu, tag_number, true, bit_string_encoded_length);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bitstring(apdu_offset, value);
len = encode_bitstring(apdu, value);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -2016,7 +2020,7 @@ int encode_bacnet_object_id(
uint8_t *apdu, BACNET_OBJECT_TYPE object_type, uint32_t instance)
{
uint32_t value = 0;
int len = 0;
int len;
value =
(((uint32_t)object_type & BACNET_MAX_OBJECT) << BACNET_INSTANCE_BITS) |
@@ -2044,17 +2048,19 @@ int encode_context_object_id(
BACNET_OBJECT_TYPE object_type,
uint32_t instance)
{
int len = 0;
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len;
/* length of object id is 4 octets, as per 20.2.14 */
len = encode_tag(apdu, tag_number, true, 4);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_object_id(apdu_offset, object_type, instance);
len = encode_bacnet_object_id(apdu, object_type, instance);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -2071,19 +2077,21 @@ int encode_context_object_id(
int encode_application_object_id(
uint8_t *apdu, BACNET_OBJECT_TYPE object_type, uint32_t instance)
{
int len = 0;
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len, tag_len;
/* get the length by using NULL APDU */
len = encode_bacnet_object_id(NULL, object_type, instance);
tag_len = encode_bacnet_object_id(NULL, object_type, instance);
len = encode_tag(
apdu, BACNET_APPLICATION_TAG_OBJECT_ID, false, (uint32_t)len);
apdu, BACNET_APPLICATION_TAG_OBJECT_ID, false, (uint32_t)tag_len);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_object_id(apdu_offset, object_type, instance);
len = encode_bacnet_object_id(apdu, object_type, instance);
apdu_len += len;
return len;
return apdu_len;
}
#if BACNET_USE_OCTETSTRING
@@ -2462,18 +2470,21 @@ int encode_bacnet_character_string(
int encode_application_character_string(
uint8_t *apdu, const BACNET_CHARACTER_STRING *char_string)
{
int len = 0;
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len, tag_len;
len = encode_bacnet_character_string(NULL, char_string);
tag_len = encode_bacnet_character_string(NULL, char_string);
len = encode_tag(
apdu, BACNET_APPLICATION_TAG_CHARACTER_STRING, false, (uint32_t)len);
apdu, BACNET_APPLICATION_TAG_CHARACTER_STRING, false,
(uint32_t)tag_len);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_character_string(apdu_offset, char_string);
len = encode_bacnet_character_string(apdu, char_string);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -2492,17 +2503,19 @@ int encode_context_character_string(
uint8_t tag_number,
const BACNET_CHARACTER_STRING *char_string)
{
int len = 0;
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len, tag_len;
len = encode_bacnet_character_string(NULL, char_string);
len = encode_tag(apdu, tag_number, true, (uint32_t)len);
tag_len = encode_bacnet_character_string(NULL, char_string);
len = encode_tag(apdu, tag_number, true, (uint32_t)tag_len);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_character_string(apdu_offset, char_string);
len = encode_bacnet_character_string(apdu, char_string);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -3029,18 +3042,20 @@ int encode_bacnet_unsigned(uint8_t *apdu, BACNET_UNSIGNED_INTEGER value)
int encode_context_unsigned(
uint8_t *apdu, uint8_t tag_number, BACNET_UNSIGNED_INTEGER value)
{
int len = 0;
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len, tag_len;
/* length of unsigned is variable, as per 20.2.4 */
len = bacnet_unsigned_length(value);
len = encode_tag(apdu, tag_number, true, (uint32_t)len);
tag_len = bacnet_unsigned_length(value);
len = encode_tag(apdu, tag_number, true, (uint32_t)tag_len);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_unsigned(apdu_offset, value);
len = encode_bacnet_unsigned(apdu, value);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -3055,18 +3070,20 @@ int encode_context_unsigned(
*/
int encode_application_unsigned(uint8_t *apdu, BACNET_UNSIGNED_INTEGER value)
{
int len = 0;
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len, tag_len;
len = bacnet_unsigned_length(value);
tag_len = bacnet_unsigned_length(value);
len = encode_tag(
apdu, BACNET_APPLICATION_TAG_UNSIGNED_INT, false, (uint32_t)len);
apdu, BACNET_APPLICATION_TAG_UNSIGNED_INT, false, (uint32_t)tag_len);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_unsigned(apdu_offset, value);
len = encode_bacnet_unsigned(apdu, value);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -3294,18 +3311,20 @@ int encode_bacnet_enumerated(uint8_t *apdu, uint32_t value)
*/
int encode_application_enumerated(uint8_t *apdu, uint32_t value)
{
int len = 0; /* return value */
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len, tag_len;
len = bacnet_unsigned_length(value);
tag_len = bacnet_unsigned_length(value);
len = encode_tag(
apdu, BACNET_APPLICATION_TAG_ENUMERATED, false, (uint32_t)len);
apdu, BACNET_APPLICATION_TAG_ENUMERATED, false, (uint32_t)tag_len);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_enumerated(apdu_offset, value);
len = encode_bacnet_enumerated(apdu, value);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -3321,17 +3340,19 @@ int encode_application_enumerated(uint8_t *apdu, uint32_t value)
*/
int encode_context_enumerated(uint8_t *apdu, uint8_t tag_number, uint32_t value)
{
int len = 0; /* return value */
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len, tag_len;
len = bacnet_unsigned_length(value);
len = encode_tag(apdu, tag_number, true, (uint32_t)len);
tag_len = bacnet_unsigned_length(value);
len = encode_tag(apdu, tag_number, true, (uint32_t)tag_len);
apdu_len = len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_enumerated(apdu_offset, value);
len = encode_bacnet_enumerated(apdu, value);
apdu_len += len;
return len;
return apdu_len;
}
#if BACNET_USE_SIGNED
@@ -3580,18 +3601,20 @@ int encode_bacnet_signed(uint8_t *apdu, int32_t value)
*/
int encode_application_signed(uint8_t *apdu, int32_t value)
{
int len = 0; /* return value */
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len, tag_len;
len = bacnet_signed_length(value);
tag_len = bacnet_signed_length(value);
len = encode_tag(
apdu, BACNET_APPLICATION_TAG_SIGNED_INT, false, (uint32_t)len);
apdu, BACNET_APPLICATION_TAG_SIGNED_INT, false, (uint32_t)tag_len);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_signed(apdu_offset, value);
len = encode_bacnet_signed(apdu, value);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -3607,17 +3630,19 @@ int encode_application_signed(uint8_t *apdu, int32_t value)
*/
int encode_context_signed(uint8_t *apdu, uint8_t tag_number, int32_t value)
{
int len = 0; /* return value */
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len, tag_len;
len = bacnet_signed_length(value);
len = encode_tag(apdu, tag_number, true, (uint32_t)len);
tag_len = bacnet_signed_length(value);
len = encode_tag(apdu, tag_number, true, (uint32_t)tag_len);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_signed(apdu_offset, value);
len = encode_bacnet_signed(apdu, value);
apdu_len += len;
return len;
return apdu_len;
}
#endif
@@ -3632,17 +3657,19 @@ int encode_context_signed(uint8_t *apdu, uint8_t tag_number, int32_t value)
*/
int encode_application_real(uint8_t *apdu, float value)
{
int len = 0;
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len;
/* length of REAL is 4 octets, as per 20.2.6 */
len = encode_tag(apdu, BACNET_APPLICATION_TAG_REAL, false, 4);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_real(value, apdu_offset);
len = encode_bacnet_real(value, apdu);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -3658,17 +3685,19 @@ int encode_application_real(uint8_t *apdu, float value)
*/
int encode_context_real(uint8_t *apdu, uint8_t tag_number, float value)
{
int len = 0;
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len;
/* length of REAL is 4 octets, as per 20.2.6 */
len = encode_tag(apdu, tag_number, true, 4);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_real(value, apdu_offset);
len = encode_bacnet_real(value, apdu);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -3849,17 +3878,19 @@ int decode_context_real(
*/
int encode_application_double(uint8_t *apdu, double value)
{
int len = 0;
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len;
/* length of DOUBLE is 8 octets, as per 20.2.7 */
len = encode_tag(apdu, BACNET_APPLICATION_TAG_DOUBLE, false, 8);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_double(value, apdu_offset);
len = encode_bacnet_double(value, apdu);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -3875,17 +3906,19 @@ int encode_application_double(uint8_t *apdu, double value)
*/
int encode_context_double(uint8_t *apdu, uint8_t tag_number, double value)
{
int len = 0;
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len;
/* length of double is 8 octets, as per 20.2.7 */
len = encode_tag(apdu, tag_number, true, 8);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_double(value, apdu_offset);
len = encode_bacnet_double(value, apdu);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -4087,17 +4120,19 @@ int encode_bacnet_time(uint8_t *apdu, const BACNET_TIME *btime)
*/
int encode_application_time(uint8_t *apdu, const BACNET_TIME *btime)
{
int len = 0;
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len;
/* length of Time value is 4 octets, as per 20.2.13 */
len = encode_tag(apdu, BACNET_APPLICATION_TAG_TIME, false, 4);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_time(apdu_offset, btime);
len = encode_bacnet_time(apdu, btime);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -4114,17 +4149,19 @@ int encode_application_time(uint8_t *apdu, const BACNET_TIME *btime)
int encode_context_time(
uint8_t *apdu, uint8_t tag_number, const BACNET_TIME *btime)
{
int len = 0; /* return value */
uint8_t *apdu_offset = NULL;
int apdu_len = 0;
int len;
/* length of time is 4 octets, as per 20.2.13 */
len = encode_tag(apdu, tag_number, true, 4);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_time(apdu_offset, btime);
len = encode_bacnet_time(apdu, btime);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -4390,7 +4427,7 @@ int decode_context_bacnet_time(
* @param apdu buffer to be encoded, or NULL for length
* @param value The value to be encoded.
*
* @return the number of apdu bytes consumed, or #BACNET_STATUS_ERROR
* @return the number of apdu bytes consumed
*/
int encode_bacnet_date(uint8_t *apdu, const BACNET_DATE *bdate)
{
@@ -4402,10 +4439,7 @@ int encode_bacnet_date(uint8_t *apdu, const BACNET_DATE *bdate)
/* allow 2 digit years */
apdu[0] = (uint8_t)bdate->year;
} else {
/*
** Don't try and guess what the user meant here. Just fail
*/
return BACNET_STATUS_ERROR;
apdu[0] = 0xFF;
}
apdu[1] = bdate->month;
apdu[2] = bdate->day;
@@ -4427,17 +4461,19 @@ int encode_bacnet_date(uint8_t *apdu, const BACNET_DATE *bdate)
*/
int encode_application_date(uint8_t *apdu, const BACNET_DATE *bdate)
{
int apdu_len = 0;
int len = 0;
uint8_t *apdu_offset = NULL;
/* length of Date value is 4 octets, as per 20.2.12 */
len = encode_tag(apdu, BACNET_APPLICATION_TAG_DATE, false, 4);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_date(apdu_offset, bdate);
len = encode_bacnet_date(apdu, bdate);
apdu_len += len;
return len;
return apdu_len;
}
/**
@@ -4454,17 +4490,19 @@ int encode_application_date(uint8_t *apdu, const BACNET_DATE *bdate)
int encode_context_date(
uint8_t *apdu, uint8_t tag_number, const BACNET_DATE *bdate)
{
int apdu_len = 0;
int len = 0; /* return value */
uint8_t *apdu_offset = NULL;
/* length of date is 4 octets, as per 20.2.12 */
len = encode_tag(apdu, tag_number, true, 4);
apdu_len += len;
if (apdu) {
apdu_offset = &apdu[len];
apdu += len;
}
len += encode_bacnet_date(apdu_offset, bdate);
len = encode_bacnet_date(apdu, bdate);
apdu_len += len;
return len;
return apdu_len;
}
/**