Moved encoding and decoding of integers out of bacdcode.c, and now relying on bacint.c. This should also help Feature Request 1532291 for reducing code size.
This commit is contained in:
+1
-446
@@ -39,6 +39,7 @@
|
||||
#include "bacenum.h"
|
||||
#include "bits.h"
|
||||
#include "bacstr.h"
|
||||
#include "bacint.h"
|
||||
|
||||
/* NOTE: byte order plays a role in decoding multibyte values */
|
||||
/* http://www.unixpapa.com/incnote/byteorder.html */
|
||||
@@ -188,347 +189,6 @@ int decode_max_apdu(uint8_t octet)
|
||||
return max_apdu;
|
||||
}
|
||||
|
||||
int encode_unsigned16(uint8_t * apdu, uint16_t value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[2];
|
||||
uint16_t value;
|
||||
} short_data = { {
|
||||
0}};
|
||||
|
||||
short_data.value = value;
|
||||
#if BIG_ENDIAN
|
||||
apdu[0] = short_data.byte[0];
|
||||
apdu[1] = short_data.byte[1];
|
||||
#else
|
||||
apdu[0] = short_data.byte[1];
|
||||
apdu[1] = short_data.byte[0];
|
||||
#endif
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int decode_unsigned16(uint8_t * apdu, uint16_t * value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[2];
|
||||
uint16_t value;
|
||||
} short_data = { {
|
||||
0}};
|
||||
|
||||
#if BIG_ENDIAN
|
||||
short_data.byte[0] = apdu[0];
|
||||
short_data.byte[1] = apdu[1];
|
||||
#else
|
||||
short_data.byte[1] = apdu[0];
|
||||
short_data.byte[0] = apdu[1];
|
||||
#endif
|
||||
if (value)
|
||||
*value = short_data.value;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int encode_unsigned24(uint8_t * apdu, uint32_t value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[4];
|
||||
uint32_t value;
|
||||
} long_data = { {
|
||||
0}};
|
||||
|
||||
long_data.value = value;
|
||||
#if BIG_ENDIAN
|
||||
apdu[0] = long_data.byte[1];
|
||||
apdu[1] = long_data.byte[2];
|
||||
apdu[2] = long_data.byte[3];
|
||||
#else
|
||||
apdu[0] = long_data.byte[2];
|
||||
apdu[1] = long_data.byte[1];
|
||||
apdu[2] = long_data.byte[0];
|
||||
#endif
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
int decode_unsigned24(uint8_t * apdu, uint32_t * value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[4];
|
||||
uint32_t value;
|
||||
} long_data = { {
|
||||
0}};
|
||||
|
||||
#if BIG_ENDIAN
|
||||
long_data.byte[1] = apdu[0];
|
||||
long_data.byte[2] = apdu[1];
|
||||
long_data.byte[3] = apdu[2];
|
||||
#else
|
||||
long_data.byte[2] = apdu[0];
|
||||
long_data.byte[1] = apdu[1];
|
||||
long_data.byte[0] = apdu[2];
|
||||
#endif
|
||||
if (value)
|
||||
*value = long_data.value;
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
int encode_unsigned32(uint8_t * apdu, uint32_t value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[4];
|
||||
uint32_t value;
|
||||
} long_data = { {
|
||||
0}};
|
||||
|
||||
long_data.value = value;
|
||||
#if BIG_ENDIAN
|
||||
apdu[0] = long_data.byte[0];
|
||||
apdu[1] = long_data.byte[1];
|
||||
apdu[2] = long_data.byte[2];
|
||||
apdu[3] = long_data.byte[3];
|
||||
#else
|
||||
apdu[0] = long_data.byte[3];
|
||||
apdu[1] = long_data.byte[2];
|
||||
apdu[2] = long_data.byte[1];
|
||||
apdu[3] = long_data.byte[0];
|
||||
#endif
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
int decode_unsigned32(uint8_t * apdu, uint32_t * value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[4];
|
||||
uint32_t value;
|
||||
} long_data = { {
|
||||
0}};
|
||||
|
||||
#if BIG_ENDIAN
|
||||
long_data.byte[0] = apdu[0];
|
||||
long_data.byte[1] = apdu[1];
|
||||
long_data.byte[2] = apdu[2];
|
||||
long_data.byte[3] = apdu[3];
|
||||
#else
|
||||
long_data.byte[3] = apdu[0];
|
||||
long_data.byte[2] = apdu[1];
|
||||
long_data.byte[1] = apdu[2];
|
||||
long_data.byte[0] = apdu[3];
|
||||
#endif
|
||||
if (value)
|
||||
*value = long_data.value;
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
/* returns the number of APDU octets used */
|
||||
int encode_signed8(uint8_t * apdu, int8_t value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte;
|
||||
int8_t value;
|
||||
} byte_data = {
|
||||
0};
|
||||
|
||||
byte_data.value = value;
|
||||
apdu[0] = byte_data.byte;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* returns the number of APDU octets consumed */
|
||||
int decode_signed8(uint8_t * apdu, int32_t * value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[4];
|
||||
int32_t value;
|
||||
} long_data = { {
|
||||
0}};
|
||||
|
||||
#if BIG_ENDIAN
|
||||
/* negative - bit 7 is set */
|
||||
if (apdu[0] & 0x80) {
|
||||
long_data.byte[0] = 0xFF;
|
||||
long_data.byte[1] = 0xFF;
|
||||
long_data.byte[2] = 0xFF;
|
||||
}
|
||||
/* fill in the rest */
|
||||
long_data.byte[3] = apdu[0];
|
||||
#else
|
||||
/* negative - bit 7 is set */
|
||||
if (apdu[0] & 0x80) {
|
||||
long_data.byte[3] = 0xFF;
|
||||
long_data.byte[2] = 0xFF;
|
||||
long_data.byte[1] = 0xFF;
|
||||
}
|
||||
/* fill in the rest */
|
||||
long_data.byte[0] = apdu[0];
|
||||
#endif
|
||||
if (value)
|
||||
*value = long_data.value;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* returns the number of APDU octets used */
|
||||
int encode_signed16(uint8_t * apdu, int16_t value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[2];
|
||||
int16_t value;
|
||||
} short_data = { {
|
||||
0}};
|
||||
|
||||
short_data.value = value;
|
||||
#if BIG_ENDIAN
|
||||
apdu[0] = short_data.byte[0];
|
||||
apdu[1] = short_data.byte[1];
|
||||
#else
|
||||
apdu[0] = short_data.byte[1];
|
||||
apdu[1] = short_data.byte[0];
|
||||
#endif
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* returns the number of APDU octets consumed */
|
||||
int decode_signed16(uint8_t * apdu, int32_t * value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[4];
|
||||
int32_t value;
|
||||
} long_data = { {
|
||||
0}};
|
||||
|
||||
#if BIG_ENDIAN
|
||||
/* negative - bit 7 is set */
|
||||
if (apdu[0] & 0x80) {
|
||||
long_data.byte[0] = 0xFF;
|
||||
long_data.byte[1] = 0xFF;
|
||||
}
|
||||
/* fill in the rest */
|
||||
long_data.byte[2] = apdu[0];
|
||||
long_data.byte[3] = apdu[1];
|
||||
#else
|
||||
/* negative - bit 7 is set */
|
||||
if (apdu[0] & 0x80) {
|
||||
long_data.byte[3] = 0xFF;
|
||||
long_data.byte[2] = 0xFF;
|
||||
}
|
||||
/* fill in the rest */
|
||||
long_data.byte[1] = apdu[0];
|
||||
long_data.byte[0] = apdu[1];
|
||||
#endif
|
||||
if (value)
|
||||
*value = long_data.value;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int encode_signed24(uint8_t * apdu, int32_t value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[4];
|
||||
int32_t value;
|
||||
} long_data = { {
|
||||
0}};
|
||||
|
||||
long_data.value = value;
|
||||
#if BIG_ENDIAN
|
||||
apdu[0] = long_data.byte[1];
|
||||
apdu[1] = long_data.byte[2];
|
||||
apdu[2] = long_data.byte[3];
|
||||
#else
|
||||
apdu[0] = long_data.byte[2];
|
||||
apdu[1] = long_data.byte[1];
|
||||
apdu[2] = long_data.byte[0];
|
||||
#endif
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
int decode_signed24(uint8_t * apdu, int32_t * value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[4];
|
||||
int32_t value;
|
||||
} long_data = { {
|
||||
0}};
|
||||
|
||||
#if BIG_ENDIAN
|
||||
/* negative - bit 7 is set */
|
||||
if (apdu[0] & 0x80)
|
||||
long_data.byte[0] = 0xFF;
|
||||
/* fill in the rest */
|
||||
long_data.byte[1] = apdu[0];
|
||||
long_data.byte[2] = apdu[1];
|
||||
long_data.byte[3] = apdu[2];
|
||||
#else
|
||||
/* negative - bit 7 is set */
|
||||
if (apdu[0] & 0x80)
|
||||
long_data.byte[3] = 0xFF;
|
||||
/* fill in the rest */
|
||||
long_data.byte[2] = apdu[0];
|
||||
long_data.byte[1] = apdu[1];
|
||||
long_data.byte[0] = apdu[2];
|
||||
#endif
|
||||
if (value)
|
||||
*value = long_data.value;
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
int encode_signed32(uint8_t * apdu, int32_t value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[4];
|
||||
int32_t value;
|
||||
} long_data = { {
|
||||
0}};
|
||||
|
||||
long_data.value = value;
|
||||
#if BIG_ENDIAN
|
||||
apdu[0] = long_data.byte[0];
|
||||
apdu[1] = long_data.byte[1];
|
||||
apdu[2] = long_data.byte[2];
|
||||
apdu[3] = long_data.byte[3];
|
||||
#else
|
||||
apdu[0] = long_data.byte[3];
|
||||
apdu[1] = long_data.byte[2];
|
||||
apdu[2] = long_data.byte[1];
|
||||
apdu[3] = long_data.byte[0];
|
||||
#endif
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
int decode_signed32(uint8_t * apdu, int32_t * value)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[4];
|
||||
int32_t value;
|
||||
} long_data = { {
|
||||
0}};
|
||||
|
||||
#if BIG_ENDIAN
|
||||
long_data.byte[0] = apdu[0];
|
||||
long_data.byte[1] = apdu[1];
|
||||
long_data.byte[2] = apdu[2];
|
||||
long_data.byte[3] = apdu[3];
|
||||
#else
|
||||
long_data.byte[3] = apdu[0];
|
||||
long_data.byte[2] = apdu[1];
|
||||
long_data.byte[1] = apdu[2];
|
||||
long_data.byte[0] = apdu[3];
|
||||
#endif
|
||||
if (value)
|
||||
*value = long_data.value;
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
/* from clause 20.2.1 General Rules for Encoding BACnet Tags */
|
||||
/* returns the number of apdu bytes consumed */
|
||||
int encode_tag(uint8_t * apdu, uint8_t tag_number, bool context_specific,
|
||||
@@ -1227,27 +887,6 @@ int decode_character_string(uint8_t * apdu, uint32_t len_value,
|
||||
return len;
|
||||
}
|
||||
|
||||
/* from clause 20.2.4 Encoding of an Unsigned Integer Value */
|
||||
/* and 20.2.1 General Rules for Encoding BACnet Tags */
|
||||
/* returns the number of apdu bytes consumed */
|
||||
int encode_bacnet_unsigned(uint8_t * apdu, uint32_t value)
|
||||
{
|
||||
int len = 0; /* return value */
|
||||
|
||||
if (value < 0x100) {
|
||||
apdu[0] = (uint8_t) value;
|
||||
len = 1;
|
||||
} else if (value < 0x10000) {
|
||||
len = encode_unsigned16(&apdu[0], (uint16_t) value);
|
||||
} else if (value < 0x1000000) {
|
||||
len = encode_unsigned24(&apdu[0], value);
|
||||
} else {
|
||||
len = encode_unsigned32(&apdu[0], value);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* from clause 20.2.4 Encoding of an Unsigned Integer Value */
|
||||
/* and 20.2.1 General Rules for Encoding BACnet Tags */
|
||||
/* returns the number of apdu bytes consumed */
|
||||
@@ -1279,37 +918,6 @@ int encode_tagged_unsigned(uint8_t * apdu, uint32_t value)
|
||||
return len;
|
||||
}
|
||||
|
||||
/* from clause 20.2.4 Encoding of an Unsigned Integer Value */
|
||||
/* and 20.2.1 General Rules for Encoding BACnet Tags */
|
||||
/* returns the number of apdu bytes consumed */
|
||||
int decode_unsigned(uint8_t * apdu, uint32_t len_value, uint32_t * value)
|
||||
{
|
||||
uint16_t unsigned16_value = 0;
|
||||
|
||||
if (value) {
|
||||
switch (len_value) {
|
||||
case 1:
|
||||
*value = apdu[0];
|
||||
break;
|
||||
case 2:
|
||||
decode_unsigned16(&apdu[0], &unsigned16_value);
|
||||
*value = unsigned16_value;
|
||||
break;
|
||||
case 3:
|
||||
decode_unsigned24(&apdu[0], value);
|
||||
break;
|
||||
case 4:
|
||||
decode_unsigned32(&apdu[0], value);
|
||||
break;
|
||||
default:
|
||||
*value = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return len_value;
|
||||
}
|
||||
|
||||
/* from clause 20.2.11 Encoding of an Enumerated Value */
|
||||
/* and 20.2.1 General Rules for Encoding BACnet Tags */
|
||||
/* returns the number of apdu bytes consumed */
|
||||
@@ -1366,59 +974,6 @@ int encode_context_enumerated(uint8_t * apdu, int tag_number, int value)
|
||||
return len;
|
||||
}
|
||||
|
||||
/* from clause 20.2.5 Encoding of a Signed Integer Value */
|
||||
/* and 20.2.1 General Rules for Encoding BACnet Tags */
|
||||
/* returns the number of apdu bytes consumed */
|
||||
int decode_signed(uint8_t * apdu, uint32_t len_value, int32_t * value)
|
||||
{
|
||||
if (value) {
|
||||
switch (len_value) {
|
||||
case 1:
|
||||
decode_signed8(&apdu[0], value);
|
||||
break;
|
||||
case 2:
|
||||
decode_signed16(&apdu[0], value);
|
||||
break;
|
||||
case 3:
|
||||
decode_signed24(&apdu[0], value);
|
||||
break;
|
||||
case 4:
|
||||
decode_signed32(&apdu[0], value);
|
||||
break;
|
||||
default:
|
||||
*value = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return len_value;
|
||||
}
|
||||
|
||||
/* from clause 20.2.5 Encoding of a Signed Integer Value */
|
||||
/* and 20.2.1 General Rules for Encoding BACnet Tags */
|
||||
/* returns the number of apdu bytes consumed */
|
||||
int encode_bacnet_signed(uint8_t * apdu, int32_t value)
|
||||
{
|
||||
int len = 0; /* return value */
|
||||
|
||||
/* don't encode the leading X'FF' or X'00' of the two's compliment.
|
||||
That is, the first octet of any multi-octet encoded value shall
|
||||
not be X'00' if the most significant bit (bit 7) of the second
|
||||
octet is 0, and the first octet shall not be X'FF' if the most
|
||||
significant bit of the second octet is 1. */
|
||||
if ((value >= -128) && (value < 128)) {
|
||||
len = encode_signed8(&apdu[0], (int8_t) value);
|
||||
} else if ((value >= -32768) && (value < 32768)) {
|
||||
len = encode_signed16(&apdu[0], (int16_t) value);
|
||||
} else if ((value > -8388608) && (value < 8388608)) {
|
||||
len = encode_signed24(&apdu[0], value);
|
||||
} else {
|
||||
len = encode_signed32(&apdu[0], value);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* from clause 20.2.5 Encoding of a Signed Integer Value */
|
||||
/* and 20.2.1 General Rules for Encoding BACnet Tags */
|
||||
/* returns the number of apdu bytes consumed */
|
||||
|
||||
Reference in New Issue
Block a user