added proper bitstring encoding

This commit is contained in:
skarg
2005-04-15 17:43:02 +00:00
parent 6cdffceab6
commit 57e3025421
4 changed files with 121 additions and 28 deletions
+26 -2
View File
@@ -544,6 +544,30 @@ bool decode_is_closing_tag_number(uint8_t * apdu, uint8_t tag_number)
return (closing_tag && (my_tag_number == tag_number));
}
static uint8_t byte_reverse_bits(uint8_t in_byte)
{
uint8_t out_byte = 0;
if (in_byte & BIT0)
out_byte |= BIT7;
if (in_byte & BIT1)
out_byte |= BIT6;
if (in_byte & BIT2)
out_byte |= BIT5;
if (in_byte & BIT3)
out_byte |= BIT4;
if (in_byte & BIT4)
out_byte |= BIT3;
if (in_byte & BIT5)
out_byte |= BIT2;
if (in_byte & BIT6)
out_byte |= BIT1;
if (in_byte & BIT7)
out_byte |= BIT0;
return out_byte;
}
// from clause 20.2.10 Encoding of a Bit String Value
// returns the number of apdu bytes consumed
int decode_bitstring(uint8_t * apdu, uint32_t len_value,
@@ -565,7 +589,7 @@ int decode_bitstring(uint8_t * apdu, uint32_t len_value,
len = 1;
for (i = 0; i < bytes_used; i++)
{
bit_string->value[i] = apdu[len++];
bit_string->value[i] = byte_reverse_bits(apdu[len++]);
}
unused_bits = apdu[0] & 0x07;
bit_string->bits_used = bytes_used * 8;
@@ -615,7 +639,7 @@ int encode_bitstring(uint8_t * apdu, BACNET_BIT_STRING *bit_string)
apdu[len++] = 8 - remaining_used_bits;
for (i = 0; i < used_bytes; i++)
{
apdu[len++] = bit_string->value[i];
apdu[len++] = byte_reverse_bits(bit_string->value[i]);
}
}
+20
View File
@@ -38,6 +38,14 @@
#include <stdbool.h>
#include <stddef.h>
// bit strings
#define MAX_BITSTRING_BYTES 15
typedef struct BACnet_Bit_String
{
uint8_t bits_used;
uint8_t value[MAX_BITSTRING_BYTES];
} BACNET_BIT_STRING;
// 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,
@@ -58,6 +66,18 @@ bool decode_is_closing_tag_number(uint8_t * apdu, uint8_t tag_number);
// returns true if the tag is context specific and matches
bool decode_is_context_tag(uint8_t * apdu, uint8_t tag_number);
// from clause 20.2.10 Encoding of a Bit String Value
void bitstring_init(BACNET_BIT_STRING *bit_string);
void bitstring_set_bit(BACNET_BIT_STRING *bit_string, uint8_t bit, bool value);
bool bitstring_bit(BACNET_BIT_STRING *bit_string, uint8_t bit);
uint8_t bitstring_bits_used(BACNET_BIT_STRING *bit_string);
// returns the number of apdu bytes consumed
int decode_bitstring(uint8_t * apdu, uint32_t len_value,
BACNET_BIT_STRING *bit_string);
// returns the number of apdu bytes consumed
int encode_bitstring(uint8_t * apdu, BACNET_BIT_STRING *bit_string);
int encode_tagged_bitstring(uint8_t * apdu, BACNET_BIT_STRING *bit_string);
// from clause 20.2.6 Encoding of a Real Number Value
// and 20.2.1 General Rules for Encoding BACnet Tags
// returns the number of apdu bytes consumed
+56 -1
View File
@@ -555,7 +555,7 @@ typedef enum
OBJECT_COMMAND = 7,
OBJECT_DEVICE = 8,
OBJECT_EVENT_ENROLLMENT = 9,
OBJECT_FILE_O = 10,
OBJECT_FILE_ = 10,
OBJECT_GROUP = 11,
OBJECT_LOOP = 12,
OBJECT_MULTI_STATE_INPUT = 13,
@@ -703,6 +703,61 @@ typedef enum {
MAX_BACNET_UNCONFIRMED_SERVICE = 10
} BACNET_UNCONFIRMED_SERVICE;
// Bit String Enumerations
typedef enum
{
// Alarm and Event Services
SERVICE_SUPPORTED_ACKNOWLEDGE_ALARM = 0,
SERVICE_SUPPORTED_CONFIRMED_COV_NOTIFICATION = 1,
SERVICE_SUPPORTED_CONFIRMED_EVENT_NOTIFICATION = 2,
SERVICE_SUPPORTED_GET_ALARM_SUMMARY = 3,
SERVICE_SUPPORTED_GET_ENROLLMENT_SUMMARY = 4,
SERVICE_SUPPORTED_GET_EVENT_INFORMATION = 39,
SERVICE_SUPPORTED_SUBSCRIBE_COV = 5,
SERVICE_SUPPORTED_SUBSCRIBE_COV_PROPERTY = 38,
SERVICE_SUPPORTED_LIFE_SAFETY_OPERATION = 37,
// File Access Services
SERVICE_SUPPORTED_ATOMIC_READ_FILE = 6,
SERVICE_SUPPORTED_ATOMIC_WRITE_FILE = 7,
// Object Access Services
SERVICE_SUPPORTED_ADD_LIST_ELEMENT = 8,
SERVICE_SUPPORTED_REMOVE_LIST_ELEMENT = 9,
SERVICE_SUPPORTED_CREATE_OBJECT = 10,
SERVICE_SUPPORTED_DELETE_OBJECT = 11,
SERVICE_SUPPORTED_READ_PROPERTY = 12,
SERVICE_SUPPORTED_READ_PROPERTY_CONDITIONAL = 13,
SERVICE_SUPPORTED_READ_PROPERTY_MULTIPLE = 14,
SERVICE_SUPPORTED_READ_RANGE = 35,
SERVICE_SUPPORTED_WRITE_PROPERTY = 15,
SERVICE_SUPPORTED_WRITE_PROPERTY_MULTIPLE = 16,
// Remote Device Management Services
SERVICE_SUPPORTED_DEVICE_COMMUNICATION_CONTROL = 17,
SERVICE_SUPPORTED_PRIVATE_TRANSFER = 18,
SERVICE_SUPPORTED_TEXT_MESSAGE = 19,
SERVICE_SUPPORTED_REINITIALIZE_DEVICE = 20,
// Virtual Terminal Services
SERVICE_SUPPORTED_VT_OPEN = 21,
SERVICE_SUPPORTED_VT_CLOSE = 22,
SERVICE_SUPPORTED_VT_DATA = 23,
// Security Services
SERVICE_SUPPORTED_AUTHENTICATE = 24,
SERVICE_SUPPORTED_REQUEST_KEY = 25,
SERVICE_SUPPORTED_I_AM = 26,
SERVICE_SUPPORTED_I_HAVE = 27,
SERVICE_SUPPORTED_UNCONFIRMED_COV_NOTIFICATION = 28,
SERVICE_SUPPORTED_UNCONFIRMED_EVENT_NOTIFICATION = 29,
SERVICE_SUPPORTED_UNCONFIRMED_PRIVATE_TRANSFER = 30,
SERVICE_SUPPORTED_UNCONFIRMED_TEXT_MESSAGE = 31,
SERVICE_SUPPORTED_TIME_SYNCHRONIZATION = 32,
SERVICE_SUPPORTED_UTC_TIME_SYNCHRONIZATION = 36,
SERVICE_SUPPORTED_WHO_HAS = 33,
SERVICE_SUPPORTED_WHO_IS = 34,
// Other services to be added as they are defined.
// All values in this production are reserved
// for definition by ASHRAE.
MAX_BACNET_SERVICES_SUPPORTED = 40
} BACNET_SERVICES_SUPPORTED;
typedef enum {
ACKNOWLEDGMENT_FILTER_ALL = 0,
ACKNOWLEDGMENT_FILTER_ACKED = 1,
+19 -25
View File
@@ -188,9 +188,6 @@ BACNET_SEGMENTATION Device_Segmentation_Supported(void)
return SEGMENTATION_NONE;
}
//FIXME: This need some bit string encodings...
//Protocol_Services_Supported
//Protocol_Object_Types_Supported
//FIXME: Probably return one at a time, or be supported by
// an object module, or encode the APDU here.
//Object_List
@@ -233,7 +230,8 @@ int Device_Encode_Property_APDU(
int32_t array_index)
{
int apdu_len = 0; // return value
BACNET_BIT_STRING bit_string;
switch (property)
{
case PROP_OBJECT_IDENTIFIER:
@@ -292,30 +290,26 @@ int Device_Encode_Property_APDU(
case PROP_PROTOCOL_VERSION:
apdu_len = encode_tagged_unsigned(&apdu[0], Device_Protocol_Version());
break;
// BACnet Legacy Support - necessary?
//case PROP_PROTOCOL_CONFORMANCE_CLASS:
// apdu_len = encode_tagged_unsigned(&apdu[0], 1);
// break;
// BACnet Legacy Support
case PROP_PROTOCOL_CONFORMANCE_CLASS:
apdu_len = encode_tagged_unsigned(&apdu[0], 1);
break;
case PROP_PROTOCOL_SERVICES_SUPPORTED:
// FIXME: needs an encoding function for bitstring
apdu[0] = 0x85; /* what is following? (this is a bitstring) */
apdu[1] = 0x06; /* length extension to 6 bytes */
apdu[2] = 0x05; /* 5 unused bits in the final byte */
apdu[3] = 0x00; /* none of the first 8 bits are set */
apdu[4] = 0x09; /* bits 3,0 are set */
apdu[5] = 0x00; /* none of the 3rd set of bits are set */
apdu[6] = 0x20; /* bit 5 is set */
apdu[7] = 0x20; /* bit 5 is set */
apdu_len = 8; /* bytes in this apdu */
bitstring_init(&bit_string);
// when APDU does automatic reject when service is NULL, then add this
//for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++)
//{
// bitstring_set_bit(&bit_string, i, apdu_service_supported(i));
//}
bitstring_set_bit(&bit_string, SERVICE_SUPPORTED_WHO_IS, true);
bitstring_set_bit(&bit_string, SERVICE_SUPPORTED_I_AM, true);
bitstring_set_bit(&bit_string, SERVICE_SUPPORTED_READ_PROPERTY, true);
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
break;
case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED:
// FIXME: needs an encoding function for bitstring
apdu[0] = 0x84; /* what is following? (this is a bitstring) */
apdu[1] = 0x06; /* 6 unused bits in the final byte */
apdu[2] = 0xFF; /* All of the first 8 bits are set */
apdu[3] = 0xFF; /* All of the second 8 bits are set */
apdu[4] = 0xC0; /* All of the valid bits are set */
apdu_len = 5; /* bytes in this apdu */
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, OBJECT_DEVICE, true);
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
break;
case PROP_OBJECT_LIST:
// FIXME: hook into real object list, not just device