Feature/apdu null length returned (#285)

* Add APDU as NULL to get BACnet type lengths.

* Fix bacapp copy test to succeed

* fix BACnet REAL and DOUBLE decode

* Add unit test for NULL APDU encoding for length

* Add unit tests for bacapp context

* refactor host-n-port to hostnport.c module

* fix BVLC decoder

* additional unit testing for bacapp

* include bacdevobjpropref module in builds

* simplify bacapp snprintf to be able to return length

* adjust compiler for variable-length arrays

* fix bug found by scan-build

Authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
Steve Karg
2022-06-01 15:42:50 -05:00
committed by GitHub
parent 810bfefb34
commit f147283293
76 changed files with 3474 additions and 2791 deletions
+100 -55
View File
@@ -43,15 +43,17 @@
int encode_unsigned16(uint8_t *apdu, uint16_t value)
{
apdu[0] = (uint8_t)((value & 0xff00) >> 8);
apdu[1] = (uint8_t)(value & 0x00ff);
if (apdu) {
apdu[0] = (uint8_t)((value & 0xff00) >> 8);
apdu[1] = (uint8_t)(value & 0x00ff);
}
return 2;
}
int decode_unsigned16(uint8_t *apdu, uint16_t *value)
{
if (value) {
if (apdu && value) {
*value = (uint16_t)((((uint16_t)apdu[0]) << 8) & 0xff00);
*value |= ((uint16_t)(((uint16_t)apdu[1]) & 0x00ff));
}
@@ -61,16 +63,18 @@ int decode_unsigned16(uint8_t *apdu, uint16_t *value)
int encode_unsigned24(uint8_t *apdu, uint32_t value)
{
apdu[0] = (uint8_t)((value & 0xff0000) >> 16);
apdu[1] = (uint8_t)((value & 0x00ff00) >> 8);
apdu[2] = (uint8_t)(value & 0x0000ff);
if (apdu) {
apdu[0] = (uint8_t)((value & 0xff0000) >> 16);
apdu[1] = (uint8_t)((value & 0x00ff00) >> 8);
apdu[2] = (uint8_t)(value & 0x0000ff);
}
return 3;
}
int decode_unsigned24(uint8_t *apdu, uint32_t *value)
{
if (value) {
if (apdu && value) {
*value = ((uint32_t)((((uint32_t)apdu[0]) << 16) & 0x00ff0000));
*value |= (uint32_t)((((uint32_t)apdu[1]) << 8) & 0x0000ff00);
*value |= ((uint32_t)(((uint32_t)apdu[2]) & 0x000000ff));
@@ -81,17 +85,19 @@ int decode_unsigned24(uint8_t *apdu, uint32_t *value)
int encode_unsigned32(uint8_t *apdu, uint32_t value)
{
apdu[0] = (uint8_t)((value & 0xff000000) >> 24);
apdu[1] = (uint8_t)((value & 0x00ff0000) >> 16);
apdu[2] = (uint8_t)((value & 0x0000ff00) >> 8);
apdu[3] = (uint8_t)(value & 0x000000ff);
if (apdu) {
apdu[0] = (uint8_t)((value & 0xff000000) >> 24);
apdu[1] = (uint8_t)((value & 0x00ff0000) >> 16);
apdu[2] = (uint8_t)((value & 0x0000ff00) >> 8);
apdu[3] = (uint8_t)(value & 0x000000ff);
}
return 4;
}
int decode_unsigned32(uint8_t *apdu, uint32_t *value)
{
if (value) {
if (apdu && value) {
*value = ((uint32_t)((((uint32_t)apdu[0]) << 24) & 0xff000000));
*value |= ((uint32_t)((((uint32_t)apdu[1]) << 16) & 0x00ff0000));
*value |= ((uint32_t)((((uint32_t)apdu[2]) << 8) & 0x0000ff00));
@@ -110,11 +116,13 @@ int decode_unsigned32(uint8_t *apdu, uint32_t *value)
*/
int encode_unsigned40(uint8_t *buffer, uint64_t value)
{
buffer[0] = (uint8_t)((value & 0x000000ff00000000ULL) >> 32);
buffer[1] = (uint8_t)((value & 0x00000000ff000000ULL) >> 24);
buffer[2] = (uint8_t)((value & 0x0000000000ff0000ULL) >> 16);
buffer[3] = (uint8_t)((value & 0x000000000000ff00ULL) >> 8);
buffer[4] = (uint8_t)(value & 0x00000000000000ffULL);
if (buffer) {
buffer[0] = (uint8_t)((value & 0x000000ff00000000ULL) >> 32);
buffer[1] = (uint8_t)((value & 0x00000000ff000000ULL) >> 24);
buffer[2] = (uint8_t)((value & 0x0000000000ff0000ULL) >> 16);
buffer[3] = (uint8_t)((value & 0x000000000000ff00ULL) >> 8);
buffer[4] = (uint8_t)(value & 0x00000000000000ffULL);
}
return 5;
}
@@ -127,7 +135,7 @@ int encode_unsigned40(uint8_t *buffer, uint64_t value)
*/
int decode_unsigned40(uint8_t *buffer, uint64_t *value)
{
if (value) {
if (buffer && value) {
*value =
((uint64_t)((((uint64_t)buffer[0]) << 32) & 0x000000ff00000000ULL));
*value |=
@@ -150,12 +158,14 @@ int decode_unsigned40(uint8_t *buffer, uint64_t *value)
*/
int encode_unsigned48(uint8_t *buffer, uint64_t value)
{
buffer[0] = (uint8_t)((value & 0x0000ff0000000000ULL) >> 40);
buffer[1] = (uint8_t)((value & 0x000000ff00000000ULL) >> 32);
buffer[2] = (uint8_t)((value & 0x00000000ff000000ULL) >> 24);
buffer[3] = (uint8_t)((value & 0x0000000000ff0000ULL) >> 16);
buffer[4] = (uint8_t)((value & 0x000000000000ff00ULL) >> 8);
buffer[5] = (uint8_t)(value & 0x00000000000000ffULL);
if (buffer) {
buffer[0] = (uint8_t)((value & 0x0000ff0000000000ULL) >> 40);
buffer[1] = (uint8_t)((value & 0x000000ff00000000ULL) >> 32);
buffer[2] = (uint8_t)((value & 0x00000000ff000000ULL) >> 24);
buffer[3] = (uint8_t)((value & 0x0000000000ff0000ULL) >> 16);
buffer[4] = (uint8_t)((value & 0x000000000000ff00ULL) >> 8);
buffer[5] = (uint8_t)(value & 0x00000000000000ffULL);
}
return 6;
}
@@ -168,7 +178,7 @@ int encode_unsigned48(uint8_t *buffer, uint64_t value)
*/
int decode_unsigned48(uint8_t *buffer, uint64_t *value)
{
if (value) {
if (buffer && value) {
*value =
((uint64_t)((((uint64_t)buffer[0]) << 40) & 0x0000ff0000000000ULL));
*value |=
@@ -193,13 +203,15 @@ int decode_unsigned48(uint8_t *buffer, uint64_t *value)
*/
int encode_unsigned56(uint8_t *buffer, uint64_t value)
{
buffer[0] = (uint8_t)((value & 0x00ff000000000000ULL) >> 48);
buffer[1] = (uint8_t)((value & 0x0000ff0000000000ULL) >> 40);
buffer[2] = (uint8_t)((value & 0x000000ff00000000ULL) >> 32);
buffer[3] = (uint8_t)((value & 0x00000000ff000000ULL) >> 24);
buffer[4] = (uint8_t)((value & 0x0000000000ff0000ULL) >> 16);
buffer[5] = (uint8_t)((value & 0x000000000000ff00ULL) >> 8);
buffer[6] = (uint8_t)(value & 0x00000000000000ffULL);
if (buffer) {
buffer[0] = (uint8_t)((value & 0x00ff000000000000ULL) >> 48);
buffer[1] = (uint8_t)((value & 0x0000ff0000000000ULL) >> 40);
buffer[2] = (uint8_t)((value & 0x000000ff00000000ULL) >> 32);
buffer[3] = (uint8_t)((value & 0x00000000ff000000ULL) >> 24);
buffer[4] = (uint8_t)((value & 0x0000000000ff0000ULL) >> 16);
buffer[5] = (uint8_t)((value & 0x000000000000ff00ULL) >> 8);
buffer[6] = (uint8_t)(value & 0x00000000000000ffULL);
}
return 7;
}
@@ -212,7 +224,7 @@ int encode_unsigned56(uint8_t *buffer, uint64_t value)
*/
int decode_unsigned56(uint8_t *buffer, uint64_t *value)
{
if (value) {
if (buffer && value) {
*value =
((uint64_t)((((uint64_t)buffer[0]) << 48) & 0x00ff000000000000ULL));
*value |=
@@ -239,14 +251,16 @@ int decode_unsigned56(uint8_t *buffer, uint64_t *value)
*/
int encode_unsigned64(uint8_t *buffer, uint64_t value)
{
buffer[0] = (uint8_t)((value & 0xff00000000000000ULL) >> 56);
buffer[1] = (uint8_t)((value & 0x00ff000000000000ULL) >> 48);
buffer[2] = (uint8_t)((value & 0x0000ff0000000000ULL) >> 40);
buffer[3] = (uint8_t)((value & 0x000000ff00000000ULL) >> 32);
buffer[4] = (uint8_t)((value & 0x00000000ff000000ULL) >> 24);
buffer[5] = (uint8_t)((value & 0x0000000000ff0000ULL) >> 16);
buffer[6] = (uint8_t)((value & 0x000000000000ff00ULL) >> 8);
buffer[7] = (uint8_t)(value & 0x00000000000000ffULL);
if (buffer) {
buffer[0] = (uint8_t)((value & 0xff00000000000000ULL) >> 56);
buffer[1] = (uint8_t)((value & 0x00ff000000000000ULL) >> 48);
buffer[2] = (uint8_t)((value & 0x0000ff0000000000ULL) >> 40);
buffer[3] = (uint8_t)((value & 0x000000ff00000000ULL) >> 32);
buffer[4] = (uint8_t)((value & 0x00000000ff000000ULL) >> 24);
buffer[5] = (uint8_t)((value & 0x0000000000ff0000ULL) >> 16);
buffer[6] = (uint8_t)((value & 0x000000000000ff00ULL) >> 8);
buffer[7] = (uint8_t)(value & 0x00000000000000ffULL);
}
return 8;
}
@@ -259,7 +273,7 @@ int encode_unsigned64(uint8_t *buffer, uint64_t value)
*/
int decode_unsigned64(uint8_t *buffer, uint64_t *value)
{
if (value) {
if (buffer && value) {
*value =
((uint64_t)((((uint64_t)buffer[0]) << 56) & 0xff00000000000000ULL));
*value |=
@@ -320,14 +334,16 @@ int bacnet_unsigned_length(BACNET_UNSIGNED_INTEGER value)
#if BACNET_USE_SIGNED
int encode_signed8(uint8_t *apdu, int8_t value)
{
apdu[0] = (uint8_t)value;
if (apdu) {
apdu[0] = (uint8_t)value;
}
return 1;
}
int decode_signed8(uint8_t *apdu, int32_t *value)
{
if (value) {
if (apdu && value) {
/* negative - bit 7 is set */
if (apdu[0] & 0x80) {
*value = 0xFFFFFF00;
@@ -342,15 +358,17 @@ int decode_signed8(uint8_t *apdu, int32_t *value)
int encode_signed16(uint8_t *apdu, int16_t value)
{
apdu[0] = (uint8_t)((value & 0xff00) >> 8);
apdu[1] = (uint8_t)(value & 0x00ff);
if (apdu) {
apdu[0] = (uint8_t)((value & 0xff00) >> 8);
apdu[1] = (uint8_t)(value & 0x00ff);
}
return 2;
}
int decode_signed16(uint8_t *apdu, int32_t *value)
{
if (value) {
if (apdu && value) {
/* negative - bit 7 is set */
if (apdu[0] & 0x80) {
*value = 0xFFFF0000;
@@ -366,16 +384,18 @@ int decode_signed16(uint8_t *apdu, int32_t *value)
int encode_signed24(uint8_t *apdu, int32_t value)
{
apdu[0] = (uint8_t)((value & 0xff0000) >> 16);
apdu[1] = (uint8_t)((value & 0x00ff00) >> 8);
apdu[2] = (uint8_t)(value & 0x0000ff);
if (apdu) {
apdu[0] = (uint8_t)((value & 0xff0000) >> 16);
apdu[1] = (uint8_t)((value & 0x00ff00) >> 8);
apdu[2] = (uint8_t)(value & 0x0000ff);
}
return 3;
}
int decode_signed24(uint8_t *apdu, int32_t *value)
{
if (value) {
if (apdu && value) {
/* negative - bit 7 is set */
if (apdu[0] & 0x80) {
*value = 0xFF000000;
@@ -392,10 +412,12 @@ int decode_signed24(uint8_t *apdu, int32_t *value)
int encode_signed32(uint8_t *apdu, int32_t value)
{
apdu[0] = (uint8_t)((value & 0xff000000) >> 24);
apdu[1] = (uint8_t)((value & 0x00ff0000) >> 16);
apdu[2] = (uint8_t)((value & 0x0000ff00) >> 8);
apdu[3] = (uint8_t)(value & 0x000000ff);
if (apdu) {
apdu[0] = (uint8_t)((value & 0xff000000) >> 24);
apdu[1] = (uint8_t)((value & 0x00ff0000) >> 16);
apdu[2] = (uint8_t)((value & 0x0000ff00) >> 8);
apdu[3] = (uint8_t)(value & 0x000000ff);
}
return 4;
}
@@ -411,4 +433,27 @@ int decode_signed32(uint8_t *apdu, int32_t *value)
return 4;
}
/**
* @brief Determines the number of bytes used by a BACnet Signed Integer
* from clause 20.2.5 Encoding of an Signed Integer Value
* @param value - signed value
* @return number of bytes used by a BACnet Signed Integer
*/
int bacnet_signed_length(int32_t value)
{
int len;
if ((value >= -128) && (value < 128)) {
len = 1;
} else if ((value >= -32768) && (value < 32768)) {
len = 2;
} else if ((value > -8388608) && (value < 8388608)) {
len = 3;
} else {
len = 4;
}
return len;
}
#endif