Corrected the encoding and decoding of the bit string.
This commit is contained in:
+42
-16
@@ -556,10 +556,12 @@ int decode_bitstring(uint8_t * apdu, uint32_t len_value,
|
|||||||
|
|
||||||
|
|
||||||
bitstring_init(bit_string);
|
bitstring_init(bit_string);
|
||||||
if (len_value && ((len_value - 1) < MAX_BITSTRING_BYTES))
|
if (len_value)
|
||||||
{
|
{
|
||||||
// the first octet contains the unused bits
|
// the first octet contains the unused bits
|
||||||
bytes_used = len_value--;
|
bytes_used = len_value - 1;
|
||||||
|
if (bytes_used <= MAX_BITSTRING_BYTES)
|
||||||
|
{
|
||||||
len = 1;
|
len = 1;
|
||||||
for (i = 0; i < bytes_used; i++)
|
for (i = 0; i < bytes_used; i++)
|
||||||
{
|
{
|
||||||
@@ -568,32 +570,53 @@ int decode_bitstring(uint8_t * apdu, uint32_t len_value,
|
|||||||
unused_bits = apdu[0] & 0x07;
|
unused_bits = apdu[0] & 0x07;
|
||||||
bit_string->bits_used = bytes_used * 8;
|
bit_string->bits_used = bytes_used * 8;
|
||||||
bit_string->bits_used -= unused_bits;
|
bit_string->bits_used -= unused_bits;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns the number of bytes that a bit string is using
|
||||||
|
static int bitstring_bytes_used(BACNET_BIT_STRING *bit_string)
|
||||||
|
{
|
||||||
|
int len = 0; // return value
|
||||||
|
uint8_t used_bytes = 0;
|
||||||
|
uint8_t last_bit = 0;
|
||||||
|
|
||||||
|
if (bit_string->bits_used)
|
||||||
|
{
|
||||||
|
last_bit = bit_string->bits_used - 1;
|
||||||
|
used_bytes = last_bit / 8;
|
||||||
|
// add one for the first byte
|
||||||
|
used_bytes++;
|
||||||
|
len = used_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
// from clause 20.2.10 Encoding of a Bit String Value
|
// from clause 20.2.10 Encoding of a Bit String Value
|
||||||
// returns the number of apdu bytes consumed
|
// returns the number of apdu bytes consumed
|
||||||
int encode_bitstring(uint8_t * apdu, BACNET_BIT_STRING *bit_string)
|
int encode_bitstring(uint8_t * apdu, BACNET_BIT_STRING *bit_string)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
uint8_t used_bits = 0;
|
uint8_t remaining_used_bits = 0;
|
||||||
uint8_t used_bytes = 0;
|
uint8_t used_bytes = 0;
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
|
|
||||||
// possible to encode an empty bit string
|
|
||||||
if (bit_string->bits_used)
|
|
||||||
used_bytes = (bit_string->bits_used / 8) + 1;
|
|
||||||
used_bits = bit_string->bits_used - (used_bytes * 8);
|
|
||||||
// if the bit string is empty, then the first octet shall be zero
|
// if the bit string is empty, then the first octet shall be zero
|
||||||
if (bit_string->bits_used)
|
if (bit_string->bits_used == 0)
|
||||||
apdu[len++] = 8 - used_bits;
|
|
||||||
else
|
|
||||||
apdu[len++] = 0;
|
apdu[len++] = 0;
|
||||||
for (i = 0; i < used_bytes; i++)
|
else
|
||||||
{
|
{
|
||||||
apdu[len++] = bit_string->value[i];
|
used_bytes = bitstring_bytes_used(bit_string);
|
||||||
|
remaining_used_bits = bit_string->bits_used - ((used_bytes - 1) * 8);
|
||||||
|
// number of unused bits in the subsequent final octet
|
||||||
|
apdu[len++] = 8 - remaining_used_bits;
|
||||||
|
for (i = 0; i < used_bytes; i++)
|
||||||
|
{
|
||||||
|
apdu[len++] = bit_string->value[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
@@ -602,10 +625,13 @@ int encode_bitstring(uint8_t * apdu, BACNET_BIT_STRING *bit_string)
|
|||||||
int encode_tagged_bitstring(uint8_t * apdu, BACNET_BIT_STRING *bit_string)
|
int encode_tagged_bitstring(uint8_t * apdu, BACNET_BIT_STRING *bit_string)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
int bit_string_encoded_length = 1;// 1 for the bits remaining octet
|
||||||
|
|
||||||
// assumes that the tag only consumes 1 octet
|
// bit string may use more than 1 octet for the tag, so find out how many
|
||||||
len = encode_bitstring(&apdu[1], bit_string);
|
bit_string_encoded_length += bitstring_bytes_used(bit_string);
|
||||||
len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_BIT_STRING, false, len);
|
len = encode_tag(&apdu[0], BACNET_APPLICATION_TAG_BIT_STRING, false,
|
||||||
|
bit_string_encoded_length);
|
||||||
|
len += encode_bitstring(&apdu[len], bit_string);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user